[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
User avatar
mk-soft
Always Here
Always Here
Posts: 6202
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mk-soft »

Not with DarkMode.

Please not code questions here
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
DannyWeijermans
User
User
Posts: 26
Joined: Thu Aug 25, 2022 10:10 pm
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by DannyWeijermans »

(checked again, thought I was wrong, but I think I'm right ;)

Dear Shardik,
Could you verify this:
I'm using your great code
to update my code from PB5 to PB6 and to newest OSX.
I think some CocoaMessage uses a 0 instead of the right ListIconGadgetID.
In your example, ListIconGadgetID = 0,
but if I change it to something else,
the ListIconGadget stops displaying.
Could you verify this?
Thanks in advance!
Regards,
Danny Weijermans - The Netherlands
Shardik wrote: Tue Feb 14, 2023 12:33 pm I have modified my example to justify text in the columns of the ListIconGadget to work both in PB 5.73 and earlier and in PB 6.00 and newer. This has become necessary because Fred has changed internals of the cells in ListIconGadgets. In PB 6.0 Fred implemented the new PBIconTextCell which enables the display of both an icon and text in a single cell. But therefore unfortunately the old modifications don't work anymore.

This new example uses the old routines in PB 5.73 and earlier and a callback in PB 6.00 and newer. Furthermore the example was extended to change the justification of header cells (which didn't change in PB 6.00) separately from the column cells. The following example was successfully tested on these MacOS versions:
  • 'Big Sur' 11.7.3 with PB 5.73 and PB 6.00 (Asm and C backend)
  • 'Monterey' 12.6.3 with PB 5.73 and PB 6.00 (Asm and C backend)
  • 'Ventura' 13.2 and 13.2.1 with PB 5.73 and PB 6.00 (Asm and C backend)

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_Version >= 600
  Structure ListIconColumnFormatEntry
    ListIconID.I
    Array ColumnFormat.I(0) 
  EndStructure

  Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
    "NSApplication sharedApplication"), "delegate")
  Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")

  NewList ListIconColumnFormat.ListIconColumnFormatEntry()

  ProcedureC WillDisplayCell(Object.I, Selector.I, TableView.I, Cell.I,
    *Column, Row.I)
    Shared ListIconColumnFormat.ListIconColumnFormatEntry()

    Protected Column.I
    Protected CellText.S
    Protected ListIconID.I
  
    ListIconID = CocoaMessage(0, TableView, "tag")

    If ListSize(ListIconColumnFormat()) > 0
      ForEach ListIconColumnFormat()
        If ListIconColumnFormat()\ListIconID = ListIconID
          Column = CocoaMessage(0, CocoaMessage(0, TableView, "tableColumns"),
            "indexOfObject:", *Column)
          CocoaMessage(0, CocoaMessage(0, *Column, "dataCell"),
            "setAlignment:", ListIconColumnFormat()\ColumnFormat(Column))
          Break
        EndIf
      Next
    EndIf

    CocoaMessage(0, Cell, "_setVerticallyCentered:", #YES)
    CellText = GetGadgetItemText(ListIconID, Row, Column)
    CocoaMessage(0, Cell, "setStringValue:$", @CellText)
  EndProcedure
CompilerEndIf

Procedure SetListIconColumnJustification(ListIconID.I, ColumnIndex.I,
  Alignment.I, IsHeaderCell.I = #False)

  Protected ColumnHeaderCell.I
  Protected ColumnObject.I
  Protected ColumnObjectArray.I
  Protected ListIconIDFound.I

  CocoaMessage(@ColumnObjectArray, GadgetID(ListIconID), "tableColumns")
  CocoaMessage(@ColumnObject, ColumnObjectArray,
    "objectAtIndex:", ColumnIndex)

  If IsHeaderCell
    ; ----- Justify text of column header
    CocoaMessage(@ColumnHeaderCell, ColumnObject, "headerCell")
    CocoaMessage(0, ColumnHeaderCell, "setAlignment:", Alignment)
  Else
    CompilerIf #PB_Compiler_Version >= 600
      Shared AppDelegate.I
      Shared ListIconColumnFormat.ListIconColumnFormatEntry()

      If ListSize(ListIconColumnFormat()) = 0
        CocoaMessage(0, GadgetID(ListIconID), "setDelegate:", AppDelegate)
        AddElement(ListIconColumnFormat())
        ListIconColumnFormat()\ListIconID = ListIconID
        ReDim ListIconColumnFormat()\ColumnFormat(GetGadgetAttribute(0 +
          ListIconID, #PB_ListIcon_ColumnCount) - 1)
        ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
      Else
        ForEach ListIconColumnFormat()
          If ListIconColumnFormat()\ListIconID = ListIconID
            ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
            ListIconIDFound = #True
            Break
          EndIf
        Next

        If ListIconIDFound = #False
          CocoaMessage(0, GadgetID(ListIconID), "setDelegate:", AppDelegate)
          AddElement(ListIconColumnFormat())
          ListIconColumnFormat()\ListIconID = ListIconID
          ReDim ListIconColumnFormat()\ColumnFormat(GetGadgetAttribute(0 +
            ListIconID, #PB_ListIcon_ColumnCount) - 1)
          ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
        EndIf
      EndIf
    CompilerElse
      CocoaMessage(0, CocoaMessage(0, ColumnObject, "dataCell"),
        "setAlignment:", Alignment)
    CompilerEndIf
  EndIf

  ; ----- Redraw ListIcon contents to see change
  CocoaMessage(0, GadgetID(ListIconID), "reloadData")
EndProcedure

Define OptionGadgetID.I

OpenWindow(0, 200, 100, 445, 220, "Change justification in 2nd column")
ListIconGadget(0, 5, 5, 435, 90, "Name", 95)
AddGadgetColumn(0, 1, "Address", 300)
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")

FrameGadget(1, 10, 95, WindowWidth(0) - 20, 50,
  "Justification of 2nd header column:")
OptionGadget(2, 20, 115, 70, 20, "Left")
OptionGadget(3, 330, 115, 70, 20, "Right")
OptionGadget(4, 180, 115, 70, 20, "Center")
SetGadgetState(2, #True)

FrameGadget(5, 10, 160, WindowWidth(0) - 20, 50,
  "Justification of 2nd column:")
OptionGadget(6, 20, 180, 70, 20, "Left")
OptionGadget(7, 330, 180, 70, 20, "Right")
OptionGadget(8, 180, 180, 70, 20, "Center")
SetGadgetState(6, #True)

CompilerIf #PB_Compiler_Version >= 600
  class_addMethod_(DelegateClass,
    sel_registerName_("tableView:willDisplayCell:forTableColumn:row:"),
    @WillDisplayCell(), "v@:@@@@")
CompilerEndIf

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      OptionGadgetID = EventGadget()

      Select OptionGadgetID
        Case 2 To 4
          SetListIconColumnJustification(0, 1, OptionGadgetID - 2, #True)
        Case 6 To 8
          SetListIconColumnJustification(0, 1, OptionGadgetID - 6)
      EndSelect
  EndSelect
ForEver
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 »

DannyWeijermans wrote: Thu Feb 15, 2024 9:51 pm Could you verify this:
I'm using your great code
to update my code from PB5 to PB6 and to newest OSX.
I think some CocoaMessage uses a 0 instead of the right ListIconGadgetID.
In your example, ListIconGadgetID = 0,
but if I change it to something else,
the ListIconGadget stops displaying.
You have to change ID 0 of the ListIconGadget at several different places. The IDs 1 to 8 are already in use for other gadgets. So you have to take an ID of 9 or above for the ListIconGadget in my code. I have modified my example to use the constant #ListIcon and have replaced all occurrences of 0 by #ListIcon:

Code: Select all

EnableExplicit

#ListIcon = 9

CompilerIf #PB_Compiler_Version >= 600
  Structure ListIconColumnFormatEntry
    ListIconID.I
    Array ColumnFormat.I(0) 
  EndStructure

  Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
    "NSApplication sharedApplication"), "delegate")
  Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")

  NewList ListIconColumnFormat.ListIconColumnFormatEntry()

  ProcedureC WillDisplayCell(Object.I, Selector.I, TableView.I, Cell.I,
    *Column, Row.I)
    Shared ListIconColumnFormat.ListIconColumnFormatEntry()

    Protected Column.I
    Protected CellText.S
    Protected ListIconID.I
  
    ListIconID = CocoaMessage(0, TableView, "tag")

    If ListSize(ListIconColumnFormat()) > 0
      ForEach ListIconColumnFormat()
        If ListIconColumnFormat()\ListIconID = ListIconID
          Column = CocoaMessage(0, CocoaMessage(0, TableView, "tableColumns"),
            "indexOfObject:", *Column)
          CocoaMessage(0, CocoaMessage(0, *Column, "dataCell"),
            "setAlignment:", ListIconColumnFormat()\ColumnFormat(Column))
          Break
        EndIf
      Next
    EndIf

    CocoaMessage(0, Cell, "_setVerticallyCentered:", #YES)
    CellText = GetGadgetItemText(ListIconID, Row, Column)
    CocoaMessage(0, Cell, "setStringValue:$", @CellText)
  EndProcedure
CompilerEndIf

Procedure SetListIconColumnJustification(ListIconID.I, ColumnIndex.I,
  Alignment.I, IsHeaderCell.I = #False)

  Protected ColumnHeaderCell.I
  Protected ColumnObject.I
  Protected ColumnObjectArray.I
  Protected ListIconIDFound.I

  CocoaMessage(@ColumnObjectArray, GadgetID(ListIconID), "tableColumns")
  CocoaMessage(@ColumnObject, ColumnObjectArray,
    "objectAtIndex:", ColumnIndex)

  If IsHeaderCell
    ; ----- Justify text of column header
    CocoaMessage(@ColumnHeaderCell, ColumnObject, "headerCell")
    CocoaMessage(0, ColumnHeaderCell, "setAlignment:", Alignment)
  Else
    CompilerIf #PB_Compiler_Version >= 600
      Shared AppDelegate.I
      Shared ListIconColumnFormat.ListIconColumnFormatEntry()

      If ListSize(ListIconColumnFormat()) = 0
        CocoaMessage(0, GadgetID(ListIconID), "setDelegate:", AppDelegate)
        AddElement(ListIconColumnFormat())
        ListIconColumnFormat()\ListIconID = ListIconID
        ReDim ListIconColumnFormat()\ColumnFormat(GetGadgetAttribute(0 +
          ListIconID, #PB_ListIcon_ColumnCount) - 1)
        ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
      Else
        ForEach ListIconColumnFormat()
          If ListIconColumnFormat()\ListIconID = ListIconID
            ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
            ListIconIDFound = #True
            Break
          EndIf
        Next

        If ListIconIDFound = #False
          CocoaMessage(0, GadgetID(ListIconID), "setDelegate:", AppDelegate)
          AddElement(ListIconColumnFormat())
          ListIconColumnFormat()\ListIconID = ListIconID
          ReDim ListIconColumnFormat()\ColumnFormat(GetGadgetAttribute(0 +
            ListIconID, #PB_ListIcon_ColumnCount) - 1)
          ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
        EndIf
      EndIf
    CompilerElse
      CocoaMessage(0, CocoaMessage(0, ColumnObject, "dataCell"),
        "setAlignment:", Alignment)
    CompilerEndIf
  EndIf

  ; ----- Redraw ListIcon contents to see change
  CocoaMessage(0, GadgetID(ListIconID), "reloadData")
EndProcedure

Define OptionGadgetID.I

OpenWindow(0, 200, 100, 445, 220, "Change justification in 2nd column")
ListIconGadget(#ListIcon, 5, 5, 435, 90, "Name", 95)
AddGadgetColumn(#ListIcon, 1, "Address", 300)
AddGadgetItem(#ListIcon, -1, "Harry Rannit" + #LF$ +
  "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(#ListIcon, -1, "Ginger Brokeit" + #LF$ +
  "130 PureBasic Road, BigTown, CodeCity")

FrameGadget(1, 10, 95, WindowWidth(0) - 20, 50,
  "Justification of 2nd header column:")
OptionGadget(2, 20, 115, 70, 20, "Left")
OptionGadget(3, 330, 115, 70, 20, "Right")
OptionGadget(4, 180, 115, 70, 20, "Center")
SetGadgetState(2, #True)

FrameGadget(5, 10, 160, WindowWidth(0) - 20, 50,
  "Justification of 2nd column:")
OptionGadget(6, 20, 180, 70, 20, "Left")
OptionGadget(7, 330, 180, 70, 20, "Right")
OptionGadget(8, 180, 180, 70, 20, "Center")
SetGadgetState(6, #True)

CompilerIf #PB_Compiler_Version >= 600
  class_addMethod_(DelegateClass,
    sel_registerName_("tableView:willDisplayCell:forTableColumn:row:"),
    @WillDisplayCell(), "v@:@@@@")
CompilerEndIf

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      OptionGadgetID = EventGadget()

      Select OptionGadgetID
        Case 2 To 4
          SetListIconColumnJustification(#ListIcon, 1, OptionGadgetID - 2, #True)
        Case 6 To 8
          SetListIconColumnJustification(#ListIcon, 1, OptionGadgetID - 6)
      EndSelect
  EndSelect
ForEver

An alternative would be to download the current Beta 6 version of PB 6.10. Since PB 6.10 it has become much easier to justify text in the columns of a ListIconGadget because of the new parameter #PB_ListIcon_ColumnAlignment in SetGadgetItemAttribute(). You may try the following short example which right-aligns the text in the 2nd column of a ListIconGadget:

Code: Select all

OpenWindow(0, 200, 100, 410, 130, "Column justification")
ListIconGadget(0, 10, 10, 390, 85, "Name", 100)
AddGadgetColumn(0, 1, "Address", 280)
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")
ButtonGadget(1, 120, 100, 170, 25, "Right-align 2nd column")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        SetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnAlignment,
          #PB_ListIcon_Right, 1)
      EndIf
  EndSelect
ForEver
User avatar
DannyWeijermans
User
User
Posts: 26
Joined: Thu Aug 25, 2022 10:10 pm
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by DannyWeijermans »

Wow! Many thanks, Shardik!
I'm already in Beta 6 version of PB 6.10,
so your 2nd option is WAY BETTER and CLEANER!
Thanks so much!
Also for clearing up the older code (what 0 means..)
Regards,
Danny Weijermans - The Netherlands
Post Reply