Page 14 of 16
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Fri Sep 16, 2016 11:43 am
by deseven
More on that (do something when user changes interface mode):
Code: Select all
Define app = CocoaMessage(0,0,"NSApplication sharedApplication")
Define appDelegate = CocoaMessage(0,app,"delegate")
Define delegateClass = object_getClass_(appDelegate)
Define selector = sel_registerName_("darkModeChanged:")
Define distributedNotificationCenter = CocoaMessage(0,0,"NSDistributedNotificationCenter defaultCenter")
Procedure darkModeChanged(notification)
Debug "mode changed"
EndProcedure
class_addMethod_(delegateClass,selector,@darkModeChanged(),"v@:@")
CocoaMessage(0,distributedNotificationCenter,
"addObserver:",appDelegate,
"selector:",selector,
"name:$",@"AppleInterfaceThemeChangedNotification",
"object:",#nil)
OpenWindow(0,#PB_Ignore,#PB_Ignore,100,100,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
Repeat : Until WaitWindowEvent(100) = #PB_Event_CloseWindow
Again thanks wilbert for showing me how to add observers
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Mon Dec 12, 2016 8:22 pm
by wilbert
Small code to show how to format text of an EditorGadget with html code.
Code: Select all
If OpenWindow(0, 0, 0, 320, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(0, 10, 10, 300, 130)
HTMLCode.s = "<font face='Helvetica' size='14'><b>Test</b> <font color='red'>code</font></font>"
AttributedString = CocoaMessage(0, CocoaMessage(0, 0, "NSAttributedString alloc"), "initWithHTML:",
CocoaMessage(0, CocoaMessage(0, 0, "NSString stringWithString:$", @HTMLCode),
"dataUsingEncoding:", 10), "documentAttributes:", #Null)
If AttributedString
TextStorage = CocoaMessage(0, GadgetID(0), "textStorage")
CocoaMessage(0, TextStorage, "setAttributedString:", AttributedString)
CocoaMessage(0, AttributedString, "release")
EndIf
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Thu May 04, 2017 11:23 pm
by deseven
Restarting your app (code ported from
this gist)
Code: Select all
Procedure restartApp(delay.i)
Protected task = CocoaMessage(0,CocoaMessage(0,CocoaMessage(0,0,"NSTask alloc"),"init"),"autorelease")
Protected args = CocoaMessage(0,0,"NSMutableArray arrayWithCapacity:",0)
Protected appPath.s = PeekS(CocoaMessage(0,CocoaMessage(0,CocoaMessage(0,0,"NSBundle mainBundle"),"bundlePath"),"UTF8String"),-1,#PB_UTF8)
Protected command.s = "sleep " + Str(delay) + ~"; open -a \"" + appPath + ~"\""
CocoaMessage(0,args,"addObject:$",@"-c")
CocoaMessage(0,args,"addObject:$",@command)
CocoaMessage(0,task,"setLaunchPath:$",@"/bin/sh")
CocoaMessage(0,task,"setArguments:",args)
CocoaMessage(0,task,"launch")
End
EndProcedure
OpenWindow(0,#PB_Ignore,#PB_Ignore,400,300,"restart app test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ButtonGadget(0,150,135,100,30,"restart")
Repeat
ev = WaitWindowEvent()
If ev = #PB_Event_Gadget And EventGadget() = 0
restartApp(1)
EndIf
Until ev = #PB_Event_CloseWindow
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Fri Nov 03, 2017 4:39 pm
by wilbert
Create UUID.
Method 1
Code: Select all
ImportC ""
CFUUIDCreate(alloc = #Null)
CFUUIDCreateString(alloc, uuid)
EndImport
Procedure.s CreateUUID()
Protected.i uuidRef, uuidStringRef, UUID.s
uuidRef = CFUUIDCreate()
uuidStringRef = CFUUIDCreateString(#Null, uuidRef)
CFRelease_(uuidRef)
UUID = PeekS(CocoaMessage(0, uuidStringRef, "UTF8String"), -1, #PB_UTF8)
CFRelease_(uuidStringRef)
ProcedureReturn UUID
EndProcedure
Debug CreateUUID()
Method 2 (MacOS 10.8+)
Code: Select all
UUID.s = PeekS(CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSUUID UUID"), "UUIDString"), "UTF8String"), -1, #PB_UTF8)
Debug UUID
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Sat Jun 13, 2020 10:24 am
by collectordave
I have created a script to renew an applications icon and saved it as a script.
Can wilberts AppleScript procedure be used to run the script or is there another way?
Regards
CD
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Sat Jun 13, 2020 5:12 pm
by wilbert
collectordave wrote:Can wilberts AppleScript procedure be used to run the script or is there another way?
If you load the script you can use that procedure.
Another option might be the terminal command
osascript
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Sun Sep 27, 2020 11:37 am
by deseven
Run a program and write to its stdin using NSTask (because
PB's RunProgram is buggy):
Code: Select all
Procedure RunProgramNative(path.s,args.s,workdir.s = "",stdin.s = "")
Protected i
Protected argsArray
If args
Protected arg.s = StringField(args,1," ")
If arg
argsArray = CocoaMessage(0,0,"NSArray arrayWithObject:$",@arg)
If CountString(args," ") > 0
For i = 2 To CountString(args," ") + 1
arg = StringField(args,i," ")
If arg
argsArray = CocoaMessage(0,argsArray,"arrayByAddingObject:$",@arg)
EndIf
Next
EndIf
EndIf
EndIf
Protected task = CocoaMessage(0,CocoaMessage(0,0,"NSTask alloc"),"init")
CocoaMessage(0,task,"setLaunchPath:$",@path)
If argsArray
CocoaMessage(0,task,"setArguments:",argsArray)
EndIf
If workdir
CocoaMessage(0,task,"setCurrentDirectoryPath:$",@workdir)
EndIf
If stdin
Protected writePipe = CocoaMessage(0,0,"NSPipe pipe")
Protected writeHandle = CocoaMessage(0,writePipe,"fileHandleForWriting")
CocoaMessage(0,task,"setStandardInput:",writePipe)
Protected string = CocoaMessage(0,0,"NSString stringWithString:$",@stdin)
Protected stringData = CocoaMessage(0,string,"dataUsingEncoding:",#NSUTF8StringEncoding)
EndIf
CocoaMessage(0,task,"launch")
If stdin
CocoaMessage(0,writeHandle,"writeData:",stringData)
CocoaMessage(0,writeHandle,"closeFile")
EndIf
CocoaMessage(0,task,"release")
EndProcedure
Based on
this article. Reading from stdout is also an option, see the bottom example.
UPD: there is now
a module for that too
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Sun Feb 14, 2021 3:44 pm
by mk-soft
Thanks to Wilbert
Update v1.02.0
- Added Struct CFRunLoopTimerContext
- Added Parameter "*Info"
Code: Select all
;-TOP
; Comment : RunLoopTimer; None blocking GUI
; Author : mk-soft
; Source : Thanks to Wilbert, 25.10.2015
; Version : 1.02.0
; Create : 14.02.2021
; Update : 19.03.2021
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
; Syntax Callback:
; - ProcedureC MyTimerCallback(timer, *info)
ImportC ""
CFRelease(object)
CFAbsoluteTimeGetCurrent.d()
CFRunLoopAddCommonMode(rl, mode)
CFRunLoopAddTimer(rl, timer, mode)
CFRunLoopGetCurrent()
CFRunLoopGetMain()
CFRunLoopTimerGetNextFireDate.d(timer)
CFRunLoopRemoveTimer(rl, timer, mode)
CFRunLoopTimerCreate(allocator, fireDate.d, interval.d, flags, order, callout, *context)
dlsym(handle, symbol.p-utf8)
EndImport
Structure struct_CFRunLoopTimerContext
Version.i
*Info
*Retain
*Release
*copyDescription
EndStructure
Structure struct_CFRunLoopTimers
Timer.i
Context.struct_CFRunLoopTimerContext
EndStructure
Global *NSEventTrackingRunLoopMode.Integer = dlsym(-2, "NSEventTrackingRunLoopMode")
Global *NSModalPanelRunLoopMode.Integer = dlsym(-2, "NSModalPanelRunLoopMode")
Global *kCFRunLoopCommonModes.Integer = dlsym(-2, "kCFRunLoopCommonModes")
Global NewMap RunLoopTimers.struct_CFRunLoopTimers()
Procedure RunLoopRemoveTimer(Timer)
Protected runLoop
If FindMapElement(RunLoopTimers(), Str(Timer))
myTimer = RunLoopTimers()\Timer
runLoop = CFRunLoopGetCurrent()
CFRunLoopRemoveTimer(runLoop, myTimer, *kCFRunLoopCommonModes\i)
CFRelease(myTimer)
DeleteMapElement(RunLoopTimers())
EndIf
EndProcedure
Procedure RunLoopAddTimer(Timer, Timeout, TimerCallbackC, *Info = 0)
Static runLoop
Protected time.d, myTimer
If Not runLoop
runLoop = CFRunLoopGetCurrent()
CFRunLoopAddCommonMode(runLoop, *NSEventTrackingRunLoopMode\i)
EndIf
RunLoopRemoveTimer(Timer)
If AddMapElement(RunLoopTimers(), Str(Timer))
RunLoopTimers()\Context\Info = *Info
time = Timeout / 1000.0
myTimer = CFRunLoopTimerCreate(#Null, CFAbsoluteTimeGetCurrent(), time, 0, 0, TimerCallbackC, RunLoopTimers()\Context)
If myTimer
RunLoopTimers()\Timer = myTimer
CFRunLoopAddTimer(runLoop, myTimer, *kCFRunLoopCommonModes\i)
Else
DeleteMapElement(RunLoopTimers())
EndIf
EndIf
ProcedureReturn myTimer
EndProcedure
CompilerEndIf
CompilerIf #PB_Compiler_IsMainFile
Define start_counter = 1
; Timer callback
ProcedureC MyTimerCallback(timer, *info)
AddGadgetItem(0, 0, "Start " + Str(*info) + #LF$ + StrD(CFRunLoopTimerGetNextFireDate(timer), 1))
EndProcedure
; Window resize callback
Procedure UpdateWindow()
ResizeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
EndProcedure
; Main
If OpenWindow(0, 0, 0, 400, 300, "Runloop Timer Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
CreateMenu(0, WindowID(0))
MenuTitle("Timer")
MenuItem(0, "Start")
MenuItem(1, "Stop")
ListIconGadget(0, 10, 10, 380, 280, "Info", 140)
AddGadgetColumn(0, 1, "Next Time", 200)
BindEvent(#PB_Event_SizeWindow, @UpdateWindow())
RunLoopAddTimer(1, 500, @MyTimerCallback(), start_counter)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Menu
Select EventMenu()
Case 0
start_counter + 1
RunLoopAddTimer(1, 500, @MyTimerCallback(), start_counter)
Case 1
RunLoopRemoveTimer(1)
EndSelect
EndSelect
ForEver
RunLoopRemoveTimer(1)
EndIf
CompilerEndIf
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Fri Mar 19, 2021 11:00 am
by deseven
mk-soft
Are there any benefits to that in comparison to the usual AddWindowTimer(), BindEvent(#PB_Event_Timer,...), RemoveWindowTimer()?
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Fri Mar 19, 2021 6:09 pm
by mk-soft
@deseven
The WindowTimer does not run when the menu is active or when the window size is changed.
Update v1.02.0
- Added Struct CFRunLoopTimerContext
- Added Parameter "*Info"
Now we can pass the parameter "*Info" to timer callback!
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Fri Mar 19, 2021 11:27 pm
by deseven
mk-soft wrote:The WindowTimer does not run when the menu is active or when the window size is changed.
Ah, nice to know, thanks
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Wed Oct 27, 2021 6:59 am
by wilbert
wilbert wrote: ↑Sat Sep 29, 2012 7:50 am
Image load and catch (all OS X supported image types, for example bmp, gif, icns, ico, jpeg, jpeg2000, png, tga, tiff).
Code: Select all
CompilerIf Not Defined(vImage_Buffer, #PB_Structure)
Structure vImage_Buffer
*data
height.i
width.i
rowBytes.i
EndStructure
CompilerEndIf
ImportC "-framework Accelerate"
vImageUnpremultiplyData_RGBA8888 (*src, *dest, flags)
EndImport
Procedure LoadImageEx(Image, Filename.s)
Protected.i Result, Rep, vImg.vImage_Buffer
Protected Size.NSSize, Point.NSPoint
CocoaMessage(@Rep, 0, "NSImageRep imageRepWithContentsOfFile:$", @Filename)
If Rep
Size\width = CocoaMessage(0, Rep, "pixelsWide")
Size\height = CocoaMessage(0, Rep, "pixelsHigh")
If Size\width And Size\height
CocoaMessage(0, Rep, "setSize:@", @Size)
Else
CocoaMessage(@Size, Rep, "size")
EndIf
If Size\width And Size\height
Result = CreateImage(Image, Size\width, Size\height, 32, #PB_Image_Transparent)
If Result
If Image = #PB_Any : Image = Result : EndIf
StartDrawing(ImageOutput(Image))
CocoaMessage(0, Rep, "drawAtPoint:@", @Point)
If CocoaMessage(0, Rep, "hasAlpha")
vImg\data = DrawingBuffer()
vImg\width = OutputWidth()
vImg\height = OutputHeight()
vImg\rowBytes = DrawingBufferPitch()
vImageUnPremultiplyData_RGBA8888(@vImg, @vImg, 0)
EndIf
StopDrawing()
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure CatchImageEx(Image, *MemoryAddress, MemorySize)
Protected.i Result, DataObj, Class, Rep, vImg.vImage_Buffer
Protected Size.NSSize, Point.NSPoint
CocoaMessage(@DataObj, 0, "NSData dataWithBytesNoCopy:", *MemoryAddress, "length:", MemorySize, "freeWhenDone:", #NO)
CocoaMessage(@Class, 0, "NSImageRep imageRepClassForData:", DataObj)
If Class
CocoaMessage(@Rep, Class, "imageRepWithData:", DataObj)
If Rep
Size\width = CocoaMessage(0, Rep, "pixelsWide")
Size\height = CocoaMessage(0, Rep, "pixelsHigh")
If Size\width And Size\height
CocoaMessage(0, Rep, "setSize:@", @Size)
Else
CocoaMessage(@Size, Rep, "size")
EndIf
If Size\width And Size\height
Result = CreateImage(Image, Size\width, Size\height, 32, #PB_Image_Transparent)
If Result
If Image = #PB_Any : Image = Result : EndIf
StartDrawing(ImageOutput(Image))
CocoaMessage(0, Rep, "drawAtPoint:@", @Point)
If CocoaMessage(0, Rep, "hasAlpha")
vImg\data = DrawingBuffer()
vImg\width = OutputWidth()
vImg\height = OutputHeight()
vImg\rowBytes = DrawingBufferPitch()
vImageUnPremultiplyData_RGBA8888(@vImg, @vImg, 0)
EndIf
StopDrawing()
EndIf
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Save image (Compression is only used for #NSJPEGFileType)
Code: Select all
Procedure SaveImageEx(Image, FileName.s, Type = #NSPNGFileType, Compression.f = 0.8)
Protected c.i = CocoaMessage(0, 0, "NSNumber numberWithFloat:@", @Compression)
Protected p.i = CocoaMessage(0, 0, "NSDictionary dictionaryWithObject:", c, "forKey:$", @"NSImageCompressionFactor")
Protected imageReps.i = CocoaMessage(0, ImageID(Image), "representations")
Protected imageData.i = CocoaMessage(0, 0, "NSBitmapImageRep representationOfImageRepsInArray:", imageReps, "usingType:", Type, "properties:", p)
CocoaMessage(0, imageData, "writeToFile:$", @FileName, "atomically:", #NO)
EndProcedure
Example
Code: Select all
Image = LoadImageEx(#PB_Any, "MyIcon.icns")
To show a full list of supported types
Code: Select all
Debug PeekS(CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSImage imageTypes"), "description"), "UTF8String"), -1, #PB_UTF8)
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Wed Oct 27, 2021 3:21 pm
by mrbungle
Thank you!
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Sat Dec 25, 2021 8:21 pm
by mrbungle
This code doesn't seem to work using PB6 Beta 1 on an M1 Mac. You have to use the built in LoadImage() function.
wilbert wrote: ↑Wed Oct 27, 2021 6:59 am
wilbert wrote: ↑Sat Sep 29, 2012 7:50 am
Image load and catch (all OS X supported image types, for example bmp, gif, icns, ico, jpeg, jpeg2000, png, tga, tiff).
Code: Select all
CompilerIf Not Defined(vImage_Buffer, #PB_Structure)
Structure vImage_Buffer
*data
height.i
width.i
rowBytes.i
EndStructure
CompilerEndIf
ImportC "-framework Accelerate"
vImageUnpremultiplyData_RGBA8888 (*src, *dest, flags)
EndImport
Procedure LoadImageEx(Image, Filename.s)
Protected.i Result, Rep, vImg.vImage_Buffer
Protected Size.NSSize, Point.NSPoint
CocoaMessage(@Rep, 0, "NSImageRep imageRepWithContentsOfFile:$", @Filename)
If Rep
Size\width = CocoaMessage(0, Rep, "pixelsWide")
Size\height = CocoaMessage(0, Rep, "pixelsHigh")
If Size\width And Size\height
CocoaMessage(0, Rep, "setSize:@", @Size)
Else
CocoaMessage(@Size, Rep, "size")
EndIf
If Size\width And Size\height
Result = CreateImage(Image, Size\width, Size\height, 32, #PB_Image_Transparent)
If Result
If Image = #PB_Any : Image = Result : EndIf
StartDrawing(ImageOutput(Image))
CocoaMessage(0, Rep, "drawAtPoint:@", @Point)
If CocoaMessage(0, Rep, "hasAlpha")
vImg\data = DrawingBuffer()
vImg\width = OutputWidth()
vImg\height = OutputHeight()
vImg\rowBytes = DrawingBufferPitch()
vImageUnPremultiplyData_RGBA8888(@vImg, @vImg, 0)
EndIf
StopDrawing()
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure CatchImageEx(Image, *MemoryAddress, MemorySize)
Protected.i Result, DataObj, Class, Rep, vImg.vImage_Buffer
Protected Size.NSSize, Point.NSPoint
CocoaMessage(@DataObj, 0, "NSData dataWithBytesNoCopy:", *MemoryAddress, "length:", MemorySize, "freeWhenDone:", #NO)
CocoaMessage(@Class, 0, "NSImageRep imageRepClassForData:", DataObj)
If Class
CocoaMessage(@Rep, Class, "imageRepWithData:", DataObj)
If Rep
Size\width = CocoaMessage(0, Rep, "pixelsWide")
Size\height = CocoaMessage(0, Rep, "pixelsHigh")
If Size\width And Size\height
CocoaMessage(0, Rep, "setSize:@", @Size)
Else
CocoaMessage(@Size, Rep, "size")
EndIf
If Size\width And Size\height
Result = CreateImage(Image, Size\width, Size\height, 32, #PB_Image_Transparent)
If Result
If Image = #PB_Any : Image = Result : EndIf
StartDrawing(ImageOutput(Image))
CocoaMessage(0, Rep, "drawAtPoint:@", @Point)
If CocoaMessage(0, Rep, "hasAlpha")
vImg\data = DrawingBuffer()
vImg\width = OutputWidth()
vImg\height = OutputHeight()
vImg\rowBytes = DrawingBufferPitch()
vImageUnPremultiplyData_RGBA8888(@vImg, @vImg, 0)
EndIf
StopDrawing()
EndIf
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Save image (Compression is only used for #NSJPEGFileType)
Code: Select all
Procedure SaveImageEx(Image, FileName.s, Type = #NSPNGFileType, Compression.f = 0.8)
Protected c.i = CocoaMessage(0, 0, "NSNumber numberWithFloat:@", @Compression)
Protected p.i = CocoaMessage(0, 0, "NSDictionary dictionaryWithObject:", c, "forKey:$", @"NSImageCompressionFactor")
Protected imageReps.i = CocoaMessage(0, ImageID(Image), "representations")
Protected imageData.i = CocoaMessage(0, 0, "NSBitmapImageRep representationOfImageRepsInArray:", imageReps, "usingType:", Type, "properties:", p)
CocoaMessage(0, imageData, "writeToFile:$", @FileName, "atomically:", #NO)
EndProcedure
Example
Code: Select all
Image = LoadImageEx(#PB_Any, "MyIcon.icns")
To show a full list of supported types
Code: Select all
Debug PeekS(CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSImage imageTypes"), "description"), "UTF8String"), -1, #PB_UTF8)
Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Sun Dec 26, 2021 7:07 am
by wilbert
mrbungle wrote: ↑Sat Dec 25, 2021 8:21 pm
This code doesn't seem to work using PB6 Beta 1 on an M1 Mac. You have to use the built in LoadImage() function.
Unfortunately I don't have a M1 Mac and the OS of my Mac doesn't get updated anymore.