Fix problem with Fl_Tree::select_only() invoking select callbacks

before all other items have first been deselected.

Also: added some related demo code to tree-simple to demonstrate
'reselect' callbacks, where a callback can be invoked when an item
that's selected already is 're-selected'.



git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10015 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Greg Ercolano 2013-11-06 20:12:08 +00:00
parent 2fd7086605
commit 52d395ad81
2 changed files with 30 additions and 19 deletions

View File

@ -43,6 +43,13 @@ void TreeCallback(Fl_Widget *w, void *data) {
break;
case FL_TREE_REASON_CLOSED:
// fprintf(stderr, "TreeCallback: Item '%s' closed\n", item->label());
break;
#if FLTK_ABI_VERSION >= 10301
// To enable this callback, use tree->item_reselect_mode(FL_TREE_SELECTABLE_ALWAYS);
case FL_TREE_REASON_RESELECTED:
// fprintf(stderr, "TreeCallback: Item '%s' reselected\n", item->label());
break;
#endif
default:
break;
}

View File

@ -1317,29 +1317,33 @@ int Fl_Tree::select_only(Fl_Tree_Item *selitem, int docallback) {
selitem = selitem ? selitem : first(); // NULL? use first()
if ( ! selitem ) return(0);
int changed = 0;
// Deselect everything first.
// Prevents callbacks from seeing more than one item selected.
//
for ( Fl_Tree_Item *item = first(); item; item = item->next() ) {
if ( item == selitem ) {
#if FLTK_ABI_VERSION >= 10301
// NEW
if ( item->is_selected() ) { // already selected?
if ( item_reselect_mode() == FL_TREE_SELECTABLE_ALWAYS ) {
select(item, docallback); // handles callback with reason==reselect
}
continue; // leave 'changed' unmodified (nothing changed)
}
#else
// OLD
if ( item->is_selected() ) continue; // don't count if already selected
#endif
select(item, docallback);
if ( item == selitem ) continue; // don't do anything to selitem yet..
if ( item->is_selected() ) {
deselect(item, docallback);
++changed;
} else {
if ( item->is_selected() ) {
deselect(item, docallback);
++changed;
}
}
}
#if FLTK_ABI_VERSION >= 10301
// Should we 'reselect' item if already selected?
if ( selitem->is_selected() && (item_reselect_mode()==FL_TREE_SELECTABLE_ALWAYS) ) {
// Selection unchanged, so no ++change
select(selitem, docallback); // do callback with reason=reselect
} else if ( !selitem->is_selected() ) {
// Item was not already selected, select and indicate changed
select(selitem, docallback);
++changed;
}
#else
if ( !selitem->is_selected() ) {
// All items deselected, now select the one we want
select(selitem, docallback);
++changed;
}
#endif
return(changed);
}