DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2480
Version: 1.3-feature
Link: http://www.fltk.org/str.php?L2480
Version: 1.3-feature
Index: FL/Fl_Tabs.H
===================================================================
--- FL/Fl_Tabs.H (revision 8014)
+++ FL/Fl_Tabs.H (working copy)
@@ -62,7 +62,12 @@
class FL_EXPORT Fl_Tabs : public Fl_Group {
Fl_Widget *value_;
Fl_Widget *push_;
- int tab_positions(int*, int*);
+ int *tab_positions_p;
+ int *tab_positions_wp;
+ void clear_tab_positions();
+ int check_children_count_changed();
+ int tab_positions();
+ int tab_count_;
int tab_height();
void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0);
protected:
@@ -77,6 +82,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, bool top_if_first=true);
};
#endif
Index: src/Fl_Tabs.cxx
===================================================================
--- src/Fl_Tabs.cxx (revision 8014)
+++ src/Fl_Tabs.cxx (working copy)
@@ -40,6 +40,7 @@
#define BORDER 2
#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
@@ -47,48 +48,50 @@
// or by EXTRASPACE or by zero.
// 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 = check_children_count_changed();
+ 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_positions_p[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_positions_wp[i] = wt+EXTRASPACE;
+ tab_positions_p[i+1] = tab_positions_p[i]+tab_positions_wp[i]+BORDER;
}
fl_draw_shortcut = prev_draw_shortcut;
int r = w();
- if (p[i] <= r) return selected;
+ if (tab_positions_p[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_positions_p[i] = r;
+ for (i = nc; i--;) {
+ int l = r-tab_positions_wp[i];
+ if (tab_positions_p[i+1] < l) l = tab_positions_p[i+1];
+ if (tab_positions_p[i] <= l) break;
+ tab_positions_p[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_positions_p[i] >= i*EXTRASPACE) break;
+ tab_positions_p[i] = i*EXTRASPACE;
+ int W = w()-1-EXTRASPACE*(children()-i) - tab_positions_p[i];
+ if (tab_positions_wp[i] > W) tab_positions_wp[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_positions_p[i] = tab_positions_p[i-1]+tab_positions_wp[i-1];
}
return selected;
}
@@ -119,17 +122,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_positions_p[i+1]) {
ret = child(i);
break;
}
}
- free(p);
- free(wp);
return ret;
}
@@ -165,7 +164,7 @@
o = which(Fl::event_x(), Fl::event_y());
if (event == FL_RELEASE) {
push(0);
- if (o && Fl::visible_focus() && Fl::focus()!=this) {
+ if (o && Fl::visible_focus() && visible_focus() && Fl::focus()!=this) {
Fl::focus(this);
redraw_tabs();
}
@@ -197,7 +196,7 @@
return ret; }
case FL_FOCUS:
case FL_UNFOCUS:
- if (!Fl::visible_focus()) return Fl_Group::handle(event);
+ if (!Fl::visible_focus() && visible_focus()) return
Fl_Group::handle(event);
if (Fl::event() == FL_RELEASE ||
Fl::event() == FL_SHORTCUT ||
Fl::event() == FL_KEYBOARD ||
@@ -313,12 +312,9 @@
if (selection_color() != c) {
// Draw the top 5 lines of the tab pane in the selection color so
// that the user knows which tab is selected...
- if (H >= 0) fl_push_clip(x(), y() + H, w(), 5);
- else fl_push_clip(x(), y() + h() - H - 4, w(), 5);
-
- draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H),
- selection_color());
-
+ int clip_y = (H >= 0) ? y() + H : y() + h() + H - SELECTION_BORDER;
+ fl_push_clip(x(), clip_y, w(), SELECTION_BORDER);
+ draw_box(box(), x(), clip_y, w(), SELECTION_BORDER, selection_color());
fl_pop_clip();
}
if (v) draw_child(*v);
@@ -327,21 +323,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_positions_p[i], x()+tab_positions_p[i+1],
+ tab_positions_wp[i], H, a[i], LEFT);
+ for (i=nc-1; i > selected; i--)
+ draw_tab(x()+tab_positions_p[i], x()+tab_positions_p[i+1],
+ tab_positions_wp[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_positions_p[i], x()+tab_positions_p[i+1],
+ tab_positions_wp[i], H, a[i], SELECTED);
}
- free(p);
- free(wp);
}
}
@@ -439,8 +434,50 @@
{
box(FL_THIN_UP_BOX);
push_ = 0;
+ tab_positions_p = 0;
+ tab_positions_wp = 0;
+ tab_count_ = 0;
}
+Fl_Tabs::~Fl_Tabs() {
+ clear_tab_positions();
+}
+
+void Fl_Tabs::client_area(int &rx, int &ry, int &rw, int &rh, bool
top_if_first){
+ int tab_label_height = fl_height(labelfont(), labelsize()) + BORDER*2;
+ int y_offset;
+ if(children()) y_offset = tab_height() < 0 ? 0 : 1;
+ else y_offset = top_if_first ? 1 : 0;
+ rx = x() + BORDER;
+ ry = y() + BORDER + y_offset*tab_label_height;
+ rw = w()-BORDER*2;
+ rh = h() - BORDER*2 - tab_label_height;
+}
+
+void Fl_Tabs::clear_tab_positions() {
+ if(tab_positions_p) {
+ free(tab_positions_p);
+ tab_positions_p = 0;
+ }
+ if(tab_positions_wp){
+ free(tab_positions_wp);
+ tab_positions_wp = 0;
+ }
+}
+
+int Fl_Tabs::check_children_count_changed() {
+ int nc = children();
+ if(nc != tab_count_){
+ clear_tab_positions();
+ if(nc) {
+ tab_positions_p = (int*)malloc((nc+1)*sizeof(int));
+ tab_positions_wp = (int*)malloc((nc+1)*sizeof(int));
+ }
+ tab_count_ = nc;
+ }
+ return nc;
+}
+
//
// End of "$Id$".
//
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev