[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Mindphazer wrote:I'm trying to find a way to sort a ListIconGadget when clicking on a column header...
Perhaps "Cocoa master" Wilbert can improve the following code even further by defining a second delegate for sorting the contents automatically. Currently my code requires you to store the ListIcon contents into the linked list Table() and to do the sorting by yourself in the procedure SortListIcon().

And because of a PureBasic bug in Pseudotype P-ASCII the following code will not work in 64 bit mode with unicode enabled although in 32 bit mode with Unicode it does work. If you need 64 bit and unicode you have to use PokeS to poke the required strings with flag #PB_ASCII into a buffer and to hand over this buffer to the functions sel_registerName() and class_addMethod().

Code: Select all

EnableExplicit

ImportC ""
  sel_registerName(*MethodName)
  class_addMethod(Class.I, Selector.I, Implementation.I, *Types)
EndImport

Structure TableEntry
  Name.S
  Address.S
EndStructure

Enumeration #PB_Event_FirstCustomValue
  #PB_Event_ListIcon_SortAscending
  #PB_Event_ListIcon_SortDescending
EndEnumeration

Define AppDelegate.I
Define AscendingArrow.I
Define ColumnArray.I
Define DelegateClass.I
Define DescendingArrow.I
Define i.I
Define LastSortColumn.I
Define MethodName.S = "tableView:didClickTableColumn:"
Define *MethodNameBuffer
Define SortColumn.I
Define SortIsAscending.I
Define Types.S = "v@:@@"
Define *TypesBuffer

NewList Table.TableEntry()

ProcedureC LeftClickOnHeaderCellCallback(Object.I, Selector.I, View.I, Column.I)
  Shared AscendingArrow.I
  Shared DescendingArrow.I
  Shared SortColumn.I
  Shared SortIsAscending.I

  SortColumn = Column

  If SortIsAscending
    PostEvent(#PB_Event_ListIcon_SortDescending)
  Else
    PostEvent(#PB_Event_ListIcon_SortAscending)
  EndIf

  SortIsAscending ! 1
EndProcedure

Procedure SortListIcon(ListIconID.I, SortColumn.I)
  Shared Table()
  Shared SortIsAscending.I

  Protected ColumnIndex.I

  ColumnIndex = Val(PeekS(CocoaMessage(0, CocoaMessage(0, SortColumn, "identifier"), "UTF8String"), -1, #PB_UTF8))

  If SortIsAscending
    If ColumnIndex = 0
      SortStructuredList(Table(), #PB_Sort_Ascending, OffsetOf(TableEntry\Name), #PB_String)
    Else
      SortStructuredList(Table(), #PB_Sort_Ascending, OffsetOf(TableEntry\Address), #PB_String)
    EndIf
  Else
    If ColumnIndex = 0
      SortStructuredList(Table(), #PB_Sort_Descending, OffsetOf(TableEntry\Name), #PB_String)
    Else
      SortStructuredList(Table(), #PB_Sort_Descending, OffsetOf(TableEntry\Address), #PB_String)
    EndIf
  EndIf

  ClearGadgetItems(ListIconID)

  ForEach Table()
    AddGadgetItem(ListIconID, -1, Table()\Name + #LF$ + Table()\Address)
  Next
EndProcedure

*MethodNameBuffer = AllocateMemory(StringByteLength(MethodName, #PB_Ascii) + 1)
PokeS(*MethodNameBuffer, MethodName, -1, #PB_Ascii)
*TypesBuffer = AllocateMemory(StringByteLength(Types, #PB_Ascii) + 1)
PokeS(*TypesBuffer, Types, -1, #PB_Ascii)
AppDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
DelegateClass = CocoaMessage(0, AppDelegate, "class")
class_addMethod(DelegateClass, sel_registerName(*MethodNameBuffer),  @LeftClickOnHeaderCellCallback(), *TypesBuffer)
FreeMemory(*MethodNameBuffer)
FreeMemory(*TypesBuffer)
OpenWindow(0, 200, 100, 430, 95, "Sort ListIcon with column click")

ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Name", 110)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnWidth) - 8)

For i = 1 To 3
  AddElement(Table())
  Read.S Table()\Name
  Read.S Table()\Address
Next i

ForEach Table()
  AddGadgetItem(0, -1, Table()\Name + #LF$ + Table()\Address)
Next

AscendingArrow = CocoaMessage(0, CocoaMessage(0, 0, "NSImage imageNamed:$", @"NSAscendingSortIndicator"), "retain")
DescendingArrow = CocoaMessage(0, CocoaMessage(0, 0, "NSImage imageNamed:$", @"NSDescendingSortIndicator"), "retain")

CocoaMessage(@ColumnArray, GadgetID(0), "tableColumns")
CocoaMessage(@SortColumn, ColumnArray, "objectAtIndex:", 0)
LastSortColumn = SortColumn
SortIsAscending = #True
SortListIcon(0, SortColumn)
CocoaMessage(0, GadgetID(0), "setIndicatorImage:", AscendingArrow, "inTableColumn:", SortColumn)
CocoaMessage(0, GadgetID(0), "setDelegate:", AppDelegate)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_ListIcon_SortAscending
      If SortColumn <> LastSortColumn
        CocoaMessage(0, GadgetID(0), "setIndicatorImage:", 0, "inTableColumn:", LastSortColumn)
        LastSortColumn = SortColumn
      EndIf
      SortListIcon(0, SortColumn)
      CocoaMessage(0, GadgetID(0), "setIndicatorImage:", AscendingArrow, "inTableColumn:", SortColumn)
    Case #PB_Event_ListIcon_SortDescending
      If SortColumn <> LastSortColumn
        CocoaMessage(0, GadgetID(0), "setIndicatorImage:", 0, "inTableColumn:", LastSortColumn)
        LastSortColumn = SortColumn
      EndIf

      SortListIcon(0, SortColumn)
      CocoaMessage(0, GadgetID(0), "setIndicatorImage:", DescendingArrow, "inTableColumn:", SortColumn)
  EndSelect
ForEver

End

DataSection
  Data.S "Harry Rannit"
  Data.S "12 Parliament Way, Battle Street, By the Bay"
  Data.S "Ginger Brokeit"
  Data.S "330 PureBasic Road, BigTown, CodeCity"
  Data.S "Didi Foundit"
  Data.S "231 Logo Drive, Mouse House, Downtown"
EndDataSection
Update 1: I had to retain the NSImages AscendingArrow and DescendingArrow in order to work in MountainLion. Thank you for your invaluable hint, Wilbert. And I implemented a workaround to circumvent PureBasic's Pseudotype bug in order to work in Unicode mode.

Update 2: For calculating the required size of the 2 buffers *MethodNameBuffer and *TypesBuffer I have changed Len() to StringByteLength() because in Unicode mode the buffers had the double size than would have been required...
Last edited by Shardik on Thu Apr 25, 2013 8:03 pm, edited 3 times in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Shardik wrote:Currently my code requires you to store the ListIcon contents into the linked list Table() and to do the sorting by yourself in the procedure SortListIcon().
I think you would have to do it more or less that way.
The PureBasic gadget provides the data source for the table. If the data source doesn't have a sorting routine built in, it won't work.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 456
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

Thank you Shardik for your quick answer.... Though I'm afraid it doesn't work :
I've got an "invalid access memory" error when I click on a column header....
I'm not sure that the error line number is very useful as it's not the same on PureBasic 5.11 64, PureBasic 5.11 32, PureBasic 5.10 64... (always without Unicode)
Anyway, thank you for giving a try...
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 15.4.1 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Mindphazer wrote:Thank you Shardik for your quick answer.... Though I'm afraid it doesn't work :
I've got an "invalid access memory" error when I click on a column header....
Sorry for that inconveniance. I tested my code example on MacOS X 10.6.8 (Snow Leopard) with 32 bit (in ASCII and Unicode mode) and 64 bit (ASCII mode, for Unicode see the remark in my previous posting) and it worked like a charme.

Oh, I see: I used Procedure instead of ProcedureC in the callback. This works in Snow Leopard but most likely produces an "Invalid memory access" in Lion and Mountain Lion. I have corrected this problem in my code example. Please give it a try again... :wink:
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 456
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

Well Shardik, I'm terribly sorry but it still doesn't work.
I'm still having an "illegal access memory", whatever version of PureBasic I'm using (5.10 x64 or x86, 5.11 x64 or x86, without Unicode)
The only difference is that the error is always spotted on the same line : 122

And, I should have said it : my OS is 10.8.3
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 15.4.1 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Wilbert has found the error and informed me via PM. In Lion and Mountain Lion the NSImages AscendingArrow and DescendingArrow have to be retained - otherwise they are autoreleased... :evil: I wouldn't have found that solution on my own or would have had to search for Wilbert's fix for a long time: Thank you very much, Wilbert, you are a true genius!

Furthermore I have implemented the above described workaround from my first posting to circumvent PureBasic's Pseudotype bug, so that the above example code now works in Mountain Lion with 32 and 64 bit and in ASCII and unicode mode without change. I have modified the example code of my first posting.
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 456
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

Shardik, you are officially granted to an official "cocoa master", along with Wilbert !

Thank you to both of you two
Your example works perfectly, I can now implement it.

I wish you a very good end of week
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 15.4.1 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

A little explanation about the autorelease issue ...
Objects that are created using alloc and init are retained and have to be released manually if you don't need them anymore.
Objects that are created by using another class method like for example NSImage imageNamed: or NSNumber numberWithInt: are autoreleased.
PureBasic drains the autorelease pool once every event loop ( Wait/WindowEvent() ). So if you need those autorelease objects to be around longer, you have to retain them manually.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 456
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

I'm -again- asking for help.
Does anyone know how to set color to a specify cell (or line) in a ListIconGadget ?
The SetGadgetItemColor() function is not implemented on OSX, do you think it can be achieved via Cocoa ?

Thanks a lot
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 15.4.1 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by J. Baker »

Add the "plus sign" to a menu item.

Code: Select all

PS = MenuItem( 1, "Plus Sign" + Chr(9) + "Shift")
CocoaMessage(0, PS, "setKeyEquivalent:$", @"+")
CocoaMessage(0, PS, "setKeyEquivalentModifierMask:", 1 << 17)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
jamirokwai
Enthusiast
Enthusiast
Posts: 796
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by jamirokwai »

Hi there,

quickly change the URL of the WebGadget:

Code: Select all

If OpenWindow(0, 270, 100, 600, 300, "WebGadget")
  WebGadget(0, 10, 10, 580, 280, "")
  CocoaMessage(0, GadgetID(0), "setMainFrameURL:$", @"http://www.purebasic.fr/")

  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Regards,
JamiroKwai
jamirokwai
Enthusiast
Enthusiast
Posts: 796
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by jamirokwai »

Letting OS X fade the window... Start-value is current value.

Code: Select all

OpenWindow(0,100,100,400,400,"Fader")
fadeTo.CGFloat = 0.8
CocoaMessage(0, CocoaMessage(0, WindowID(0), "animator"), "setAlphaValue:@", @fadeTo)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Regards,
JamiroKwai
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

To set the url of a WebGadget you can simply use SetGadgetText; there's no need to send a cocoa message.

The window fade is nice. :)
Is there any reference in the Apple docs about this ? I can't find it anywhere.
If it's not, it still is a nice code example but using private api can get an app rejected from the app store.
So that's why I'm just asking :wink:
Windows (x64)
Raspberry Pi OS (Arm64)
jamirokwai
Enthusiast
Enthusiast
Posts: 796
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by jamirokwai »

wilbert wrote:To set the url of a WebGadget you can simply use SetGadgetText; there's no need to send a cocoa message.
Yep. Just for fun... Just learning Cocoa in PB :wink:
wilbert wrote:The window fade is nice. :)
Is there any reference in the Apple docs about this ? I can't find it anywhere.
If it's not, it still is a nice code example but using private api can get an app rejected from the app store.
So that's why I'm just asking :wink:
See here: http://developer.apple.com/library/mac/ ... index.html
I assume, it's non-private :-)
Last edited by jamirokwai on Mon Apr 29, 2013 5:34 pm, edited 1 time in total.
Regards,
JamiroKwai
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

jamirokwai wrote:See here: http://developer.apple.com/library/mac/ ... index.html
I assume, it's non-private :-)
Thanks. I was looking at the NSWindow reference. I added your fade example to the list on the first post.
Cocoa is fun :idea:
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply