wxTreeCtrl with checkboxes
Posted: Sat May 31, 2014 8:25 am
Have you ever wanted a tree control with check boxes?
Probably not, but I recently needed to use many check boxes that had an obvious hierarchical structure. And so I decided to derive a class from wxTreeCtrl and use the tree control's state icons and a profusion of hittests to simulate check boxes. I decided to dump the code here in case anyone else would find it useful.
I know that wxTreeListCtrl supports check boxes, but I didn't quite like that implementation because 1) the check boxes aren't as responsive as I'd like. I sometimes need to click a box twice to get it to check or uncheck. 2) I didn't want clicking a check box to select the corresponding tree item. And 3) in wxTreeListCtrl, it seems either every node has check boxes or none do. I wanted the ability to mix nodes with and without check boxes.
Description
The class has all of wxTreeCtrl methods and 5 extra methods:
bool EnableCheckBox(const wxTreeItemId &item, bool enable = true );
bool DisableCheckBox(const wxTreeItemId &item);
void Check(const wxTreeItemId &item,bool state=true);
void Uncheck(const wxTreeItemId &item);
void MakeCheckable(const wxTreeItemId &item,bool state=false);
Basically, to make a node have a check box, you call MakeCheckable on the node's ids. You can then use the other 4 functions to check, uncheck, enable, or disable the box respectivly.
Events
The class emits 2 kinds of wxTreeEvents:
1)wxEVT_CHECKTREE_CHOICE: these events are generated when a box is checked or unchecked. In an event handler, GetItem() will return the tree item to which the check box belongs. And GetExtraLong() will return 0 if the box is currently unchecked and 1 if it is checked. (I couldn't figure out how to set value returned by the events IsChecked() method.)
2) wxEVT_CHECKTREE_FOCUS: as I mentioned above, I didn't want checking a box to result in the corresponding tree item to be focused. Instead I wanted the tree's items to only be focusable due to keyboard navigation. This left a slight problem: if you're navigating the applications form with the tab keys, when the you reach the tree control, there is no indication that it has focus until you start navigating the tree's nodes with the up and down arrows. I decided that when the tree receives focus from the keyboard, this event will be thrown so that if the application wants to do anything to indicate that the tree has focus, it can. The sample included in the zip has an example.
Probably not, but I recently needed to use many check boxes that had an obvious hierarchical structure. And so I decided to derive a class from wxTreeCtrl and use the tree control's state icons and a profusion of hittests to simulate check boxes. I decided to dump the code here in case anyone else would find it useful.
I know that wxTreeListCtrl supports check boxes, but I didn't quite like that implementation because 1) the check boxes aren't as responsive as I'd like. I sometimes need to click a box twice to get it to check or uncheck. 2) I didn't want clicking a check box to select the corresponding tree item. And 3) in wxTreeListCtrl, it seems either every node has check boxes or none do. I wanted the ability to mix nodes with and without check boxes.
Description
The class has all of wxTreeCtrl methods and 5 extra methods:
bool EnableCheckBox(const wxTreeItemId &item, bool enable = true );
bool DisableCheckBox(const wxTreeItemId &item);
void Check(const wxTreeItemId &item,bool state=true);
void Uncheck(const wxTreeItemId &item);
void MakeCheckable(const wxTreeItemId &item,bool state=false);
Basically, to make a node have a check box, you call MakeCheckable on the node's ids. You can then use the other 4 functions to check, uncheck, enable, or disable the box respectivly.
Events
The class emits 2 kinds of wxTreeEvents:
1)wxEVT_CHECKTREE_CHOICE: these events are generated when a box is checked or unchecked. In an event handler, GetItem() will return the tree item to which the check box belongs. And GetExtraLong() will return 0 if the box is currently unchecked and 1 if it is checked. (I couldn't figure out how to set value returned by the events IsChecked() method.)
2) wxEVT_CHECKTREE_FOCUS: as I mentioned above, I didn't want checking a box to result in the corresponding tree item to be focused. Instead I wanted the tree's items to only be focusable due to keyboard navigation. This left a slight problem: if you're navigating the applications form with the tab keys, when the you reach the tree control, there is no indication that it has focus until you start navigating the tree's nodes with the up and down arrows. I decided that when the tree receives focus from the keyboard, this event will be thrown so that if the application wants to do anything to indicate that the tree has focus, it can. The sample included in the zip has an example.