Author: AlbrechtS
Date: 2010-12-22 05:06:03 -0800 (Wed, 22 Dec 2010)
New Revision: 8101
Log:
Added Fl_Tabs::client_area() (STR #2480).
Fixed some typos in CHANGES.


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

Modified: branches/branch-1.3/CHANGES
===================================================================
--- branches/branch-1.3/CHANGES 2010-12-22 13:05:06 UTC (rev 8100)
+++ branches/branch-1.3/CHANGES 2010-12-22 13:06:03 UTC (rev 8101)
@@ -3,7 +3,7 @@
 
          New Features
 
-       - Added UTF-8 Unicode supprt
+       - Added UTF-8 Unicode support
        - Added Fl_Tree widget for hierarchical views
        - Added Fl_Table widget for widget layout
        - Added Fl_Native_Filechooser as a widget and global options
@@ -13,7 +13,9 @@
        - Added basic Fl_Device abstraction layer for all drawing functions
 
          Other Additions
-       
+
+       - Added new method client_area() for easier positioning of children
+         in Fl_Tabs (STR #2480)
        - Added global UI options (STR #2471)
        - Added drag'n'drop support for Fl_Text_*
        - Added new label and image alignments (STR #2269)
@@ -28,7 +30,7 @@
        - Added class Fl_Widget_Tracker to simplify safe handling of widget
          deletion in callbacks. This is used in Fl_Widget::do_callback()
          to prevent accessing widgets after deletion in the callback.
-       - Added argument-less constructor in Fuid Widget Class
+       - Added argument-less constructor in Fluid Widget Class
        - Added Fl_Menu_::find_item by callback
        - Added indexing to Fl_Preferences
        - Added jpeg support to Fluid image() element
@@ -42,7 +44,7 @@
        - Added "ide" subdirectory for all IDE support files
         - Added Fl_Menu_ methods: insert(), find_index(), clear_submenu()
        - Added menu shortcut alignment for OS X
-       - Added drop box to utf8 test that will show the utf8 encoding
+       - Added drop box to UTF-8 test that will show the UTF-8 encoding
          for the first dropped character
        - Added flexible gap size for text buffer (STR #2046)
        - Added sorting to Fl_Browser_ (STR #2113)
@@ -50,7 +52,7 @@
        - Added scroll_to(int,int) to Fl_Scroll, replacing 
          position(int,int) which now behaves as it should (STR #1303)
        - Added alternative text input awareness on OS X 
-       
+
          Documentation
 
        - Added documentation for event delivery (STR #1983)
@@ -59,10 +61,10 @@
        - Updated Copyright dates to 2010 (STR #2036)
        - Updated mirror sites in documentation (STR #2220)
        - Fixed documentation for Fl_Progress (STR #2209)
-       - Fixed documentation (added missing COMCTRL32.LIB dependency)
-       
+       - Fixed documentation (added missing COMCTL32.LIB dependency)
+
          Improvements
-       
+
        - Moved OS X code base to the more modern Cocoa toolkit thanks
          to the awesome work of Manolo Gouy (STR #2221)
        - Improved handling of composed keys in OS X 10.5 and up
@@ -210,11 +212,10 @@
 
        - Removed Watcom compiler support because it was introduced in
          1.1.6 as a partial solution and never completed.
-       - Removed an XForms compatibility "feature" that prevented the down
-         array of Fl_Menu_Button from drawing (STR #2141).
+       - Removed an XForms compatibility "feature" that prevented the
+         down array of Fl_Menu_Button from drawing (STR #2141).
        - Removed support for gcc 2.x (or older)
        - Removed redundant Fl_Group casts
-       
 
 CHANGES IN FLTK 1.1.9
 
@@ -223,7 +224,7 @@
        - Fixed regression in callback handling (STR #1918)
        - Fixed wrong relative path when absolute path has a 
          trailing slash in fl_filename_relative (STR #1920)
-       - Fixed multiple selction of files and directories in
+       - Fixed multiple selection of files and directories in
          Fl_File_Chooser (STR #1913)
        - Fixed MSWindows crash when selecting umlauts
          in Fl_Help_View (STR #1912)

Modified: branches/branch-1.3/FL/Fl_Tabs.H
===================================================================
--- branches/branch-1.3/FL/Fl_Tabs.H    2010-12-22 13:05:06 UTC (rev 8100)
+++ branches/branch-1.3/FL/Fl_Tabs.H    2010-12-22 13:06:03 UTC (rev 8101)
@@ -62,7 +62,11 @@
 class FL_EXPORT Fl_Tabs : public Fl_Group {
   Fl_Widget *value_;
   Fl_Widget *push_;
-  int tab_positions(int*, int*);
+  int *tab_pos;                // array of x-offsets of tabs per child + 1
+  int *tab_width;      // array of widths of tabs per child + 1
+  int tab_count;       // array size
+  int tab_positions(); // allocate and calculate tab positions
+  void clear_tab_positions();
   int tab_height();
   void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0);
 protected:
@@ -77,6 +81,8 @@
   int push(Fl_Widget *);
   Fl_Tabs(int,int,int,int,const char * = 0);
   Fl_Widget *which(int event_x, int event_y);
+  ~Fl_Tabs();
+  void client_area(int &rx, int &ry, int &rw, int &rh, int tabh=0);
 };
 
 #endif

Modified: branches/branch-1.3/src/Fl_Tabs.cxx
===================================================================
--- branches/branch-1.3/src/Fl_Tabs.cxx 2010-12-22 13:05:06 UTC (rev 8100)
+++ branches/branch-1.3/src/Fl_Tabs.cxx 2010-12-22 13:06:03 UTC (rev 8101)
@@ -42,60 +42,74 @@
 #define EXTRASPACE 10
 #define SELECTION_BORDER 5
 
-// return the left edges of each tab (plus a fake left edge for a tab
-// past the right-hand one).  These position are actually of the left
+// Return the left edges of each tab (plus a fake left edge for a tab
+// past the right-hand one).  These positions are actually of the left
 // edge of the slope.  They are either separated by the correct distance
 // or by EXTRASPACE or by zero.
+// These positions are updated in the private arrays tab_pos[] and
+// tab_width[], resp.. If needed, these arrays are (re)allocated.
 // Return value is the index of the selected item.
 
-int Fl_Tabs::tab_positions(int* p, int* wp) {
+int Fl_Tabs::tab_positions() {
+  int nc = children();
+  if (nc != tab_count) {
+    clear_tab_positions();
+    if (nc) {
+      tab_pos   = (int*)malloc((nc+1)*sizeof(int));
+      tab_width = (int*)malloc((nc+1)*sizeof(int));
+    }
+    tab_count = nc;
+  }
+  if (nc == 0) return 0;
   int selected = 0;
   Fl_Widget*const* a = array();
   int i;
   char prev_draw_shortcut = fl_draw_shortcut;
   fl_draw_shortcut = 1;
 
-  p[0] = Fl::box_dx(box());
-  for (i=0; i<children(); i++) {
+  tab_pos[0] = Fl::box_dx(box());
+  for (i=0; i<nc; i++) {
     Fl_Widget* o = *a++;
     if (o->visible()) selected = i;
 
     int wt = 0; int ht = 0;
     o->measure_label(wt,ht);
 
-    wp[i]  = wt+EXTRASPACE;
-    p[i+1] = p[i]+wp[i]+BORDER;
+    tab_width[i] = wt + EXTRASPACE;
+    tab_pos[i+1] = tab_pos[i] + tab_width[i] + BORDER;
   }
   fl_draw_shortcut = prev_draw_shortcut;
 
   int r = w();
-  if (p[i] <= r) return selected;
+  if (tab_pos[i] <= r) return selected;
   // uh oh, they are too big:
   // pack them against right edge:
-  p[i] = r;
-  for (i = children(); i--;) {
-    int l = r-wp[i];
-    if (p[i+1] < l) l = p[i+1];
-    if (p[i] <= l) break;
-    p[i] = l;
+  tab_pos[i] = r;
+  for (i = nc; i--;) {
+    int l = r-tab_width[i];
+    if (tab_pos[i+1] < l) l = tab_pos[i+1];
+    if (tab_pos[i] <= l) break;
+    tab_pos[i] = l;
     r -= EXTRASPACE;
   }
   // pack them against left edge and truncate width if they still don't fit:
-  for (i = 0; i<children(); i++) {
-    if (p[i] >= i*EXTRASPACE) break;
-    p[i] = i*EXTRASPACE;
-    int W = w()-1-EXTRASPACE*(children()-i) - p[i];
-    if (wp[i] > W) wp[i] = W;
+  for (i = 0; i<nc; i++) {
+    if (tab_pos[i] >= i*EXTRASPACE) break;
+    tab_pos[i] = i*EXTRASPACE;
+    int W = w()-1-EXTRASPACE*(children()-i) - tab_pos[i];
+    if (tab_width[i] > W) tab_width[i] = W;
   }
   // adjust edges according to visiblity:
-  for (i = children(); i > selected; i--) {
-    p[i] = p[i-1]+wp[i-1];
+  for (i = nc; i > selected; i--) {
+    tab_pos[i] = tab_pos[i-1] + tab_width[i-1];
   }
   return selected;
 }
 
-// return space needed for tabs.  Negative to put them on the bottom:
+// Returns space (height) in pixels needed for tabs. Negative to put them on 
the bottom.
+// Returns full height, if children() = 0.
 int Fl_Tabs::tab_height() {
+  if (children() == 0) return h();
   int H = h();
   int H2 = y();
   Fl_Widget*const* a = array();
@@ -109,8 +123,10 @@
   else return (H <= 0) ? 0 : H;
 }
 
-// this is used by fluid to pick tabs:
+// This is used for event handling (clicks) and by fluid to pick tabs.
+// Returns 0, if children() = 0, or if the event is outside of the tabs area.
 Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
+  if (children() == 0) return 0;
   int H = tab_height();
   if (H < 0) {
     if (event_y > y()+h() || event_y < y()+h()+H) return 0;
@@ -120,17 +136,13 @@
   if (event_x < x()) return 0;
   Fl_Widget *ret = 0L;
   int nc = children();
-  int *p  = (int*)malloc((nc+1)*sizeof(int));
-  int *wp = (int*)malloc((nc+1)*sizeof(int));
-  tab_positions(p, wp);
-  for (int i=0; i<children(); i++) {
-    if (event_x < x()+p[i+1]) {
+  tab_positions();
+  for (int i=0; i<nc; i++) {
+    if (event_x < x()+tab_pos[i+1]) {
       ret = child(i);
       break;
     }
   }
-  free(p);
-  free(wp);
   return ret;
 }
 
@@ -325,21 +337,20 @@
   }
   if (damage() & (FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) {
     int nc = children();
-    int *p  = (int*)malloc((nc+1)*sizeof(int));
-    int *wp = (int*)malloc((nc+1)*sizeof(int));
-    int selected = tab_positions(p,wp);
+    int selected = tab_positions();
     int i;
     Fl_Widget*const* a = array();
     for (i=0; i<selected; i++)
-      draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], LEFT);
-    for (i=children()-1; i > selected; i--)
-      draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], RIGHT);
+      draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
+               tab_width[i], H, a[i], LEFT);
+    for (i=nc-1; i > selected; i--)
+      draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
+               tab_width[i], H, a[i], RIGHT);
     if (v) {
       i = selected;
-      draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], SELECTED);
+      draw_tab(x()+tab_pos[i], x()+tab_pos[i+1],
+               tab_width[i], H, a[i], SELECTED);
     }
-    free(p);
-    free(wp);
   }
 }
 
@@ -420,11 +431,11 @@
     away from the top or bottom edge of the Fl_Tabs widget,
     which is where the tabs will be drawn.
 
-    All children of Fl_Tab should have the same size and exactly fit on top of 
+    All children of Fl_Tabs should have the same size and exactly fit on top 
of 
     each other. They should only leave space above or below where that tabs 
will 
-    go, but not on the sides. If the first child of Fl_Tab is set to 
+    go, but not on the sides. If the first child of Fl_Tabs is set to 
     "resizable()", the riders will not resize when the tabs are resized.
- 
+
     The destructor <I>also deletes all the children</I>. This
     allows a whole tree to be deleted at once, without having to
     keep a pointer to all the children in the user code. A kludge
@@ -437,8 +448,81 @@
 {
   box(FL_THIN_UP_BOX);
   push_ = 0;
+  tab_pos = 0;
+  tab_width = 0;
+  tab_count = 0;
 }
 
+Fl_Tabs::~Fl_Tabs() {
+  clear_tab_positions();
+}
+
+/**
+    Returns the position and size available to be used by its children.
+
+    If there isn't any child yet the \p tabh parameter will be used to
+    calculate the return values. This assumes that the children's labelsize
+    is the same as the Fl_Tabs' labelsize and adds a small border.
+
+    If there are already children, the values of child(0) are returned, and
+    \p tabh is ignored.
+
+    \note Children should always use the same positions and sizes.
+
+    \p tabh can be one of
+    \li    0: calculate label size, tabs on top
+    \li   -1: calculate label size, tabs on bottom
+    \li >  0: use given \p tabh value, tabs on top (height = tabh)
+    \li < -1: use given \p tabh value, tabs on bottom (height = -tabh)
+
+    \param[in] tabh            position and optional height of tabs (see above)
+    \param[out]        rx,ry,rw,rh     (x,y,w,h) of client area for children
+*/
+void Fl_Tabs::client_area(int &rx, int &ry, int &rw, int &rh, int tabh) {
+
+  if (children()) {                    // use existing values
+
+    rx = child(0)->x();
+    ry = child(0)->y();
+    rw = child(0)->w();
+    rh = child(0)->h();
+
+  } else {                             // calculate values
+
+    int y_offset;
+    int label_height = fl_height(labelfont(), labelsize()) + BORDER*2;
+
+    if (tabh == 0)                     // use default (at top)
+      y_offset = label_height;
+    else if (tabh == -1)               // use default (at bottom)
+      y_offset = -label_height;
+    else
+      y_offset = tabh;                 // user given value
+
+    rx = x();
+    rw = w();
+
+    if (y_offset >= 0) {               // labels at top
+      ry = y() + y_offset;
+      rh = h() - y_offset;
+    } else {                           // labels at bottom
+      ry = y();
+      rh = h() + y_offset;
+    }
+  }
+}
+
+void Fl_Tabs::clear_tab_positions() {
+  if (tab_pos) {
+    free(tab_pos);
+    tab_pos = 0;
+  }
+  if (tab_width){
+    free(tab_width);
+    tab_width = 0;
+  }
+}
+
 //
 // End of "$Id$".
 //

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

Reply via email to