Treeview - couple of probs

Just starting out? Need help? Post your questions and find answers here.
Perkin
Enthusiast
Enthusiast
Posts: 504
Joined: Thu Jul 03, 2008 10:13 pm
Location: Kent, UK

Treeview - couple of probs

Post by Perkin »

Hi all, new to forums so please be gentle with me :)

I have a couple of problems with a treeview gadget i'm using.

I need to be able to doubleclick on items, what i want to do is either disable folding of children nodes.
(There will only be one sublevel which will be expanded for all nodes, and I'm not showing the Tree root boxes)

If I doubleclick on the parent , it currently folds/unfolds.

If I then automatically expand the node when double clicked, how can I keep the current view stationary ( the current top item stays there).

e.g. scroll down so 'This is a Disk' is at the top of the display, then doubleclick on 'This is another Disk', which folds/unfolds.
BUT changes the view.

I've been tring to get the first visible item and then seting the view back to that but have had no luck. ( #TVGN_FIRSTVISIBLE )

Can anyone help me either

disable the folding/unfolding on doubleclick

or

restore the view to where it was before re-expanding any doubleclicked parent

Anyboy have any ideas?

Thanks in advance.

Code: Select all

; treeview test
#Tree=51

Procedure TreeViewExpandAll(gadget.l) 
Define hwndTV.l, hRoot.l, hItem.l
  hwndTV.l = GadgetID(gadget)  
  hRoot.l = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)  
  hItem.l = hRoot  
  Repeat 
    SendMessage_(hwndTV, #TVM_EXPAND, #TVE_EXPAND, hItem) 
    hItem = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_NEXTVISIBLE , hItem)  
  Until hItem = #Null  
  SendMessage_(hwndTV, #TVM_ENSUREVISIBLE, 0, hRoot) 
EndProcedure 

Procedure RemoveTreeRootBoxes(treeview, bool)
Define result.l
  ;...This removes ALL +/- boxes at the tree root
  If bool
    result = SetWindowLong_(GadgetID(treeview), #GWL_STYLE, GetWindowLong_(GadgetID(treeview), #GWL_STYLE) & (~#TVS_LINESATROOT))
  Else
    result = SetWindowLong_(GadgetID(treeview), #GWL_STYLE, GetWindowLong_(GadgetID(treeview), #GWL_STYLE) | #TVS_LINESATROOT)
  EndIf
  ProcedureReturn result
EndProcedure

If OpenWindow(0, 0, 0, 280, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  
  TreeGadget(#Tree, 10, 10, 260, 180) ;,#PB_Tree_NoLines)
  ;...Remove +/- boxes at tree root
  RemoveTreeRootBoxes(#Tree, 1)

  AddGadgetItem(#Tree, -1, "Here's one song", 0, 0)
  AddGadgetItem(#Tree, -1, "Here's another song", 0, 0)
  AddGadgetItem(#Tree, -1, "This is a Disk", 0, 0)
  AddGadgetItem(#Tree, -1, "Song 01", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 02", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 03", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 04", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 05", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 06", 0, 1)
  AddGadgetItem(#Tree, -1, "Some other song", 0, 0)
  AddGadgetItem(#Tree, -1, "Just another song", 0, 0)
  AddGadgetItem(#Tree, -1, "This is another Disk", 0, 0)
  AddGadgetItem(#Tree, -1, "Song 01", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 02", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 03", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 04", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 05", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 06", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 07", 0, 1)
  AddGadgetItem(#Tree, -1, "Song 08", 0, 1)
  AddGadgetItem(#Tree, -1, "Another single song", 0, 0)

TreeViewExpandAll(#Tree)

  Repeat
    Event = WaitWindowEvent()
    Select Event
    Case #PB_Event_Gadget 
      Select EventGadget() 
      Case #Tree
        Select EventType()
        Case #PB_EventType_LeftClick
        Case #PB_EventType_RightClick
        Case #PB_EventType_LeftDoubleClick
          ; BUG - keep displayed contents in view
          CurrentItem.l = GetGadgetState(#Tree)
          CurSubLevel.l=GetGadgetItemAttribute(#Tree,CurrentItem,#PB_Tree_SubLevel)
          If curSubLevel=0 
            SetGadgetItemState(#Tree, CurrentItem, #PB_Tree_Expanded)
          EndIf
;          TreeViewExpandAll(#Tree)
        Case #PB_EventType_RightDoubleClick
        EndSelect
      EndSelect
    EndSelect
  Until Event = #PB_Event_CloseWindow
EndIf
End
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

You could subclass the treeview :

Code: Select all

; treeview test 
#Tree=51 

Procedure TreeViewExpandAll(gadget.l) 
  Define hwndTV.l, hRoot.l, hItem.l 
  hwndTV.l = GadgetID(gadget)  
  hRoot.l = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)  
  hItem.l = hRoot  
  Repeat 
    SendMessage_(hwndTV, #TVM_EXPAND, #TVE_EXPAND, hItem) 
    hItem = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_NEXTVISIBLE , hItem)  
  Until hItem = #NULL  
  SendMessage_(hwndTV, #TVM_ENSUREVISIBLE, 0, hRoot) 
EndProcedure 

Procedure RemoveTreeRootBoxes(treeview, bool) 
  Define result.l 
  ;...This removes ALL +/- boxes at the tree root 
  If bool 
    result = SetWindowLong_(GadgetID(treeview), #GWL_STYLE, GetWindowLong_(GadgetID(treeview), #GWL_STYLE) & (~#TVS_LINESATROOT)) 
  Else 
    result = SetWindowLong_(GadgetID(treeview), #GWL_STYLE, GetWindowLong_(GadgetID(treeview), #GWL_STYLE) | #TVS_LINESATROOT) 
  EndIf 
  ProcedureReturn result 
EndProcedure 

Procedure SubClassedTree(hwnd.l, message.l, wParam.l, lParam.l)
  Shared OldProc
  If OldProc
    If message = #WM_LBUTTONDBLCLK
      Debug "#PB_EventType_LeftDoubleClick"
    Else
      ReturnValue = CallWindowProc_(OldProc, hwnd, message, wParam, lParam)
    EndIf
    ProcedureReturn ReturnValue
  EndIf
EndProcedure


If OpenWindow(0, 0, 0, 280, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  
  TreeGadget(#Tree, 10, 10, 260, 180) ;,#PB_Tree_NoLines) 
  OldProc = SetWindowLong_(GadgetID(#Tree), #GWL_WNDPROC, @SubClassedTree())
  ;...Remove +/- boxes at tree root 
  RemoveTreeRootBoxes(#Tree, 1) 
  
  AddGadgetItem(#Tree, -1, "Here's one song", 0, 0) 
  AddGadgetItem(#Tree, -1, "Here's another song", 0, 0) 
  AddGadgetItem(#Tree, -1, "This is a Disk", 0, 0) 
  AddGadgetItem(#Tree, -1, "Song 01", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 02", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 03", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 04", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 05", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 06", 0, 1) 
  AddGadgetItem(#Tree, -1, "Some other song", 0, 0) 
  AddGadgetItem(#Tree, -1, "Just another song", 0, 0) 
  AddGadgetItem(#Tree, -1, "This is another Disk", 0, 0) 
  AddGadgetItem(#Tree, -1, "Song 01", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 02", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 03", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 04", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 05", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 06", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 07", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 08", 0, 1) 
  AddGadgetItem(#Tree, -1, "Another single song", 0, 0) 
  
  TreeViewExpandAll(#Tree) 
  
  Repeat 
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow 
EndIf 
End
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Alternatively :

Code: Select all

; treeview test 
#Tree=51 

Procedure TreeViewExpandAll(gadget.l) 
Define hwndTV.l, hRoot.l, hItem.l 
  hwndTV.l = GadgetID(gadget)  
  hRoot.l = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)  
  hItem.l = hRoot  
  Repeat 
    SendMessage_(hwndTV, #TVM_EXPAND, #TVE_EXPAND, hItem) 
    hItem = SendMessage_(hwndTV, #TVM_GETNEXTITEM, #TVGN_NEXTVISIBLE , hItem)  
  Until hItem = #Null  
  SendMessage_(hwndTV, #TVM_ENSUREVISIBLE, 0, hRoot) 
EndProcedure 


Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  Protected *nmh.NMHDR
  result = #PB_ProcessPureBasicEvents
  Select uMsg
    Case #WM_NOTIFY 
      *nmh = lParam
      Select *nmh\code
        Case #TVN_ITEMEXPANDING
          If *nmh\hwndFrom = GadgetID(#Tree)
            result =1
          EndIf
      EndSelect
  EndSelect
  ProcedureReturn Result
EndProcedure

If OpenWindow(0, 0, 0, 280, 200, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  
  TreeGadget(#Tree, 10, 10, 260, 180, #PB_Tree_NoLines|#PB_Tree_NoButtons) ;,#PB_Tree_NoLines) 

  AddGadgetItem(#Tree, -1, "Here's one song", 0, 0) 
  AddGadgetItem(#Tree, -1, "Here's another song", 0, 0) 
  AddGadgetItem(#Tree, -1, "This is a Disk", 0, 0) 
  AddGadgetItem(#Tree, -1, "Song 01", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 02", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 03", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 04", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 05", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 06", 0, 1) 
  AddGadgetItem(#Tree, -1, "Some other song", 0, 0) 
  AddGadgetItem(#Tree, -1, "Just another song", 0, 0) 
  AddGadgetItem(#Tree, -1, "This is another Disk", 0, 0) 
  AddGadgetItem(#Tree, -1, "Song 01", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 02", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 03", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 04", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 05", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 06", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 07", 0, 1) 
  AddGadgetItem(#Tree, -1, "Song 08", 0, 1) 
  AddGadgetItem(#Tree, -1, "Another single song", 0, 0) 
  TreeViewExpandAll(#Tree) 

  SetWindowCallback(@WinCallback())

  Repeat 
    Event = WaitWindowEvent() 
    Select Event 
    Case #PB_Event_Gadget 
      Select EventGadget() 
      Case #Tree 
        Select EventType() 
        Case #PB_EventType_LeftClick 
        Case #PB_EventType_RightClick 
        Case #PB_EventType_LeftDoubleClick 
        Case #PB_EventType_RightDoubleClick 
        EndSelect 
      EndSelect 
    EndSelect 
  Until Event = #PB_Event_CloseWindow 
EndIf 
End 
I may look like a mule, but I'm not a complete ass.
Perkin
Enthusiast
Enthusiast
Posts: 504
Joined: Thu Jul 03, 2008 10:13 pm
Location: Kent, UK

Thanks

Post by Perkin »

Both answers work as i would like.

Thanks to both of you.

I think I'll go with the way srod done it.

I do need the 'bars' for the child nodes, so I've taken out the '#PB__Tree_NoLines'

On a side note - this no longer needed the 'RemoveTreeRootBoxes'

Can you say why.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Because of the #PB_Tree_NoButtons style which you case use with the TreeGadget() command.
I may look like a mule, but I'm not a complete ass.
Perkin
Enthusiast
Enthusiast
Posts: 504
Joined: Thu Jul 03, 2008 10:13 pm
Location: Kent, UK

Post by Perkin »

I've just seen why it doesn't need RemoveTreeRootBoxes

'#PB_Tree_NoButtons'

Didn't notice it on first readthrough. (I don't usually use the flag, but as this is treeview will only have the one sublevel it works great)

Thanks for help.
Perkin
Enthusiast
Enthusiast
Posts: 504
Joined: Thu Jul 03, 2008 10:13 pm
Location: Kent, UK

Post by Perkin »

I'm now using the code from 'gnozal' as this allows me to also have the root boxes, which fold, and also allows the doubleclick event to do what I want.

Thanks gnozal :D
Post Reply