On 08/05/13 07:45, MacArthur, Ian (Selex ES, UK) wrote:
>> You can, but it's non-trivial; unless I'm missing something obvious,
>> I think you'd have to subclass Fl_Tabs and overload the resize() method
>> to resize the children to keep the tab height constant.
>>
>> In other words, keep the children's y() a fixed distance from the tab's y().
>
> I seem to recall (and I might be making this up; I have not tried this prior
> to posting...) that if you put a group inside the tab area and make that
> explicitly resizable, that then makes the tab height "work" OK.
>
> Or; I might be misremembering...
Nice! That does seem to work. So basically:
tabs = new Fl_Tabs(..);
child_a = new Fl_Group(..);
child_b = new Fl_Group(..);
tabs->end();
tabs->resizable(child_a); // ADD THIS
Huh, this should be in the docs for Fl_Tabs, jeez.
Woulda saved me a bit of work (below).
I'll see about adding that doc mod,
along with others I mentioned earlier in this thread.
>> Having a way to keep the tab height constant is something the Fl_Tabs
>> widget really should have built into it but it doesn't. I've played
>> with adding such a feature today, and might check it in if there's
>> no other way to solve it.
>
> I'd be in favour of that anyway, I think!
Here's a patch.
But given the above works and seems functionally the same,
I think it's kinda moot.
The following adds a new method to Fl_Tabs called fixed_height_tabs(int)
which takes an integer pixel size for the tab height.
Positive values for tabs along the top,
negative value for tabs along the bottom.
So to have 25 pixel high tabs along the top: tabs->fixed_height_tabs(25);
And same for bottom tabs: tabs->fixed_height_tabs(-25);
When set, the children's y() and h() are managed automatically,
keeping the margin opposite the tabs constant.
$ svn diff FL/Fl_Tabs.H src/Fl_Tabs.cxx
Index: FL/Fl_Tabs.H
===================================================================
--- FL/Fl_Tabs.H (revision 9925)
+++ FL/Fl_Tabs.H (working copy)
@@ -98,6 +98,7 @@
Fl_Widget *push_;
int *tab_pos; // array of x-offsets of tabs per child + 1
int *tab_width; // array of widths of tabs per child + 1
+ int tabs_fixed_height;// fixed height of tabs (0=off)
int tab_count; // array size
int tab_positions(); // allocate and calculate tab positions
void clear_tab_positions();
@@ -109,6 +110,7 @@
public:
int handle(int);
+ void resize(int X,int Y,int W,int H);
Fl_Widget *value();
int value(Fl_Widget *);
/**
@@ -127,6 +129,8 @@
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);
+ void fixed_height_tabs(int val);
+ int fixed_height_tabs() const;
};
#endif
Index: src/Fl_Tabs.cxx
===================================================================
--- src/Fl_Tabs.cxx (revision 9925)
+++ src/Fl_Tabs.cxx (working copy)
@@ -101,6 +101,7 @@
// Returns full height, if children() = 0.
int Fl_Tabs::tab_height() {
if (children() == 0) return h();
+ if ( fixed_height_tabs() != 0 ) return fixed_height_tabs();
int H = h();
int H2 = y();
Fl_Widget*const* a = array();
@@ -549,6 +550,7 @@
tab_pos = 0;
tab_width = 0;
tab_count = 0;
+ tabs_fixed_height = 0;
}
Fl_Tabs::~Fl_Tabs() {
@@ -623,6 +625,63 @@
}
}
+/**
+ Enables fixed height for tabs, so that tabs remain a constant height when resized.
+
+ Positive values indicate the desired height of the tabs along the top in pixels.
+ Negative values indicate the desired height of the tabs along the bottom in pixels.
+ Zero value disables fixed height tabs (default behavior).
+ **/
+void Fl_Tabs::fixed_height_tabs(int val) {
+ tabs_fixed_height = val;
+ if ( val == 0 ) return;
+ resize(x(), y(), w(), h()); // apply settings to children
+ redraw();
+}
+
+/**
+ Returns the set by fixed_height_tabs(int).
+
+ A value of zero indicates fixed height tabs are disabled (default).
+ **/
+int Fl_Tabs::fixed_height_tabs() const {
+ return tabs_fixed_height;
+}
+
+void Fl_Tabs::resize(int X,int Y,int W,int H) {
+ int th = fixed_height_tabs();
+ if ( th != 0 && children()>0 ) {
+ // Save children's vertical margin opposite tabs
+ int *vmargins = (int*)malloc(children() * sizeof(int));
+ int t;
+ for ( t=0; t<children(); t++ ) {
+ Fl_Widget *o = child(t);
+ if ( th > 0 ) vmargins[t] = (y()+h()) - (o->y()+o->h()); // tabs on top
+ else vmargins[t] = o->y() - y(); // tabs on bottom
+ }
+ // Resize group. Children's y() and h() will be wrong for our needs.
+ Fl_Group::resize(X,Y,W,H);
+ // Now fix up children's y() and h()
+ for ( t=0; t<children(); t++ ) {
+ Fl_Widget *o = child(t);
+ if ( th > 0 )
+ o->resize(o->x(), // tabs on top
+ Y + th,
+ o->w(),
+ H - vmargins[t] - th);
+ else
+ o->resize(o->x(), // tabs on bottom
+ Y + vmargins[t],
+ o->w(),
+ H - vmargins[t] + th);
+ }
+ free((void*)vmargins);
+ init_sizes(); // we resized children
+ } else {
+ Fl_Group::resize(X,Y,W,H);
+ }
+}
+
//
// End of "$Id$".
//