For SurgeED, I’ve had to build some tree views:
I’m using the Win32 C API to build the GUI, but the TreeView control available didn’t support everything I needed (or supported it in such oblique ways it was too much work). I tried finding a control like this on the Internet, but either they cost money (which I can’t afford), the functionality wasn’t there, or they used MFCs (which I don’t like).
I decided to build my own, on top of the Windows one, and make the code available.
My tree view supports:
-
Multiple selection
-
Drag/drop operation
-
Context sensitive pop-up menu
-
Callbacks for
-
Selection
-
Command (WM_COMMAND message)
-
Drag operation (start/finish)
-
Popup called
-
Sort operation
-
Size change
You can download the files here. They probably don’t work “out of the box”, some helper functions are missing, and probably some includes need to be removed. Anyway, it should be easy enough to extrapolate what’s missing.
Some usage instructions (check .h file for the public interface):
-
To initialize (register the window class – you have to create a define called SURGE_TREE_VIEW with the name you want the class to have internally), you have to call “scc_register_tree_view()”. To unregister, call “scc_unregister_tree_view()”
-
To create a tree view, either use a custom control (with the class set to whatever the name was), or something like:
HWND tree= CreateWindow(SURGE_TREE_VIEW,window_name,window_flags,
x,y,width,height,parent_window,NULL,instance,0L);
To enable/disable multiple selection, call “scc_set_tree_view_multiselect(tree,true/false)” To set a callback function, use “scc_set_tree_view_*_callback” To add nodes, you have to use "scc_add_node”. This takes as a parameter an object of type SurgeTreeNode (more on this later). This will add the node at the top level of the Tree View. To add elements as sub-nodes, use the “add_node” function on the SurgeTreeNode you want to be parent of this one. The SurgeTreeNode is the base class of all the nodes in the tree. You should subclass it for “type of nodes”. For example, on the Component Explorer of SurgeED, I have loads of classes (“Project”, “Component Group”, “Component”, “Group” and “Entity”). All of these can have different options on the pop-up menu, have different behaviors on drag, etc.
- add_node: Adds a subnode to this node
-
remove: Remove a subnode from this node
-
expand: Expands/contracts this node
-
toggle_expand: Expands the node if it is contracted, and vice-versa
-
select: Selects this node (and the nodes below, if the second parameter is set to “true”). Note that for this to work correctly, when you select a node, all the nodes below it are unselected (or else we could have some weird behaviors on the drags), although they are still highlighted (like they are selected because someone up the chain is selected)
-
toggle_select: Selects this node if it is unselected, and vice-versa
-
update_label: Forces a refresh on the label of the node
-
set_bold: Sets the label on this node to bold
-
(Virtual) get_label: Returns the label of the node
-
(Virtual) evt_select_change: This function is called whenever this node is selected
-
(Virtual) is_draggable: Should return true if this node can be dragged. Only if all nodes in the current selection can be dragged can the operation be executed.
-
(Virtual) try_drag: Should return true if this node can be dragged to the given target node
-
(Virtual) can_accept: Should return true if this node can accept all the given nodes as sub-nodes
-
(Virtual) notify_drag: This function gets call for each node that is dragged onto the target node, when the drag operation is completed (don’t have to do anything to change the structure of the tree itself, the nodes will be moved to the correct place)
-
(Virtual) get_menu_options: fetches a list of strings with the names of the options to show up on the pop-up menu. Only the options that are shared by all the selected nodes show up.
-
(Virtual) handle_menu_option: Gets called for all selected nodes when an option is selected.
For the record, you can use this code in any way you want (commercial and non-commercial), a heads-up and thank you would be nice.
I’m not responsible for any damages and bugs!
Anyway, if you have any questions, just shoot them here or email me…
Hope this is helpful!