[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
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 »

@William, maybe you could use a progress indicator

Code: Select all

If OpenWindow(0, 0, 0, 220, 60, "Progress Indicator", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ProgressBarGadget(0, 10, 10, 0, 0, 0, 0)
  Indicator = GadgetID(0)
  CocoaMessage(0, Indicator, "setIndeterminate:", #YES)
  CocoaMessage(0, Indicator, "setStyle:", 1)
  CocoaMessage(0, Indicator, "setControlSize:", 1)
  CocoaMessage(0, Indicator, "sizeToFit")
  
  CocoaMessage(0, Indicator, "startAnimation:", #nil)
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  
  CocoaMessage(0, Indicator, "stopAnimation:", #nil)
  
EndIf
Another option would be to use an image cursor (any PureBasic image can be used as a cursor).
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

WilliamL wrote:I expected to see all the same cursors as with Carbon but I don't see the spinning ball or watch. I need something that looks like the computer is busy. Odd that those two aren't there.
William,

Cocoa and Carbon are technically very different frameworks. So you unfortunately can't expect to find all elements from Carbon to be also implemented in Cocoa (like the animated cursors). But I have simply tried to run the animated Carbon cursors in Cocoa and they still seem to work!

Spinning wheel cursor:
http://www.purebasic.fr/english/viewtop ... 31&start=4

Spinning wheel and running watch:
http://www.purebasic.fr/english/viewtop ... 31&start=6

Update: The above linked examples only work in PB 5 x86 because the imported API functions were not ported to 64 bit by Apple!
Last edited by Shardik on Sun Nov 11, 2012 1:13 pm, edited 1 time in total.
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 »

Shardik wrote:But I have simply tried to run the animated Carbon cursors in Cocoa and they still seem to work!
Some things were removed with 10.7 Lion. QDDisplayWaitCursor for example is one of them.
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

wilbert wrote:Some things were removed with 10.7 Lion. QDDisplayWaitCursor for example is one of them.
Wilbert,
did you try the example with QDDisplayWaitCursor? It still works in Mountain Lion... :twisted:

So QDDisplayWaitCursor can't have been removed until now. I assume it has been declared as deprecated in Lion (even maybe QuickDraw completely?) but it's still working in Mountain Lion.

The example from my second link works too in Mountain Lion but instead of a running watch now a spinning disk with blue and white sectors is displayed.

William,
some programmers assume that animated cursors were not implemented in Cocoa on purpose because it is regarded as bad practice to display animated cursors (for further explanations take a look into my old Carbon thread).
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 »

Shardik wrote:did you try the example with QDDisplayWaitCursor? It still works in Mountain Lion... :twisted:
I'm using the x64 version of PureBasic by default.
I checked again with the x86 version and it seems to work for x86. For x64 however it doesn't.
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

wilbert wrote:I'm using the x64 version of PureBasic by default.
I checked again with the x86 version and it seems to work for x86. For x64 however it doesn't.
You are right. I am using the x86 version of PureBasic by default (because of many old programs requiring subsystem Carbon which is only available for 32 bit). QDDisplayWaitCursor is a QuickDraw function which isn't available for 64 bit programs, so programs needing 32 bit API functions won't run anymore in PB 5 x64. Both above linked programs therefore don't run in x64 mode!

QDDisplayWaitCursor was already deprecated in Mac OS X 10.4: :oops:
Apple's QuickDraw Reference wrote:QDDisplayWaitCursor
(Deprecated in Mac OS X v10.4. Use Quartz 2D instead; see Quartz Programming Guide for QuickDraw Developers.)
WilliamL
Addict
Addict
Posts: 1214
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by WilliamL »

Shardik,

Oh, yes, we did discuss the wait cursors back in June of 2011! For my own use, I'd like a 'wait cursor' for those times that are not as long as needing a progress bar but longer than 'is the program working?'. The added code of the Carbon version wasn't worth the effort but the simple Cocoa cursor change looked easy (one line).. but there wasn't any cursor that looked like waiting. I suppose I could use the 'full hand' to show waiting.

Wilbert's spinning progress bar is interesting. Actually that is pretty cool. I think that goes to the top of the list. :)

[later] Actually, the Mac 'spinning ball' (SPOD) is very effective at showing a wait state and over-writes any cursor anyway so trying to make a wait cursor is useless. If I need a wait indication then a progress gadget would seem to be the best option (like Wilbert's example).

Here is a Procedure to start a spinning wait animation and then stop it. It uses a ProgressGadget that is drawn (where ever you like - like the middle of the screen) and then is erased when the wait is over. It doesn't seem to matter that it appears on top of another gadget. I threw in some error checking but haven't really tried all the possibilities. :wink:

Code: Select all

Procedure Wait(wndw,state)
    Static Indicator,efid,startwndw
    If State=1 And startwndw=0 ; can't send start twice
        startwndw=wndw
        efid=ProgressBarGadget(#PB_Any, WindowWidth(wndw)/2, WindowHeight(wndw)/2, 0, 0, 0, 0) ; center of window
        Indicator = GadgetID(efid)
        CocoaMessage(0, Indicator, "setIndeterminate:", #YES)
        CocoaMessage(0, Indicator, "setStyle:", 1)
        CocoaMessage(0, Indicator, "setControlSize:", 1)
        CocoaMessage(0, Indicator, "sizeToFit")
        CocoaMessage(0, Indicator, "startAnimation:", #nil)
    Else
        If wndw=startwndw ; must be same as start window
            CocoaMessage(0, Indicator, "stopAnimation:", #nil)
            If IsGadget(efid) : FreeGadget(efid) : EndIf ; in case stop is sent before start
            startwndw=0
        EndIf
    EndIf
EndProcedure
[addendum] The above only works because the ProgressGadget is drawn by Cocoa, if you use a normal ProgressGadget (with bars) it will not draw completely because it needs to go thru the event loop. You will get the bar but not the enclosing box.
Last edited by WilliamL on Fri Nov 16, 2012 10:04 pm, edited 10 times in total.
MacBook Pro-M1 (2021), Sonoma 14.3.1 (CLT 15.3), PB 6.10b7 M1
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

William,

I only demonstrated how to utilize the system-predefined cursors in Cocoa. An alternative for you would be to draw an hourglass cursor by yourself and to change the cursor to your drawn image. The only drawback is that it is not possible to animate your Cocoa cursor. Try my example which loads a png image and uses this image as a custom cursor:

Code: Select all

Define Hotspot.NSPoint

OpenWindow(0, 200, 100, 290, 100, "Display custom cursor")
ButtonGadget(0, WindowWidth(0) / 2 - 120, 40, 240, 25, "Change cursor to custom image")

UsePNGImageDecoder()

If LoadImage(0, #PB_Compiler_Home + "Examples/Sources/Data/World.png")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget
        If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
          Hotspot\x = 4
          Hotspot\y = 4
          NewCursor = CocoaMessage(0, 0, "NSCursor alloc")
          CocoaMessage(0, NewCursor, "initWithImage:", ImageID(0), "hotSpot:@", @Hotspot)
          CocoaMessage(0, NewCursor, "set")
        EndIf
    EndSelect
  ForEver
EndIf
Update: The example now runs without problems in PB 5 x86 and x64. "hotSpot:" had to be changed to "hotSpot:@". Thank you for spotting the error, Wilbert!
Last edited by Shardik on Tue Nov 13, 2012 11:44 pm, edited 1 time in total.
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: [PB Cocoa] Methods, Tips & Tricks

Post by fsw »

-> Here <- is shown how to add the fullscreen button to your window.
If you want to switch the application into Fullscreen at program start you have to use the "toggleFullScreen" command (after initializing the Fullscreen button) like this:

Code: Select all

    CocoaMessage(0, WindowID(0), "setCollectionBehavior:", 128) ;
    CocoaMessage(0, WindowID(0), "toggleFullScreen:")

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Change height of rows in ListIconGadget (works also with ListViewGadget):

Code: Select all

Define RowHeight.CGFloat

OpenWindow(0, 200, 100, 420, 220, "Change ListIcon's row height")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, 102, "Name", 100, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnWidth) - 8)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ + "321 Logo Drive, Mouse House, Downtown")
Frame3DGadget(1, 20, GadgetY(0) + GadgetHeight(0) + 10, WindowWidth(0) - 40, 90, "Row height:")
TrackBarGadget(2, GadgetX(1) + 10, GadgetY(1) + 30, GadgetWidth(1) - 20, 23, 15, 26, #PB_TrackBar_Ticks)
CocoaMessage(0, GadgetID(2), "setAllowsTickMarkValuesOnly:", #YES)
TextGadget(3, GadgetX(1) + 10, GadgetY(2) + GadgetHeight(2) + 5, GadgetWidth(1) - 10, 20, "15     16     17     18     19     20     21     22     23     24     25")

; ----- Read current row height and set TrackBar to that value
CocoaMessage(@RowHeight, GadgetID(0), "rowHeight")
SetGadgetState(2, RowHeight)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 2
        RowHeight = GetGadgetState(2)
        ; ----- Set new row height
        CocoaMessage(0, GadgetID(0), "setRowHeight:@", @RowHeight)
      EndIf
  EndSelect
ForEver
jag
New User
New User
Posts: 2
Joined: Sun Nov 25, 2012 2:33 am
Location: New Hampshire

Re: [PB Cocoa] Methods, Tips & Tricks

Post by jag »

Hello,

The examples for using CocoaMessage() to access cocoa objects are very interesting, and I would like to experiment with them. What I am missing is a good example of how and what to specify at the beginning of my program to use them. Am I supposed to use Import... EndImport or OpenLibrary() and a prototype? I am trying to use the precompiled library from the zip file. I am a beginner with PB, so a simple example would be a big help, because I am stumped. I have tried searching the forum, but can't seem to find a complete enough example.

Thanks,

John
Mindphazer
Enthusiast
Enthusiast
Posts: 340
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

You need to download the file (first post of this thread), unzip it, then copy the file CocoaMsg_x86 (or x64, depending on Purebasic version) into /Purebasic/purelibraries/userlibraries
Restart compiler, then you can use CocoaMessage function as it was a native PB command.
MacBook Pro 14" M1 Pro - 16 Gb - MacOS 14 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Hide title line in ListIconGadget:

Code: Select all

OpenWindow(0, 200, 100, 430, 125, "ListIcon Example")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 50, "Name", 110)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnWidth) - 8)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ + "321 Logo Drive, Mouse House, Downtown")
ButtonGadget(1, WindowWidth(0) / 2 - 70, WindowHeight(0) - 30, 140, 25, "Hide title header")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1 And EventType() = #PB_EventType_LeftClick
        CocoaMessage(0, GadgetID(0), "setHeaderView:", 0)
        DisableGadget(1, #True)
      EndIf
  EndSelect
ForEver
jag
New User
New User
Posts: 2
Joined: Sun Nov 25, 2012 2:33 am
Location: New Hampshire

Re: [PB Cocoa] Methods, Tips & Tricks

Post by jag »

Thanks - Mindphazer,

That information was exactly what I needed.

John
Mindphazer
Enthusiast
Enthusiast
Posts: 340
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

jag wrote:Thanks - Mindphazer,

That information was exactly what I needed.

John
You're welcome :-)
MacBook Pro 14" M1 Pro - 16 Gb - MacOS 14 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
Post Reply