Change the app's icon in real-time

Mac OSX specific forum
User avatar
Torf
User
User
Posts: 13
Joined: Thu Apr 27, 2023 8:03 pm

Change the app's icon in real-time

Post by Torf »

Hello.

Please, is it possible to change the icon of my app in real-time?

I supose that Cocoa would to have a method for do this, but I can not find it.

Thanks you in advance!
User avatar
yuki
Enthusiast
Enthusiast
Posts: 101
Joined: Sat Mar 31, 2018 9:09 pm

Re: Change the app's icon in real-time

Post by yuki »

The applicationIconImage property of NSApplication does what you want, e.g.:

Code: Select all

; Get application instance.
Define app = CocoaMessage(#Null, #Null, "NSApplication sharedApplication")
; Create a solid black image.
Define img = CreateImage(#PB_Any, 256, 256, 32)
; Replace the application's icon with our image.
CocoaMessage(#Null, app, "setApplicationIconImage:", ImageID(img))
Here's a complete, runnable example which should create an empty window and update the app's icon on a timer:

Code: Select all

EnableExplicit

Define wnd = OpenWindow(#PB_Any, 0, 0, 400, 300, "Dynamic Icon", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define app = CocoaMessage(#Null, #Null, "NSApplication sharedApplication")
Define img = CreateImage(#PB_Any, 256, 256, 32)
Define iconSizeStep = 0

AddWindowTimer(wnd, 1, 32)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow, #PB_Event_Menu
      Break
    Case #PB_Event_Timer
      iconSizeStep % 100
      iconSizeStep + 1
      StartDrawing(ImageOutput(img))
        DrawingMode(#PB_2DDrawing_AllChannels)
        Box(0, 0, OutputWidth(), OutputHeight(), $00000000)
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Circle(OutputWidth() / 2, OutputHeight() / 2, (iconSizeStep / 200.0) * OutputWidth(), $ffff00ff)
      StopDrawing()
      CocoaMessage(#Null, app, "setApplicationIconImage:", ImageID(img))
  EndSelect
ForEver
User avatar
deseven
Enthusiast
Enthusiast
Posts: 367
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

Re: Change the app's icon in real-time

Post by deseven »

That's a very clever example, yuki!
I didn't even know that icon changing could be so fast, you could even create animations that way :)
User avatar
yuki
Enthusiast
Enthusiast
Posts: 101
Joined: Sat Mar 31, 2018 9:09 pm

Re: Change the app's icon in real-time

Post by yuki »

deseven wrote: Mon Oct 09, 2023 7:42 pm That's a very clever example, yuki!
I didn't even know that icon changing could be so fast, you could even create animations that way :)
Yeah, it can be changed quite rapidly!

Though, submitting many images in short succession this way (esp. large ones) can ramp up load a bit. So, while it's definitely usable for very dynamic but brief transitions, continuous long-running animations may have users complain (about either visual noise or fan noise :wink:).

You can take control of the application's NSDockTile presentation to carefully optimise this, but it will come at the cost of added code complexity.
User avatar
Torf
User
User
Posts: 13
Joined: Thu Apr 27, 2023 8:03 pm

Re: Change the app's icon in real-time

Post by Torf »

yuki wrote: Mon Oct 09, 2023 3:37 pm The applicationIconImage property of NSApplication does what you want, e.g.:

Code: Select all

; Get application instance.
Define app = CocoaMessage(#Null, #Null, "NSApplication sharedApplication")
; Create a solid black image.
Define img = CreateImage(#PB_Any, 256, 256, 32)
; Replace the application's icon with our image.
CocoaMessage(#Null, app, "setApplicationIconImage:", ImageID(img))
Here's a complete, runnable example which should create an empty window and update the app's icon on a timer:

Code: Select all

EnableExplicit

Define wnd = OpenWindow(#PB_Any, 0, 0, 400, 300, "Dynamic Icon", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define app = CocoaMessage(#Null, #Null, "NSApplication sharedApplication")
Define img = CreateImage(#PB_Any, 256, 256, 32)
Define iconSizeStep = 0

AddWindowTimer(wnd, 1, 32)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow, #PB_Event_Menu
      Break
    Case #PB_Event_Timer
      iconSizeStep % 100
      iconSizeStep + 1
      StartDrawing(ImageOutput(img))
        DrawingMode(#PB_2DDrawing_AllChannels)
        Box(0, 0, OutputWidth(), OutputHeight(), $00000000)
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Circle(OutputWidth() / 2, OutputHeight() / 2, (iconSizeStep / 200.0) * OutputWidth(), $ffff00ff)
      StopDrawing()
      CocoaMessage(#Null, app, "setApplicationIconImage:", ImageID(img))
  EndSelect
ForEver

Thanks very much, Yuki, it's just I need. It's a very good example.
Post Reply