Expand All TreeView nodes?
BlitzMax Forums/MaxGUI Module/Expand All TreeView nodes?
| ||
How do I do it? The code below doesn't work and I'm wondering what I'm doing wrong? If TreeView Local root_node:TGadget=TreeViewRoot(TreeView) For Local node:TGadget=EachIn root_node.kids If node.CountKids() > 0 Then ExpandTreeViewNode node Next End If Any ideas appreciated! Thanks David |
| ||
A simple recursive function should do the trick. How about something like this:Function ExpandAllTreeViewNodes( pTreeView:TGadget, pRecurseNode:TGadget = Null ) If Not pTreeView Then Return If pRecurseNode Then ExpandTreeViewNode( pRecurseNode ) PollSystem() For Local tmpChildNode:TGadget = EachIn pRecurseNode.kids ExpandAllTreeViewNodes( pTreeView, tmpChildNode ) Next Else ExpandAllTreeViewNodes( pTreeView, TreeViewRoot(pTreeView) ) EndIf EndFunctionIt should iterate through all nodes and child-nodes and expand them each in turn. Don't worry about the second parameter when calling it, simply pass the treeview you want to completely expand. For example (modified CreateTreeView.bmx source from the BMax docs): |
| ||
Seb, Thanks very much for a thorough answer. I really appreciate it. I'm running your example on OS X 10.4.10 Intel iMac, however, and the treeview stays collapsed (as does my initial attempt's code). Perhaps this is an OS X issue? Did you try it on your mac? David |
| ||
I'm running your example on OS X 10.4.10 Intel iMac, however, and the treeview stays collapsed (as does my initial attempt's code). That's strange... It seems to work fine on Windows. You could try calling RedrawGadget( treeview ) after calling ExpandAllTreeViewNodes(). I'm away from home at the moment, so I didn't have my Mac to try it on. |
| ||
Unfortunately the result is the same with RedrawGadget( treeview ) included as suggested above. All nodes remain collapsed. |
| ||
Did you check if there is some OSX design enforcement on that topic? many of the OSX ui things have enforced behaviors to guarantee consistency. |
| ||
Dreamora, I'm not sure of the logic of such a restriction or how it is enforced when single calls to ExpandTreeViewNode(node) work just fine in the example above? For eg, although the above doesn't work, if I place (OS X) ExpandTreeViewNode(help) ExpandTreeViewNode(projects) Just under (or instead of) ExpandAllTreeViewNodes( treeview ) 'Let's expand all the nodes we just created Then help and projects (but not project 2) expand as expected. |
| ||
Try the (now modified) function I posted above. It's a shot in the dark, but it might work :-P Notice the addition of PollSystem() after ExpandTreeViewNode(). I remember having a few problems with Cocoa not updating under certain circumstances but PollSystem() fixed them. If that doesn't work, could you post what happens to the treeview if you add DebugStop before calling ExpandAllTreeViewNodes() and step through the function line-by-line. |
| ||
Modified function has no effect Seb. Strangely, I can't see the line I'm on (no highlighting - this is in the plain MaxIDE) when I try a DebugStop on this (even though the debugger works fine if I switch straight to the project I'm working on). But by inserting a print statement after every line in the recursive function I can say with certainty that the code never enters the for-loop. For Local tmpChildNode:TGadget = EachIn pRecurseNode.kids ' We never get in here Next This is despite pRecurseNode.CountKids() returning the right amount immediately before this same loop A puzzle! |
| ||
What is output if you call pRecurseNode.kids.Count() just before the For...Next loop? From what you've said, it seems as though Cocoa MaxGUI isn't storing child nodes in the parent's kid list (which is strange). NB: pRecurseNode.CountKids() uses an external Cocoa fuinction to count how many children there are and therefore doesn't rely on pRecurseNode.kids.Count(). |
| ||
OK let's get a bit more serious. 1. The debugger is working this morning! 2. Modified code: Function ExpandAllTreeViewNodes( pTreeView:TGadget, pRecurseNode:TGadget = Null ) If Not pTreeView Then Return If pRecurseNode Then Print "Recurse Node is OK, about to expand " +GadgetText(pRecurseNode) ExpandTreeViewNode( pRecurseNode ) PollSystem() Print "Pre For Loop node " +GadgetText(pRecurseNode) +" has kids: " +pRecurseNode.Countkids() +" alt kids count: " +pRecurseNode.kids.Count() If pRecurseNode.kids = Null Print "kids are null!" For Local tmpChildNode:TGadget = EachIn pRecurseNode.kids Print "Inside For Loop: num kids " +pRecurseNode.Countkids() ExpandAllTreeViewNodes( pTreeView, tmpChildNode ) Next Else Print GadgetText(pTreeView) + " Recursing to a root node" ExpandAllTreeViewNodes( pTreeView, TreeViewRoot(pTreeView) ) EndIf EndFunction Produces the following output. Note GadgetText doesn't seem to work on the nodes? Building test_expand_treeview Compiling:test_expand_treeview.bmx Linking:test_expand_treeview.debug Executing:test_expand_treeview.debug Recursing to a root node Recurse Node is OK, about to expand Pre For Loop node has kids: 2 alt kids count: 0 WindowActivate: data=0, mods=0, x=0, y=0, extra="" AppResume: data=0, mods=0, x=0, y=0, extra="" WindowClose: data=0, mods=0, x=0, y=0, extra="" Process complete |
| ||
It seems like nodes aren't being added the parent node's child list when using the Cocoa MaxGUI driver. Therefore, we can't iterate through them and expand them. I don't think there is much you can do about this - you could try posting a bug report in the MaxGUI Bug Reports forum, but I wouldn't hold your breath! |
| ||
Thanks Seb. Assuming I can work around this problem, I'm still faced with the need to clear and repopulate a treeview in OSX. Given that I can't traverse the child nodes, how to I clear a treeview in OSX without actually freeing the gadget? [later edit] One messy and inefficient answer: You can create a TList and add a node to the list every time one is added to the treeview. Then: Method FreeListNodes() If Not TreeView Or Not List Return Local b_node_removed:Int = True ' While at least one node has been removed last pass While b_node_removed b_node_removed = False ' Step through all nodes in the list For Local node:TGadget = EachIn List ' If the node has no children, it is safe to remove If node.CountKids() = 0 List.Remove(node) FreeTreeViewNode(node) b_node_removed = True EndIf Next Wend ' This should be redundant List.Clear() End Method |
| ||
I've used these function from the code archives and they work fine on Win32, but you may again have some problems on OS X. |
| ||
No, that code appears to be broken as well. For example, using the above example Print TreeViewNodeIndex(AddTreeViewNode("node sits under projects",projects)) Prints 0 using Jake's code. Actually it calls an exception as Jake fails to test for NULL links before calling link.Value(). I think the node child List is broken in MacOS treeviews generally. Be nice if someone else out there would confirm this before I submit a bug report though. |