Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Sat Jan 13, 2024 12:03 pm
Not with DarkMode.
Please not code questions here
Please not code questions here
http://www.purebasic.com
https://www.purebasic.fr/english/
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
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: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.
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
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