Page 1 of 1

TreeGadget question

Posted: Tue Dec 16, 2008 10:09 pm
by quasiperfect
is possible to display CheckBoxes only for desired items in a TreeGadget ?

what i want to do
Image

Posted: Wed Dec 17, 2008 10:42 am
by Shardik
For Windows (successfully tested in Win98SE, WinNT SP6 and WinXP SP2) you could try this API solution:

Code: Select all

Procedure SwitchCheckBoxVisibility(ItemID)
  Protected TVItem.TV_ITEM

  TVItem\Mask = #TVIF_STATE
  TVItem\hItem = GadgetItemID(0, ItemID)
  TVItem\StateMask = #TVIS_STATEIMAGEMASK
  SendMessage_(GadgetID(0), #TVM_GETITEM, 0, @TVItem)

  If TVItem\State & $3000
    TVItem\State = 0
  Else
    TVItem\State = $1000
  EndIf
 
  SendMessage_(GadgetID(0), #TVM_SETITEM, 0, @TVItem)
EndProcedure

If OpenWindow(0, 0, 0, 160, 140, "TreeView Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CompilerIf #PB_Compiler_Version < 430
    CreateGadgetList(WindowID(0))
  CompilerEndIf
 
  TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 40, #PB_Tree_CheckBoxes)
  ButtonGadget(1, 10, WindowHeight(0) - 25, WindowWidth(0) - 20, 20, "Switch CheckBox Visibility")

  AddGadgetItem(0, -1, "Node", 0, 0)

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

  SetGadgetItemState(0, 0, #PB_Tree_Expanded)

  Repeat
    WindowEvent = WaitWindowEvent()

    If WindowEvent = #PB_Event_Gadget
      If EventGadget() = 1
        SwitchCheckBoxVisibility(2)
      EndIf
    EndIf   
  Until WindowEvent = #PB_Event_CloseWindow
EndIf

Posted: Wed Dec 17, 2008 6:39 pm
by Sparkie
This works well on XP but it's not tested on Vista....
http://www.purebasic.fr/english/viewtop ... 079#271079

Posted: Thu Dec 18, 2008 9:35 am
by quasiperfect
thanks to both, that solves my problem :)

@Shardik +1

Posted: Thu Dec 18, 2008 3:08 pm
by Sparkie
@Shardik: One minor bug you may want to address.... select an item without a checkbox and then press the spacebar. The checkbox will once again be visible for that item.

Posted: Fri Dec 19, 2008 1:11 pm
by Shardik
@Sparkie: you are right. I had to integrate the callback from your posting in order to catch the spacebar action for items without checkbox in order to rewrite an item without checkbox and to keep track of the current state by using SetGadgetItemData for each item:

Code: Select all

Procedure SwitchCheckBoxVisibility(ItemID)
  Protected NMHdr.NMHDR
  Protected TVItem.TV_ITEM

  TVItem\Mask =  #TVIF_HANDLE | #TVIF_STATE
  TVItem\hItem = GadgetItemID(0, ItemID)
  TVItem\StateMask = #TVIS_STATEIMAGEMASK
  SendMessage_(GadgetID(0), #TVM_GETITEM, 0, @TVItem)

  If TVItem\State & $3000
    TVItem\State = 0
    SetGadgetItemData(0, ItemID, #False)
  Else
    TVItem\State = $1000
    SetGadgetItemData(0, ItemID, #True)
  EndIf
 
  SendMessage_(GadgetID(0), #TVM_SETITEM, 0, @TVItem)
EndProcedure

Procedure WindowCallback(Handle, Msg, WParam, LParam)
  If Msg = #WM_NOTIFY
    *NMHdr.NMHDR = LParam
    If *NMHdr\hWndFrom = GadgetID(0)
      If *NMHdr\Code = #NM_CUSTOMDRAW
        *NMTVCustomDraw.NMTVCUSTOMDRAW = LParam
        ItemID = *NMTVCustomDraw\nmcd\lItemlParam
        ;- See if the checkbox is set to on or off
        If GetGadgetItemData(0, ItemID) = #False
          ;- If it's set to off, prevent the checkbox from displaying
          TVItem.TV_ITEM
          TVItem\Mask = #TVIF_HANDLE | #TVIF_STATE
          TVItem\hItem = GadgetItemID(0, ItemID)
          TVItem\State = 0
          TVItem\StateMask = #TVIS_STATEIMAGEMASK
          SendMessage_(*NMHdr\hWndFrom, #TVM_SETITEM, 0, @TVItem)
        EndIf
      EndIf
    EndIf
  EndIf
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 160, 140, "TreeView Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CompilerIf #PB_Compiler_Version < 430
    CreateGadgetList(WindowID(0))
  CompilerEndIf
 
  TreeGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 40, #PB_Tree_CheckBoxes)
  ButtonGadget(1, 10, WindowHeight(0) - 25, WindowWidth(0) - 20, 20, "Switch CheckBox Visibility")

  AddGadgetItem(0, -1, "Node", 0, 0)
  SetGadgetItemData(0, 0, #True)

  For i = 1 To 3
    AddGadgetItem(0, -1, "Subnode " + Str(i), 0, 1)
    SetGadgetItemData(0, i, #True)
  Next i

  SetGadgetItemState(0, 0, #PB_Tree_Expanded)

  SetWindowCallback(@WindowCallback())

  Repeat
    WindowEvent = WaitWindowEvent()

    If WindowEvent = #PB_Event_Gadget
      If EventGadget() = 1
        SwitchCheckBoxVisibility(2)
      EndIf
    EndIf
  Until WindowEvent = #PB_Event_CloseWindow
EndIf