For a Mac only application it is possible to use a DesktopButton and set the Mac button style to Square. It can have an image and reacts to mouse presses.
You have to do it with declares or plugins, the following method will do it for any control that allows an image. It also works for controls that allow more than one image (such as DesktopSegmentedButtons)
Sub setControlImage(ControlHandle as Ptr, ThisImage as Picture, isTemplate as Boolean, nSegment as Integer = -1)
Var finalImage As Ptr = ThisImage.CopyOSHandle( Picture.HandleTypes.MacNSImage )
Declare Sub SetTemplate Lib "AppKit" Selector "setTemplate:" ( imageObj As Ptr, value As Boolean )
SetTemplate( finalImage, True )
// We need to know if the received Handler can respond to the setImage message (that is, it's a View)
Declare Function RespondsToSelector Lib "/usr/lib/libobjc.A.dylib" Selector "respondsToSelector:" ( obj As Ptr, sel As Ptr ) As Boolean
Declare Function NSSelectorFromString Lib "Foundation" ( sel As CFStringRef ) As Ptr
Var sel As Ptr = NSSelectorFromString( "setImage:" )
Var sel2 As Ptr = NSSelectorFromString( "setImage:forSegment:" )
// We check if it's a valid handler, we have an NSImage object and the handler can receive the "setImage" message
If ControlHandle <> Nil And finalImage <> Nil And RespondsToSelector( ControlHandle, sel ) Then
Declare Sub Set Lib "AppKit" Selector "setImage:" ( control As Ptr, Image As Ptr )
// We set the NSImage to the received control
Set( ControlHandle, finalImage )
ElseIf nSegment <> -1 And ControlHandle <> Nil And finalImage <> Nil And RespondsToSelector( ControlHandle, sel2 ) Then
Declare Sub Set Lib "AppKit" Selector "setImage:forSegment:" ( control As Ptr, Image As Ptr, segment As Integer )
// We set the NSImage to the received control
Set( ControlHandle, finalImage, nSegment )
End If
End Sub
// Set PicFile as the image of the myButton DesktopButton.
// If you set isTemplate to true use a black and white image and it will automatically swap with light / dark mode.
setControlImage( myButton.handle, PicFile, true )
// set the image of the first segment
setControlImage( mySegment.handle, PicFile1, true, 0 )
// set the image of the second segment
setControlImage( mySegment.handle, PicFile2, true, 1 )
You can also use SF symbols in buttons. At the end of the blog article is a sample project you can download, which shows an SF symbol in the DesktopButton.