Page 1 of 2

Any way to add separators to ListIconGadget/NSTableView?

Posted: Mon Apr 19, 2021 6:02 pm
by deseven
Anyone got any ideas how to add groups/separators to NSTableView?

Something like this:
Image

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Mon Apr 19, 2021 7:01 pm
by Shardik
deseven wrote: Mon Apr 19, 2021 6:02 pm Anyone got any ideas how to add groups/separators to NSTableView?
A simple example:

Code: Select all

EnableExplicit

ProcedureC IsGroupRow(Object.I, Selector.I, TableView.I, Row.I)
  Protected IsGroupRow.I

  Select Row
    Case 0, 3
      IsGroupRow = #True
    Default
      IsGroupRow = #False
  EndSelect

  ProcedureReturn IsGroupRow
EndProcedure

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define Selector.I = sel_registerName_("tableView:isGroupRow:")

OpenWindow(0, 200, 100, 612, 178, "Pinball Highscores")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
  "Pinball/table name", 190, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Players total", 90)
AddGadgetColumn(0, 2, "Rank", 50)
AddGadgetColumn(0, 3, "Shardik", 90)
AddGadgetColumn(0, 4, "Lady Bug", 90)
AddGadgetItem(0, 0, "Atomic Pinball Collection")
AddGadgetItem(0, 1, "Rob-O-Bot High Score" + #LF$ + "53.449" + #LF$ +
  "330" + #LF$ + "4.017.940" + #LF$ + "619.010")
AddGadgetItem(0, 2, "Masks of Glory High Score" + #LF$ + "118.565" + #LF$ +
  "1.055" + #LF$ + "11.316.790" + #LF$ + "1.230.630")
AddGadgetItem(0, 3, "Pure Pinball")
AddGadgetItem(0, 4, "Pure Pinball" + #LF$ + "121.824" + #LF$ +
  "659" + #LF$ + "282.843.920" + #LF$ + "14.589.340")

class_addMethod_(DelegateClass, Selector, @IsGroupRow(), "v@:@@")
CocoaMessage(0, GadgetID(0), "setDelegate:", AppDelegate)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
If you want to colorize the text or background color of the group names, the code will become more complicated because you also need additional callbacks for cell display and color.

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Mon Apr 19, 2021 8:13 pm
by deseven
Thank you, Shardik!

I looked at groups before, but they can't really achieve this exact behavior, as you can see on the screenshot the separator text isn't limited to one single column, it's like one big cell from the beginning to the end. Unless i'm missing something...

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Tue Apr 20, 2021 11:04 pm
by mk-soft
Small extension to get the gadget number in the callback

Code: Select all

EnableExplicit

ProcedureC IsGroupRow(Object.I, Selector.I, TableView.I, Row.I)
  Protected Gadget, IsGroupRow.I
  
  Gadget = CocoaMessage(0, TableView, "tag")
  
  Select Gadget
    Case 1
      IsGroupRow = GetGadgetItemData(Gadget, Row)
      
  EndSelect
  
  ProcedureReturn IsGroupRow
EndProcedure

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define Selector.I = sel_registerName_("tableView:isGroupRow:")

OpenWindow(0, 200, 100, 612, 178, "Pinball Highscores")
ListIconGadget(1, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
  "Pinball/table name", 190, #PB_ListIcon_GridLines)
AddGadgetColumn(1, 1, "Players total", 90)
AddGadgetColumn(1, 2, "Rank", 50)
AddGadgetColumn(1, 3, "Shardik", 90)
AddGadgetColumn(1, 4, "Lady Bug", 90)
AddGadgetItem(1, 0, "Atomic Pinball Collection")
AddGadgetItem(1, 1, "Rob-O-Bot High Score" + #LF$ + "53.449" + #LF$ +
  "330" + #LF$ + "4.017.940" + #LF$ + "619.010")
AddGadgetItem(1, 2, "Masks of Glory High Score" + #LF$ + "118.565" + #LF$ +
  "1.055" + #LF$ + "11.316.790" + #LF$ + "1.230.630")
AddGadgetItem(1, 3, "Pure Pinball")
AddGadgetItem(1, 4, "Pure Pinball" + #LF$ + "121.824" + #LF$ +
  "659" + #LF$ + "282.843.920" + #LF$ + "14.589.340")

; Define group rows
SetGadgetItemData(1, 0, #True)
SetGadgetItemData(1, 3, #True)

class_addMethod_(DelegateClass, Selector, @IsGroupRow(), "v@:@@")
CocoaMessage(0, GadgetID(1), "setDelegate:", AppDelegate)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Wed Apr 21, 2021 9:56 am
by deseven
Well, i sort of achieved the look i wanted, that will do for now. Thank you guys!

Image

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Wed Apr 21, 2021 9:10 pm
by Shardik
deseven wrote: Wed Apr 21, 2021 9:56 am Well, i sort of achieved the look i wanted, that will do for now.
Sorry, too late! But perhaps you may still take a look into my following example which tries to reproduce the screenshot from your first posting. I have tested it on MacOS 11.2.3 'Big Sur' (dark theme) with PB 5.73.

Image

Code: Select all

EnableExplicit

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

ProcedureC WillDisplayCell(Object.I, Selector.I, TableView.I, Cell.I,
  *Column, Row.I)
  Protected Column.I
  Protected CellFrame.NSRect
  Protected GadgetID.I
  Protected LineFrame.NSRect
  Protected RowFrame.NSRect
  Protected TextSize.NSSize

  GadgetID = CocoaMessage(0, TableView, "tag")

  If GetGadgetItemData(GadgetID, Row) = #True
    CocoaMessage(0, Cell, "_setVerticallyCentered:", #YES)
    Column = CocoaMessage(0, CocoaMessage(0, TableView, "tableColumns"),
      "indexOfObject:", *Column)

    If Column = 0
      CocoaMessage(@CellFrame, TableView,
        "frameOfCellAtColumn:", Column,
        "row:", Row)
      CocoaMessage(@TextSize, Cell, "cellSize")
      CocoaMessage(@RowFrame, GadgetID(GadgetID), "rectOfRow:", Row)

      ; ----- Draw line from end of text in column 0 to end of row

      LineFrame\origin\x = CellFrame\origin\x + TextSize\width + 10
      LineFrame\origin\y =  CellFrame\origin\y + CellFrame\size\height / 2 + 1
      LineFrame\size\height = 1
      LineFrame\size\width = RowFrame\size\width - TextSize\width - 20
      CocoaMessage(0, CocoaMessage(0, 0, "NSColor textColor"), "setFill")
      CocoaMessage(0, 0, "NSBezierPath fillRect:@", @LineFrame)
      CocoaMessage(0, Cell,
        "drawInteriorWithFrame:@", @LineFrame,
        "inView:", TableView)

      CocoaMessage(0, Cell,
        "setTitle:", CocoaMessage(0, Cell, "title"))
      CocoaMessage(0, Cell, 
        "setTextColor:", CocoaMessage(0, 0, "NSColor textColor"))
    EndIf
  Else
    CocoaMessage(0, Cell, 
      "setTextColor:", CocoaMessage(0, 0, "NSColor textColor"))
  EndIf
EndProcedure

ProcedureC IsGroupRowCallback(Object.I, Selector.I, TableView.I, Row.I)
  Protected IsGroupRow.I

  IsGroupRow = GetGadgetItemData(0, Row)

  ProcedureReturn IsGroupRow
EndProcedure

OpenWindow(0, 200, 100, 202, 250, "Group demo")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
  "Fruit", 90)
AddGadgetColumn(0, 1, "Euro/kg", 60)
AddGadgetItem(0, 0, "Stone fruits")
SetGadgetItemData(0, 0, #True)
AddGadgetItem(0, 1, "Apricots" + #LF$ + "2,99")
AddGadgetItem(0, 2, "Peaches" + #LF$ + "2,69")
AddGadgetItem(0, 3, "Plums" + #LF$ + "1,60")
AddGadgetItem(0, 4, "Berries")
SetGadgetItemData(0, 4, #True)
AddGadgetItem(0, 5, "Grapes" + #LF$ + "1,78")
AddGadgetItem(0, 6, "Raspberries" + #LF$ + "2,99")
AddGadgetItem(0, 7, "Strawberries" + #LF$ + "3,56")
CocoaMessage(0, GadgetID(0), "setUsesAlternatingRowBackgroundColors:", #YES)

class_addMethod_(DelegateClass,
  sel_registerName_("tableView:isGroupRow:"),
  @IsGroupRowCallback(), "v@:@@")
class_addMethod_(DelegateClass,
  sel_registerName_("tableView:willDisplayCell:forTableColumn:row:"),
  @WillDisplayCell(), "v@:@@@@")
CocoaMessage(0, GadgetID(0), "setDelegate:", AppDelegate)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Update 1: I have added the detection of the GadgetID with tag as proposed by mk-soft to allow using multiple ListIconGadgets. Thank you for your proposition, mk-soft!
Update 2: I have changed the 3 occurrences of whiteColor to textColor so that the text color is automatically set correctly in dark and light themes. Thank you again, mk-soft!

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Wed Apr 21, 2021 11:14 pm
by deseven
Nice example, thank you!

I will surely integrate it later, but anyway every piece of information is great, i believe this can be useful for others too.

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Thu Apr 22, 2021 7:49 am
by mk-soft
Does not work under macOS High Sierra!?

Get the gadget number from the "tag", then it will also work with several TableViews. Then you only need to execute "setDelegate".

Code: Select all

Gadget = CocoaMessage(0, TableView, "tag")

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Thu Apr 22, 2021 6:14 pm
by Shardik
mk-soft wrote: Thu Apr 22, 2021 7:49 am Does not work under macOS High Sierra!?
Shardik wrote: Wed Apr 21, 2021 9:10 pm I have tested it on MacOS 11.2.3 'Big Sur' (dark theme) with PB 5.73.
I stated that I tested the example with the dark theme on Big Sur. To work with a light theme, you have to change the 3 occurrences of whiteColor to blackColor and you will obtain the following output on High Sierra:
Image
mk-soft wrote: Thu Apr 22, 2021 7:49 am Get the gadget number from the "tag", then it will also work with several TableViews. Then you only need to execute "setDelegate".

Code: Select all

Gadget = CocoaMessage(0, TableView, "tag")
You are right about using tag to obtain the GadgetID to handle multiple ListIconGadgets. I have added it to my example above. But I don't understand
mk-soft wrote: Thu Apr 22, 2021 7:49 am Then you only need to execute "setDelegate".
Without the two method definitions before setDelegate my code won't work...

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Thu Apr 22, 2021 7:02 pm
by mk-soft
The added methods for the tableView (class_addMethod) are for all tableViews in the application.

To get the right colour you can also use textColor. This way it is always correct for light or dark mode.

Code: Select all

CocoaMessage(0, 0, "NSColor textColor")
P.S. Perhaps you can use this:
Link: MacOS SetGadgetCallback and SetGadgetNotification (Base by Shardik)

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Wed May 11, 2022 9:08 pm
by deseven
For some bizarre reason none of this works in the latest beta with C backend, all fields become empty (only visually, though).

I've checked the docs for tableView:isGroupRow: to see if something has changed, but there were no changes for a looooong time. Anyone have any idea what's up with that?

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Wed May 11, 2022 10:54 pm
by mk-soft

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Thu May 12, 2022 3:47 pm
by deseven
mk-soft wrote: Wed May 11, 2022 10:54 pm Same as here: https://www.purebasic.fr/english/viewtopic.php?t=79115
Oh damn, this is huge. Yeah, now I see that everything related to ListIconGadget customization stopped working, including pretty minor things like text justification. I have no clue how to move on from that, hopefully someone will crack it soon enough and figure out some basic approach that can be adopted to everything else.

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Thu May 12, 2022 7:41 pm
by deseven
Alright, here's the fixed group row example (I looked at what Shardik did to fix SetGadgetItemColor here):

Code: Select all

EnableExplicit

ProcedureC IsGroupRow(Object.I, Selector.I, TableView.I, Row.I)
  Protected Gadget, IsGroupRow.I
  
  Gadget = CocoaMessage(0, TableView, "tag")
  
  Select Gadget
    Case 1
      IsGroupRow = GetGadgetItemData(Gadget, Row)
      
  EndSelect
  
  ProcedureReturn IsGroupRow
EndProcedure

ProcedureC CellDisplayCallback(Object.I, Selector.I, TableView.I, Cell.I, *Column, Row.I)
  Protected Column.i = CocoaMessage(0, CocoaMessage(0, TableView, "tableColumns"), "indexOfObject:", *Column)
  Protected CellText.s = GetGadgetItemText(CocoaMessage(0, TableView, "tag"), Row, Column)
  CocoaMessage(0, Cell, "setStringValue:$", @CellText)
EndProcedure

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define Selector.I = sel_registerName_("tableView:isGroupRow:")
class_addMethod_(DelegateClass, Selector, @IsGroupRow(), "v@:@@")
Selector = sel_registerName_("tableView:willDisplayCell:forTableColumn:row:")
class_addMethod_(DelegateClass, Selector, @CellDisplayCallback(), "v@:@@@@")


OpenWindow(0, 200, 100, 612, 178, "Pinball Highscores")
ListIconGadget(1, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
  "Pinball/table name", 190, #PB_ListIcon_GridLines)
AddGadgetColumn(1, 1, "Players total", 90)
AddGadgetColumn(1, 2, "Rank", 50)
AddGadgetColumn(1, 3, "Shardik", 90)
AddGadgetColumn(1, 4, "Lady Bug", 90)
AddGadgetItem(1, 0, "Atomic Pinball Collection")
AddGadgetItem(1, 1, "Rob-O-Bot High Score" + #LF$ + "53.449" + #LF$ +
  "330" + #LF$ + "4.017.940" + #LF$ + "619.010")
AddGadgetItem(1, 2, "Masks of Glory High Score" + #LF$ + "118.565" + #LF$ +
  "1.055" + #LF$ + "11.316.790" + #LF$ + "1.230.630")
AddGadgetItem(1, 3, "Pure Pinball")
AddGadgetItem(1, 4, "Pure Pinball" + #LF$ + "121.824" + #LF$ +
  "659" + #LF$ + "282.843.920" + #LF$ + "14.589.340")

; Define group rows
SetGadgetItemData(1, 0, #True)
SetGadgetItemData(1, 3, #True)

CocoaMessage(0, GadgetID(1), "setDelegate:", AppDelegate)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
However, group rows now have no visible selection, no borders or bold font. Do we need to set it all manually now? I think I can manage to make the font bold and add borders, but what about the selection?

Re: Any way to add separators to ListIconGadget/NSTableView?

Posted: Fri May 13, 2022 12:26 pm
by deseven
Can anyone tell me how do I draw text manually with the defined font in the cell frame? Instead of a simple rectangle, for example, which can be drawn with NSBezierPath fillRect.