I want to replace OpenFileRequester with NSOPenPanel. Any API gurus here
API call help
-
spacebuddy
- Enthusiast

- Posts: 364
- Joined: Thu Jul 02, 2009 5:42 am
API call help
I am trying to call an API (NSOpenPanel) but running into problems.
I want to replace OpenFileRequester with NSOPenPanel. Any API gurus here
I want to replace OpenFileRequester with NSOPenPanel. Any API gurus here
Re: API call help
Unfortunately, NSOPenPanel is Cocoa (objectiveC) and this is not accessible trough PB. The 'easier' is your really need it is to write a small wrapper in ObjectiveC which expose a C function and then call it from PB
Re: API call help
Fred is right, it's Cocoa.
Last edited by wilbert on Sun Sep 23, 2012 12:07 pm, edited 1 time in total.
Re: API call help
By the way... 
How would you convert a PB string to a NSString?
This is what I do:
When PB is in non unicode mode, it works if there aren't any special character in the PB String (ie éèë...)
When PB is in unicode mode, it only gets the first letter of the PB string into the NSString.
Any solution?
How would you convert a PB string to a NSString?
This is what I do:
Code: Select all
void function (const char* pbstring)
{
NSString string = [NSString stringWithUTF8String: string];
}When PB is in unicode mode, it only gets the first letter of the PB string into the NSString.
Any solution?
Re: API call help
It's easier to usePolo wrote:How would you convert a PB string to a NSString?
NSString * string = [NSString stringWithFormat:@"%S", pbstring];
when unicode is used and
NSString * string = [NSString stringWithFormat:@"%s", pbstring];
when unicode is not used. That way you can use a static variable you set once that contains the format ( @"%S" or @"%s" ) and use the same convert function all the time.
Re: API call help
Using Cocoa panels in PB, that's quite easy, just link your app with cocoa
ImportC "/System/Library/Frameworks/Cocoa.framework/Cocoa"
EndImport
ImportC "/System/Library/Frameworks/AppKit.framework/AppKit"
EndImport
(last one is just in case
)
Create a static library with Xcode with the ObjC code you need, like this for instance, and import the C function in PB.
(you'd still need to handle the string conversion to make the panel customisable, which i didn't in the example below)
ImportC "/System/Library/Frameworks/Cocoa.framework/Cocoa"
EndImport
ImportC "/System/Library/Frameworks/AppKit.framework/AppKit"
EndImport
(last one is just in case
Create a static library with Xcode with the ObjC code you need, like this for instance, and import the C function in PB.
(you'd still need to handle the string conversion to make the panel customisable, which i didn't in the example below)
Code: Select all
void mOpenFileRequester()
{
NSString *title = "Requester title";
NSString *directory = "";
NSString *file = "";
NSString *extensions = "";
currentwin=[NSApp keyWindow];
if ( !currentwin ) [NSApp activateIgnoringOtherApps:YES];
NSOpenPanel *panel=[NSOpenPanel openPanel];
[panel setTitle:title];
if ( [panel runModalForDirectory:directory file:file types:extensions]==NSFileHandlingPanelOKButton )
{
NSString *fileselected=[[panel filename] UTF8String];
}
if ( currentwin ) [currentwin makeKeyWindow];
}
Re: API call help
Cheers wilbert, works great!
Re: API call help
I'd like to do the same (calling a Cocoa API). I need to access CoreMIDI to do some real-time MIDI. I used the WinAPI on Windows but it looks like a different game on MacOS X. Thanks!
Re: API call help
Hi,
can some give me a easy example of this code. I'm a beginner and have no experience with C.
Thanks!
can some give me a easy example of this code. I'm a beginner and have no experience with C.
Thanks!
macOS Catalina 10.15.7
Re: API call help
I'm not sure what your goal is.Wolfram wrote:can some give me a easy example of this code. I'm a beginner and have no experience with C.
Polo gave a small piece of Objective-C code a few posts above if that's what you are looking for.
When it comes to the question this thread started with, it's no longer relevant. At that time, PureBasic for OS X was Carbon based.
The current 5.2x LTS version is Cocoa based and allows you to interact using the CocoaMessage() command.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: API call help
PB help says:Wolfram wrote:can some give me a easy example of this code. I'm a beginner and have no experience with C.
So here a version with patterns, based on Polo's Objective-C code:Note: The 'Pattern$' and 'PatternPosition' parameters have no effect on Mac OSX (the requester always displays all files).
Code: Select all
Macro CreateCocoaObject(objectName,withMethod="alloc")
CocoaMessage(0,0,objectName+" "+withMethod)
EndMacro
#showHiddenFiles = 1
#allowMultipleSelection = 1 << 1
#returnAbsoluteNames = 1 << 2
#NSFileHandlingPanelOKButton = 1
#NSFileHandlingPanelCancelButton = 0
Procedure OpenFileRequester_(List out.s(), title.s, defaultdirectory.s="", pattern.s="", message.s="", flags=0)
ClearList(out())
NSApp = CreateCocoaObject("NSApplication")
If NSApp
currentwin = CocoaMessage(0,NSApp,"keyWindow")
If Not currentwin
CocoaMessage(0,NSApp,"activateIgnoringOtherApps:",#YES)
EndIf
panel = CreateCocoaObject("NSOpenPanel","openPanel")
If panel
;
; set title
;
CocoaMessage(0,panel,"setTitle:$",@title)
;
; set optional message text
;
If message
CocoaMessage(0,panel,"setMessage:$",@message)
EndIf
;
; set allowed patterns, separated by '|'
;
If pattern <> ""
i = 1
nextPattern.s = StringField(pattern,i,"|")
fileTypesArray = CocoaMessage(0,0,"NSArray arrayWithObject:$", @nextPattern)
Repeat
i + 1
nextPattern = StringField(pattern,i,"|")
If nextPattern
fileTypesArray = CocoaMessage(0,fileTypesArray, "arrayByAddingObject:$", @nextPattern)
EndIf
Until nextPattern = ""
CocoaMessage(0,panel,"setAllowedFileTypes:",fileTypesArray)
EndIf
;
; show hidden files?
;
If flags & #showHiddenFiles
CocoaMessage(0,panel,"setShowsHiddenFiles:",#YES)
EndIf
;
; allow multiple selection?
;
If flags & #allowMultipleSelection
CocoaMessage(0,panel,"setAllowsMultipleSelection:",#YES)
EndIf
;
; set default directory
;
url = CocoaMessage(0,0,"NSURL URLWithString:$",@defaultdirectory)
CocoaMessage(0,panel,"setDirectoryURL:",url)
;
; run
;
If CocoaMessage(0,panel,"runModal") = #NSFileHandlingPanelOKButton
;
; get results
;
results = CocoaMessage(0,panel,"URLs")
If results
count = CocoaMessage(0, results, "count")
If count
For i = 0 To count-1
NSURL = CocoaMessage(0,results,"objectAtIndex:",i)
If NSURL
If Not flags & #returnAbsoluteNames
;
; return file names
;
string = CocoaMessage(0,NSURL,"fileSystemRepresentation")
If string
fileName.s = PeekS(string,-1,#PB_UTF8)
If AddElement(out())
out() = fileName
EndIf
EndIf
Else
;
; return absolute names
;
string = CocoaMessage(0,NSURL,"absoluteString")
If string
utf8 = CocoaMessage(0,string,"UTF8String")
If utf8
fileName.s = PeekS(utf8,-1,#PB_UTF8)
If AddElement(out())
out() = fileName
EndIf
EndIf
EndIf
EndIf
EndIf
Next i
EndIf
EndIf
EndIf
EndIf
EndIf
If currentwin
CocoaMessage(0,currentwin,"makeKeyWindow")
EndIf
ProcedureReturn count
EndProcedure
NewList files.s()
num = OpenFileRequester_( files(),
"Please choose file(s) to load",
"/users/",
"pb|pbi|prefs|rtf|txt",
"Optional message:"+#CR$+"Please open a file for loading."+#CR$+"Second message line",
#allowMultipleSelection |
#showHiddenFiles )
Debug num
ForEach files()
Debug files()
NextMy version uses newer methods, but I think it requires at least OS X v10.6.
Re: API call help
Many Thanks!
but I get an Error if I try to load a File
Object dose not respond to method "fileSystemRepresentation"
but I get an Error if I try to load a File
Object dose not respond to method "fileSystemRepresentation"
macOS Catalina 10.15.7
Re: API call help
The fileSystemRepresentation method requires OS X 10.9 (Mavericks).Wolfram wrote:Object dose not respond to method "fileSystemRepresentation"
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: API call help
Does it work for you with flag '#returnAbsoluteNames'?Wolfram wrote:but I get an Error if I try to load a File
Object dose not respond to method "fileSystemRepresentation"
In this case you get results like "file:///users/danilo/todo.rtf", but it could
be different URL for Network files.
Re: API call help
Here's also a simplified version of Danilo's approach returning all absolute names in one string separated by |
Minimum requirement is OS X 10.6
Minimum requirement is OS X 10.6
Code: Select all
#showHiddenFiles = 1 << 0
#allowMultipleSelection = 1 << 1
Procedure.s OpenFileRequester_(title.s, defaultdirectory.s = "", pattern.s = "", message.s = "", flags = 0)
Protected NSPanel, NSArray, NSString
NSPanel = CocoaMessage(0, 0, "NSOpenPanel openPanel")
NSArray = CocoaMessage(0, CocoaMessage(0, 0, "NSString stringWithString:$", @pattern), "componentsSeparatedByString:$", @"|")
CocoaMessage(0, NSPanel, "setTitle:$", @title)
CocoaMessage(0, NSPanel, "setDirectoryURL:", CocoaMessage(0, 0, "NSURL URLWithString:$", @defaultdirectory))
CocoaMessage(0, NSPanel, "setAllowedFileTypes:", NSArray)
CocoaMessage(0, NSPanel, "setMessage:$", @message)
If flags & #showHiddenFiles
CocoaMessage(0, NSPanel, "setShowsHiddenFiles:", #YES)
EndIf
If flags & #allowMultipleSelection
CocoaMessage(0, NSPanel, "setAllowsMultipleSelection:", #YES)
EndIf
If CocoaMessage(0, NSPanel, "runModal")
NSString = CocoaMessage(0, CocoaMessage(0, NSPanel, "URLs"), "componentsJoinedByString:$", @"|")
ProcedureReturn PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
Else
ProcedureReturn ""
EndIf
EndProcedure
Debug OpenFileRequester_("Please choose file(s) to load",
"/users/",
"pb|pbi|prefs|rtf|txt",
"Optional message:"+#CR$+"Please open a file for loading."+#CR$+"Second message line",
#allowMultipleSelection |
#showHiddenFiles )
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)



