More fixes for STR #3527; handle usericons, etc

This commit is contained in:
Greg Ercolano 2019-08-25 01:13:35 -07:00
parent eed1d364d9
commit 4870cde0a6
4 changed files with 38 additions and 9 deletions

View File

@ -293,7 +293,7 @@ class FL_EXPORT Fl_Tree : public Fl_Group {
Fl_Tree_Prefs _prefs; // all the tree's settings
int _scrollbar_size; // size of scrollbar trough
Fl_Tree_Item *_lastselect; // last selected item
char _lastpushed; // entity FL_PUSH occurred on: 0=nothing, 1=open/close, 2=item
char _lastpushed; // FL_PUSH occurred on: 0=nothing, 1=open/close, 2=usericon, 3=label
void fix_scrollbar_order();
protected:

View File

@ -453,6 +453,7 @@ public:
const Fl_Tree_Item* find_clicked(const Fl_Tree_Prefs &prefs, int yonly=0) const;
Fl_Tree_Item* find_clicked(const Fl_Tree_Prefs &prefs, int yonly=0);
int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const;
int event_on_user_icon(const Fl_Tree_Prefs &prefs) const;
int event_on_label(const Fl_Tree_Prefs &prefs) const;
/// Is this item the root of the tree?
int is_root() const {

View File

@ -219,7 +219,7 @@ int Fl_Tree::extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to,
return(changed);
}
enum { PushedNothing=0, PushedOpenClose, PushedItem };
enum { PUSHED_NONE=0, PUSHED_OPEN_CLOSE, PUSHED_USER_ICON, PUSHED_LABEL };
/// Standard FLTK event handler for this widget.
/// \todo add Fl_Widget_Tracker (see Fl_Browser_.cxx::handle())
int Fl_Tree::handle(int e) {
@ -386,9 +386,10 @@ int Fl_Tree::handle(int e) {
if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
Fl_Tree_Item *item = _root->find_clicked(_prefs, 0);
// Tell FL_DRAG what was pushed
_lastpushed = item ? (item->event_on_collapse_icon(_prefs) ? PushedOpenClose // open/close icon clicked
: PushedItem) // item clicked
: PushedNothing; // none of the above
_lastpushed = item ? item->event_on_collapse_icon(_prefs) ? PUSHED_OPEN_CLOSE // open/close icon clicked
: item->event_on_user_icon(_prefs) ? PUSHED_USER_ICON // usericon clicked
: PUSHED_LABEL // label clicked
: PUSHED_NONE; // none of the above
if ( !item ) { // clicked, but not on an item?
_lastselect = 0;
switch ( _prefs.selectmode() ) {
@ -407,8 +408,7 @@ int Fl_Tree::handle(int e) {
if ( Fl::event_button() == FL_LEFT_MOUSE ) {
if ( item->event_on_collapse_icon(_prefs) ) { // collapse icon clicked?
open_toggle(item); // toggle open (handles redraw)
} else if ( item->event_on_label(_prefs) && // label clicked?
(!item->widget() || !Fl::event_inside(item->widget())) ) { // not inside widget
} else if ( !item->widget() || !Fl::event_inside(item->widget()) ) { // not inside widget()
switch ( _prefs.selectmode() ) {
case FL_TREE_SELECT_NONE:
break;
@ -440,8 +440,11 @@ int Fl_Tree::handle(int e) {
break;
}
case FL_DRAG: {
// FL_PUSH not on item? Ignore drag to prevent unexpected selections (STR #3527)
if ( _lastpushed != PushedItem ) return 0;
// FL_PUSH outside item or on open/close?
// Ignore drag to prevent unexpected selections (STR #3527)
//
if ( _lastpushed == PUSHED_NONE ||
_lastpushed == PUSHED_OPEN_CLOSE ) return 0;
// Do scrolling first

View File

@ -1190,6 +1190,31 @@ int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const {
}
}
/// Was the event on the 'user icon' of this item, if any?
///
int Fl_Tree_Item::event_on_user_icon(const Fl_Tree_Prefs &prefs) const {
// NOTE: Fl_Tree_Item doesn't keep an _xywh[] for usericon, but we can derive it as
// by elimitation of all other possibilities.
if ( !is_visible() ) return 0; // item not visible? not us
if ( !event_inside(_xywh) ) return 0; // not inside item? not us
if ( event_on_collapse_icon(prefs) ) return 0; // inside collapse icon? not us
if ( Fl::event_x() >= _label_xywh[0] ) return 0; // inside label or beyond (e.g. widget())? not us
// Is a user icon being shown?
// TBD: Determining usericon xywh and 'if displayed' should be class methods used here and by draw_*()
Fl_Image *ui = 0;
if ( is_active() ) {
if ( usericon() ) ui = usericon(); // user icon for item?
else if ( prefs.usericon() ) ui = prefs.usericon(); // user icon for tree?
} else {
if ( userdeicon() ) ui = userdeicon(); // user deicon for this item?
else if ( prefs.userdeicon() ) ui = prefs.userdeicon(); // user deicon for tree?
}
if ( !ui ) return 0; // no user icon? not us
int uix = _label_xywh[0]-ui->w(); // find x position of usericon
if ( Fl::event_x() < uix ) return 0; // event left of usericon? not us
return 1; // must be inside usericon by elimination
}
/// Was event on the label() of this item?
///
int Fl_Tree_Item::event_on_label(const Fl_Tree_Prefs &prefs) const {