[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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 :)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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
Windows (x64)
Raspberry Pi OS (Arm64)
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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
Last edited by deseven on Sun Dec 26, 2021 9:12 pm, edited 1 time in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mk-soft »

Thanks to Wilbert :wink:

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
Last edited by mk-soft on Fri Mar 19, 2021 7:17 pm, edited 2 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by deseven »

mk-soft
Are there any benefits to that in comparison to the usual AddWindowTimer(), BindEvent(#PB_Event_Timer,...), RemoveWindowTimer()?
Last edited by deseven on Fri Mar 19, 2021 11:28 pm, edited 1 time in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mk-soft »

@deseven

The WindowTimer does not run when the menu is active or when the window size is changed. :( :wink:

Update v1.02.0
- Added Struct CFRunLoopTimerContext
- Added Parameter "*Info"

Now we can pass the parameter "*Info" to timer callback!
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by deseven »

mk-soft wrote:The WindowTimer does not run when the menu is active or when the window size is changed. :( :wink:
Ah, nice to know, thanks :)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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)
Windows (x64)
Raspberry Pi OS (Arm64)
mrbungle
Enthusiast
Enthusiast
Posts: 111
Joined: Wed Dec 30, 2020 3:18 am

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mrbungle »

Thank you!
mrbungle
Enthusiast
Enthusiast
Posts: 111
Joined: Wed Dec 30, 2020 3:18 am

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post 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.
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply