Author: greg.ercolano
Date: 2012-04-23 21:45:03 -0700 (Mon, 23 Apr 2012)
New Revision: 9400
Log:
Fixes STR #2796
Prevent situations where user finds themselves scrolled past bottom of tree.


Modified:
   branches/branch-1.3/FL/Fl_Tree.H
   branches/branch-1.3/src/Fl_Tree.cxx

Modified: branches/branch-1.3/FL/Fl_Tree.H
===================================================================
--- branches/branch-1.3/FL/Fl_Tree.H    2012-04-24 04:42:46 UTC (rev 9399)
+++ branches/branch-1.3/FL/Fl_Tree.H    2012-04-24 04:45:03 UTC (rev 9400)
@@ -289,6 +289,7 @@
   void do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason);
   Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir);
   void extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to);
+  int draw_tree();
 
 public:
   Fl_Tree(int X, int Y, int W, int H, const char *L=0);

Modified: branches/branch-1.3/src/Fl_Tree.cxx
===================================================================
--- branches/branch-1.3/src/Fl_Tree.cxx 2012-04-24 04:42:46 UTC (rev 9399)
+++ branches/branch-1.3/src/Fl_Tree.cxx 2012-04-24 04:45:03 UTC (rev 9400)
@@ -404,8 +404,37 @@
   return(ret);
 }
 
+static void redraw_soon(void *data) {
+  ((Fl_Tree*)data)->redraw();
+  Fl::remove_timeout(redraw_soon, data);
+}
+
 /// Standard FLTK draw() method, handles drawing the tree widget.
 void Fl_Tree::draw() {
+  int ytoofar = draw_tree();
+  // See if we're scrolled below bottom of tree
+  //   This can happen if someone just closed a large item.
+  //   If so, change scroller as needed.
+  //
+  if ( _vscroll->visible() && ytoofar > 0 ) {
+    int scrollval = _vscroll->value();
+    int ch = h() - Fl::box_dh(box());
+    int range2 = scrollval - ytoofar;
+    int size2 = ch + range2;
+    if ( range2 < 0 ) {
+      _vscroll->value(0);
+      _vscroll->hide();
+    } else {
+      _vscroll->slider_size(float(ch)/float(size2));
+      _vscroll->range(0.0,range2);
+      _vscroll->value(range2);
+    }
+    Fl::add_timeout(.10, redraw_soon, (void*)this);    // use timer to trigger 
redraw; we can't
+  }
+}
+
+int Fl_Tree::draw_tree() {
+  int ret = 0;
   fix_scrollbar_order();
   // Let group draw box+label but *NOT* children.
   // We handle drawing children ourselves by calling each item's draw()
@@ -420,7 +449,7 @@
       Fl_Group::draw_box();
       Fl_Group::draw_label();
     }
-    if ( ! _root ) return;
+    if ( ! _root ) return(0);
     // These values are changed during drawing
     // By end, 'Y' will be the lowest point on the tree
     int X = cx + _prefs.marginleft();
@@ -452,7 +481,7 @@
       int SY = Y;
 #endif
       int ydiff = (SY+_prefs.margintop())-Ysave;               // ydiff=size 
of tree
-      int ytoofar = (cy+ch) - SY;                              // ytoofar -- 
scrolled beyond bottom (e.g. stow)
+      int ytoofar = (cy+ch) - SY;                              // ytoofar -- 
if >0, scrolled beyond bottom
       if ( ytoofar > 0 ) ydiff += ytoofar;
       if ( Ysave<cy || ydiff>ch || int(_vscroll->value())>1 ) {
        _vscroll->visible();
@@ -465,13 +494,16 @@
        _vscroll->resize(sx,sy,sw,sh);
        _vscroll->slider_size(float(ch)/float(ydiff));
        _vscroll->range(0.0,ydiff-ch);
+       ret = ytoofar;
       } else {
        _vscroll->Fl_Slider::value(0);
        _vscroll->hide();
+       ret = 0;
       }
     }
   }
   draw_child(*_vscroll);       // draw scroll last
+  return(ret);
 }
 
 /// Print the tree as 'ascii art' to stdout.

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to