Any way to add separators to ListIconGadget/NSTableView?

Mac OSX specific forum
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

Any way to add separators to ListIconGadget/NSTableView?

Post by deseven »

Anyone got any ideas how to add groups/separators to NSTableView?

Something like this:
Image
User avatar
Shardik
Addict
Addict
Posts: 1984
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

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

Post 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.
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

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

Post 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...
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

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

Post 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
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
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

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

Post by deseven »

Well, i sort of achieved the look i wanted, that will do for now. Thank you guys!

Image
User avatar
Shardik
Addict
Addict
Posts: 1984
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

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

Post 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!
Last edited by Shardik on Sat Apr 24, 2021 4:29 pm, edited 3 times in total.
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

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

Post 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.
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

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

Post 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")
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
Shardik
Addict
Addict
Posts: 1984
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

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

Post 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...
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

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

Post 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)
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
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

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

Post 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?
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

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

Post by mk-soft »

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
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

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

Post 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.
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

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

Post 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?
User avatar
deseven
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Jan 12, 2011 3:48 pm
Location: Serbia
Contact:

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

Post 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.
Post Reply