diff options
| author | Greg Ercolano <erco@seriss.com> | 2012-05-29 13:34:39 +0000 |
|---|---|---|
| committer | Greg Ercolano <erco@seriss.com> | 2012-05-29 13:34:39 +0000 |
| commit | df5c8cc76f19c7366f0c4b35cb9470e6eea27a90 (patch) | |
| tree | 8e4edd6d7b38b5f317c51009f75a8f451a29f6e3 /src/Fl_Tree.cxx | |
| parent | 3bcc267052e4b6bacf21db54285df552fec45240 (diff) | |
Fixed some keynav problems:
No focus, hitting down would skip first item
Enter key to toggle was falling through to other widgets
Removing an item that has focus clears item focus (to prevent wild ptr)
Added new methods:
Fl_Tree::get_item_focus()
Fl_Tree::first_visible()
Fl_Tree::last_visible()
Fl_Tree::is_vscroll_visible()
Simplified + fixed Fl_Tree_Item::next_displayed()
Fixed Fl_Tree_Item::visible_r(), was skipping item if it was a closed branch.
tree demo: fixed button ordering for "Test Suggestions" button
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9555 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Tree.cxx')
| -rw-r--r-- | src/Fl_Tree.cxx | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/src/Fl_Tree.cxx b/src/Fl_Tree.cxx index 95247e354..1f91a00e9 100644 --- a/src/Fl_Tree.cxx +++ b/src/Fl_Tree.cxx @@ -195,21 +195,24 @@ int Fl_Tree::handle(int e) { // Do shortcuts first or scrollbar will get them... if ( (Fl::focus() == this) && // tree has focus? _prefs.selectmode() > FL_TREE_SELECT_NONE ) { // select mode that supports kb events? - if ( !_item_focus ) { - set_item_focus(first()); + if ( !_item_focus ) { // no current focus item? + set_item_focus(first_visible()); // use first vis item + if ( Fl::event_key() == FL_Up || // Up or down? + Fl::event_key() == FL_Down ) // ..if so, already did 'motion' + return(1); // ..so just return. } if ( _item_focus ) { int ekey = Fl::event_key(); switch (ekey) { case FL_Enter: // ENTER: toggle open/close case FL_KP_Enter: { - open_toggle(_item_focus, when()); - break; + open_toggle(_item_focus, when()); // toggle item in focus + return(1); // done, we handled key } case ' ': // SPACE: change selection state switch ( _prefs.selectmode() ) { case FL_TREE_SELECT_NONE: - break; + break; // ignore, let group have shot at event case FL_TREE_SELECT_SINGLE: if ( is_ctrl ) { // CTRL-SPACE: (single mode) toggle if ( ! _item_focus->is_selected() ) { @@ -221,7 +224,7 @@ int Fl_Tree::handle(int e) { select_only(_item_focus, when()); // SPACE: (single mode) select only } _lastselect = _item_focus; - return(1); + return(1); // done, we handled key case FL_TREE_SELECT_MULTI: if ( is_ctrl ) { select_toggle(_item_focus, when()); // CTRL-SPACE: (multi mode) toggle selection @@ -229,7 +232,7 @@ int Fl_Tree::handle(int e) { select(_item_focus, when()); // SPACE: (multi-mode) select } _lastselect = _item_focus; - return(1); + return(1); // done, we handled key } break; case FL_Right: // RIGHT: open children (if any) @@ -280,7 +283,7 @@ int Fl_Tree::handle(int e) { case FL_TREE_SELECT_MULTI: // Do a 'select all' select_all(); - _lastselect = first(); + _lastselect = first_visible(); take_focus(); return(1); } @@ -588,13 +591,16 @@ Fl_Tree_Item* Fl_Tree::insert(Fl_Tree_Item *item, const char *name, int pos) { /// Remove the specified \p item from the tree. /// \p item may not be NULL. /// If it has children, all those are removed too. +/// If item being removed has focus, no item will have focus. /// \returns 0 if done, -1 if 'item' not found. /// int Fl_Tree::remove(Fl_Tree_Item *item) { + // Item being removed is focus item? zero focus + if ( item == _item_focus ) _item_focus = 0; if ( item == _root ) { clear(); } else { - Fl_Tree_Item *parent = item->parent(); // find item's parent + Fl_Tree_Item *parent = item->parent(); // find item's parent if ( ! parent ) return(-1); parent->remove_child(item); // remove child + children } @@ -755,7 +761,8 @@ Fl_Tree_Item* Fl_Tree::item_clicked() { /// Fl_Tree_Item *Fl_Tree::next_visible_item(Fl_Tree_Item *item, int dir) { if ( ! item ) { // no start item? - item = ( dir == FL_Up ) ? last() : first(); // start at top or bottom + item = ( dir == FL_Up ) ? last_visible() : // wrap to bottom + first_visible(); // wrap to top if ( ! item ) return(0); if ( item->visible_r() ) return(item); // return first/last visible item } @@ -782,6 +789,19 @@ Fl_Tree_Item* Fl_Tree::first() { return(_root); // first item always root } +/// Returns the first visible item in the tree. +/// \returns first visible item in tree, or 0 if none. +/// \see first_visible(), last_visible() +/// +Fl_Tree_Item* Fl_Tree::first_visible() { + Fl_Tree_Item *i = showroot() ? first() : next(first()); + while ( i ) { + if ( i->visible() ) return(i); + i = next(i); + } + return(0); +} + /// Return the next item after \p item, or 0 if no more items. /// /// Use this code to walk the entire tree: @@ -844,6 +864,26 @@ Fl_Tree_Item* Fl_Tree::last() { return(item); } +/// Returns the last visible item in the tree. +/// \returns last visible item in the tree, or 0 if none. +/// +/// \see first_visible(), last_visible() +/// +Fl_Tree_Item* Fl_Tree::last_visible() { + Fl_Tree_Item *item = last(); + while ( item ) { + if ( item->visible() ) { + if ( item == _root && !showroot() ) { + return(0); + } else { + return(item); + } + } + item = prev(item); + } + return(item); +} + /// Returns the first selected item in the tree. /// /// Use this to walk the tree looking for all the selected items, eg: @@ -1334,6 +1374,11 @@ int Fl_Tree::select_all(Fl_Tree_Item *item, int docallback) { return(count); } +/// Get the item that currently has keyboard focus. +Fl_Tree_Item* Fl_Tree::get_item_focus() const { + return(_item_focus); +} + /// Set the item that currently should have keyboard focus. /// Handles calling redraw() to update the focus box (if it is visible). /// @@ -1899,6 +1944,12 @@ void Fl_Tree::scrollbar_size(int size) { } } +/// See if the vertical scrollbar is currently visible. +/// \returns 1 if scrollbar visible, 0 if not. +int Fl_Tree::is_vscroll_visible() const { + return(_vscroll->visible() ? 1 : 0); +} + /// Do the callback for the item, setting the item and reason void Fl_Tree::do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason) { callback_reason(reason); |
