TreeGadget subnodes with indented checkboxes

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

TreeGadget subnodes with indented checkboxes

Post by Shardik »

The TreeGadget has the same problem with checkboxes as with images: they are always displayed at the left side of the gadget and are not indented with the subnode text:

Image

This is the output from my workaround code below with indented checkboxes. As a further goodie it is possible to create nodes with and without checkboxes:

Image

My workaround works as follows:

1. A callback is defined in the procedure SetGadgetCallback(). In this procedure the callback CellDisplayCallback() is setup for the TreeGadget as a delegate for the method "outlineView:dataCellForTableColumn:item:". This method is called for every display of a tree node and is now routed to CellDisplayCallback().

2. For each node that should display a checkbox, the procedure AddCheckBoxToRow() has to be called. In this procedure a NSButtonCell object is allocated for the specified row/node. It contains a checkbox and the text for the node. Each NSButtonCell object is stored in the array ButtonCell().

3. Every time when a tree node has to be displayed, the callback CellDisplayCallback() is called. For each tree node containing a checkbox, the ButtonCell object from the array ButtonCell() is returned containing the checkbox and the text for the node to be displayed. An array element for a node without a checkbox contains 0 and so 0 is returned by the callback, so in this case no checkbox is displayed.

Code: Select all

EnableExplicit

#NSSwitchButton = 3

ImportC ""
  sel_registerName(MethodName.P-ASCII)
  class_addMethod(Class.I, Selector.I, Implementation.I, Types.P-ASCII)
EndImport

Dim ButtonCell.I(0)
Define i.I

ProcedureC CellDisplayCallback(Object.I, Selector.I, OutlineView.I,
  TableColumn.I, Item.I)
  Shared ButtonCell.I()
  Protected Row.I = CocoaMessage(0, GadgetID(0), "rowForItem:", Item)

  If ButtonCell(Row) <> 0
    ProcedureReturn ButtonCell(Row)
  EndIf
EndProcedure

Procedure SetGadgetCallback(GadgetID.I, GadgetCallback.I, Method.S)
  Protected AppDelegate.I
  Protected DelegateClass.I
  Protected PlaceholderList.S

  PlaceholderList = LSet("@:", CountString(Method, ":"), "@")
  AppDelegate = CocoaMessage(0, CocoaMessage(0, 0,
    "NSApplication sharedApplication"), "delegate")
  DelegateClass = CocoaMessage(0, AppDelegate, "class")
  class_addMethod(DelegateClass, sel_registerName(Method), GadgetCallback,
    PlaceholderList)
  CocoaMessage(0, GadgetID(GadgetID), "setDelegate:", AppDelegate)
EndProcedure

Procedure AddCheckBoxToTreeRow(Row.I)
  Shared ButtonCell.I()
  Protected ItemText.S
  Protected TableColumn.I

  TableColumn = CocoaMessage(0, CocoaMessage(0, GadgetID(0), "tableColumns"),
    "objectAtIndex:", 0)
  ButtonCell(Row) = CocoaMessage(0, 0, "NSButtonCell new")
  CocoaMessage(0, ButtonCell(Row), "setButtonType:", #NSSwitchButton)
  ItemText = GetGadgetItemText(0, Row)
  CocoaMessage(0, ButtonCell(Row), "setTitle:$", @ItemText)
EndProcedure

OpenWindow(0, 270, 100, 160, 100, "TreeGadget", #PB_Tree_CheckBoxes)
TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)

AddGadgetItem (0, -1, "Parent")

For i = 1 To 3
  AddGadgetItem (0, -1, "Child " + Str(i), 0, 1)
Next i

SetGadgetItemState(0, 0, #PB_Tree_Expanded)

; ----- Setup callback for TreeGadget
SetGadgetCallback(0, @CellDisplayCallback(),
  "outlineView:dataCellForTableColumn:item:")

; ----- Add checkboxes to specified rows
ReDim ButtonCell(CountGadgetItems(0) - 1)
AddCheckBoxToTreeRow(0)
AddCheckBoxToTreeRow(1)
AddCheckBoxToTreeRow(3)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

For i = 0 To CountGadgetItems(0) - 1
  If ButtonCell(i)
    If GetGadgetItemState(0, i) & #PB_Tree_Checked
      Debug "Item '" + GetGadgetItemText(0, i) + "' is checked."
    Else
      Debug "Item '" + GetGadgetItemText(0, i) + "' is unchecked."
    EndIf

    CocoaMessage(0, ButtonCell(i), "release")
  EndIf
Next i