From 93ea93ee2b424ded25358d87529b1160cdb4f80c Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Tue, 1 Nov 2022 13:30:05 +0100 Subject: [PATCH] Fluid support for Fl_Flex (#523) and some Fl_Flex improvements * Adding Fluid support for Fl_Flex, margins, and gap. * Fluid Fl_Flex mostly working. Fixed in Fl_Flex::set_size(). * Fluid Flex live mode works, interactive dragging works * Fluid Flex: adding check box for fixed children * Fluid Flex: visual flexibility indicator in guides. * Fluid Flex: bug in generated code. * Fix formatting * Fixing Tooltip, fixing resize issue PR #518. * Removing unused variables. Co-authored-by: Albrecht Schlosser --- fluid/Fl_Group_Type.cxx | 221 ++++++++++++++++++++++++++++++ fluid/Fl_Group_Type.h | 33 +++++ fluid/Fl_Type.h | 2 + fluid/Fl_Widget_Type.cxx | 280 +++++++++++++++++++++++++++++++++++++-- fluid/Fl_Window_Type.cxx | 56 +++++++- fluid/factory.cxx | 12 +- fluid/file.cxx | 1 + fluid/function_panel.cxx | 14 ++ fluid/function_panel.fl | 15 ++- fluid/pixmaps.cxx | 6 +- fluid/pixmaps.h | 1 + fluid/pixmaps/flFlex.xpm | 45 +++++++ fluid/widget_panel.cxx | 80 ++++++++++- fluid/widget_panel.fl | 67 +++++++++- fluid/widget_panel.h | 15 +++ src/Fl_Flex.cxx | 33 +++-- 16 files changed, 833 insertions(+), 48 deletions(-) create mode 100644 fluid/pixmaps/flFlex.xpm diff --git a/fluid/Fl_Group_Type.cxx b/fluid/Fl_Group_Type.cxx index eab62cb77..0ab8efcb0 100644 --- a/fluid/Fl_Group_Type.cxx +++ b/fluid/Fl_Group_Type.cxx @@ -34,6 +34,7 @@ #include "../src/flstring.h" #include +#include // Override group's resize behavior to do nothing to children: void igroup::resize(int X, int Y, int W, int H) { @@ -146,6 +147,226 @@ Fl_Menu_Item pack_type_menu[] = { Fl_Pack_Type Fl_Pack_type; // the "factory" +void Fl_Pack_Type::copy_properties() +{ + Fl_Group_Type::copy_properties(); + Fl_Pack *d = (Fl_Pack*)live_widget, *s =(Fl_Pack*)o; + d->spacing(s->spacing()); +} + +//////////////////////////////////////////////////////////////// + +const char flex_type_name[] = "Fl_Flex"; + +Fl_Menu_Item flex_type_menu[] = { + {"HORIZONTAL", 0, 0, (void*)Fl_Flex::HORIZONTAL}, + {"VERTICAL", 0, 0, (void*)Fl_Flex::VERTICAL}, + {0}}; + +Fl_Flex_Type Fl_Flex_type; // the "factory" + +Fl_Widget *Fl_Flex_Type::enter_live_mode(int) { + Fl_Flex *grp = new Fl_Flex(o->x(), o->y(), o->w(), o->h()); + live_widget = grp; + copy_properties(); + suspend_auto_layout = 1; + Fl_Type *n; + for (n = next; n && n->level > level; n = n->next) { + if (n->level == level+1) + n->enter_live_mode(); + } + suspend_auto_layout = 0; + Fl_Flex *d = grp, *s =(Fl_Flex*)o; + int nc = s->children(), nd = d->children(); + if (nc>nd) nc = nd; + for (int i=0; iset_size(s->child(i))) { + Fl_Widget *dc = d->child(i); + d->set_size(d->child(i), s->horizontal() ? dc->w() : dc->h()); + } + } + grp->end(); //this also updates the layout + return live_widget; +} + +void Fl_Flex_Type::copy_properties() +{ + Fl_Group_Type::copy_properties(); + Fl_Flex *d = (Fl_Flex*)live_widget, *s =(Fl_Flex*)o; + int lm, tm, rm, bm; + s->margins(&lm, &tm, &rm, &bm); + d->margin(lm, tm, rm, bm); + d->gap( s->gap() ); +} + +void Fl_Flex_Type::write_properties() +{ + Fl_Group_Type::write_properties(); + Fl_Flex* f = (Fl_Flex*)o; + int lm, tm, rm, bm; + f->margins(&lm, &tm, &rm, &bm); + if (lm!=0 || tm!=0 || rm!=0 || bm!=0) + write_string("margins {%d %d %d %d}", lm, tm, rm, bm); + if (f->gap()) + write_string("gap %d", f->gap()); + int nSet = 0; + for (int i=0; ichildren(); i++) + if (f->set_size(f->child(i))) + nSet++; + if (nSet) { + write_string("size_set {%d", nSet); + for (int i=0; ichildren(); i++) + if (f->set_size(f->child(i))) + write_string(" %d", i); + write_string("}"); + } +} + +void Fl_Flex_Type::read_property(const char *c) +{ + Fl_Flex* f = (Fl_Flex*)o; + suspend_auto_layout = 1; + if (!strcmp(c,"margins")) { + int lm, tm, rm, bm; + if (sscanf(read_word(),"%d %d %d %d",&lm,&tm,&rm,&bm) == 4) + f->margin(lm, tm, rm, bm); + } else if (!strcmp(c,"gap")) { + int g; + if (sscanf(read_word(),"%d",&g)) + f->gap(g); + } else if (!strcmp(c,"size_set")) { + read_word(1); // must be '{' + const char *nStr = read_word(1); // number of indices in table + fixedSizeTableSize = atoi(nStr); + fixedSizeTable = new int[fixedSizeTableSize]; + for (int i=0; i=0 && ixchildren()) { + Fl_Widget *ci = f->child(ix); + f->set_size(ci, f->horizontal()?ci->w():ci->h()); + } + } + fixedSizeTableSize = 0; + delete[] fixedSizeTable; + fixedSizeTable = NULL; + f->layout(); + suspend_auto_layout = 0; +} + +void Fl_Flex_Type::write_code2() { + const char *var = name() ? name() : "o"; + Fl_Flex* f = (Fl_Flex*)o; + int lm, tm, rm, bm; + f->margins(&lm, &tm, &rm, &bm); + if (lm!=0 || tm!=0 || rm!=0 || bm!=0) + write_c("%s%s->margin(%d, %d, %d, %d);\n", indent(), var, lm, tm, rm, bm); + if (f->gap()) + write_c("%s%s->gap(%d);\n", indent(), var, f->gap()); + for (int i=0; ichildren(); ++i) { + Fl_Widget *ci = f->child(i); + if (f->set_size(ci)) + write_c("%s%s->set_size(%s->child(%d), %d);\n", indent(), var, var, i, + f->horizontal() ? ci->w() : ci->h()); + } + Fl_Group_Type::write_code2(); +} + +void Fl_Flex_Type::add_child(Fl_Type* a, Fl_Type* b) { + Fl_Group_Type::add_child(a, b); + if (!suspend_auto_layout) + ((Fl_Flex*)o)->layout(); +} + +void Fl_Flex_Type::move_child(Fl_Type* a, Fl_Type* b) { + Fl_Group_Type::move_child(a, b); + if (!suspend_auto_layout) + ((Fl_Flex*)o)->layout(); +} + +void Fl_Flex_Type::remove_child(Fl_Type* a) { + if (a->is_widget()) + ((Fl_Flex*)o)->set_size(((Fl_Widget_Type*)a)->o, 0); + Fl_Group_Type::remove_child(a); + ((Fl_Flex*)o)->layout(); +} + +// Change from HORIZONTAL to VERTICAL or back. +// Children in a horizontal Flex have already the full vertical height. If we +// just change to vertical, the accumulated hight of all children is too big. +// We need to relayout existing children. +void Fl_Flex_Type::change_subtype_to(int n) { + Fl_Flex* f = (Fl_Flex*)o; + int nc = f->children(); + if (f->type()==n || nc==0) return; + + int dw = Fl::box_dw(f->box()); + int dh = Fl::box_dh(f->box()); + int lm, tm, rm, bm; + f->margins(&lm, &tm, &rm, &bm); + int gap = f->gap(); + int fw = f->w()-dw-lm-rm-(nc*gap); + if (fw<=nc) fw = nc; // avoid division by zero + int fh = f->h()-dh-tm-bm-(nc*gap); + if (fh<=nc) fh = nc; // avoid division by zero + + if (f->type()==Fl_Flex::HORIZONTAL && n==Fl_Flex::VERTICAL) { + float scl = (float)fh/(float)fw; + for (int i=0; ichild(i); + c->size(f->w(), (int)(c->w()*scl)); + } + } else if (f->type()==Fl_Flex::VERTICAL && n==Fl_Flex::HORIZONTAL) { + float scl = (float)fw/(float)fh; + for (int i=0; ichild(i); + c->size((int)(c->h()*scl), f->h()); + } + } + f->type(n); + f->layout(); +} + +int Fl_Flex_Type::parent_is_flex(Fl_Type *t) { + return (t->is_widget() + && t->parent + && t->parent->is_flex()); +} + +int Fl_Flex_Type::size(Fl_Type *t, char fixed_only) { + if (!t->is_widget()) return 0; + if (!t->parent) return 0; + if (!t->parent->is_flex()) return 0; + Fl_Flex_Type* ft = (Fl_Flex_Type*)t->parent; + Fl_Flex* f = (Fl_Flex*)ft->o; + Fl_Widget *w = ((Fl_Widget_Type*)t)->o; + if (fixed_only && !f->set_size(w)) return 0; + return f->horizontal() ? w->w() : w->h(); +} + +int Fl_Flex_Type::is_fixed(Fl_Type *t) { + if (!t->is_widget()) return 0; + if (!t->parent) return 0; + if (!t->parent->is_flex()) return 0; + Fl_Flex_Type* ft = (Fl_Flex_Type*)t->parent; + Fl_Flex* f = (Fl_Flex*)ft->o; + Fl_Widget *w = ((Fl_Widget_Type*)t)->o; + return f->set_size(w); +} + //////////////////////////////////////////////////////////////// static const int MAX_ROWS = 14; diff --git a/fluid/Fl_Group_Type.h b/fluid/Fl_Group_Type.h index 581f9ce3a..3d21a44b6 100644 --- a/fluid/Fl_Group_Type.h +++ b/fluid/Fl_Group_Type.h @@ -21,6 +21,7 @@ #include #include +#include #include void group_cb(Fl_Widget *, void *); @@ -82,6 +83,38 @@ public: void copy_properties(); }; +extern const char flex_type_name[]; +extern Fl_Menu_Item flex_type_menu[]; + +class Fl_Flex_Type : public Fl_Group_Type { + Fl_Menu_Item *subtypes() {return flex_type_menu;} + int fixedSizeTableSize; + int *fixedSizeTable; + int suspend_auto_layout; +public: + Fl_Flex_Type() : fixedSizeTableSize(0), fixedSizeTable(NULL), suspend_auto_layout(0) { } + virtual const char *type_name() {return flex_type_name;} + virtual const char *alt_type_name() {return "fltk::FlexGroup";} + Fl_Widget_Type *_make() { return new Fl_Flex_Type(); } + Fl_Widget *widget(int X,int Y,int W,int H) { + Fl_Flex *g = new Fl_Flex(X,Y,W,H); Fl_Group::current(0); return g;} + int pixmapID() { return 56; } + void write_properties(); + void read_property(const char *); + Fl_Widget *enter_live_mode(int top=0); + void copy_properties(); + void postprocess_read(); + void write_code2(); + void add_child(Fl_Type*, Fl_Type*); + void move_child(Fl_Type*, Fl_Type*); + void remove_child(Fl_Type*); + int is_flex() const {return 1;} + void change_subtype_to(int n); + static int parent_is_flex(Fl_Type*); + static int size(Fl_Type*, char fixed_only=0); + static int is_fixed(Fl_Type*); +}; + extern const char table_type_name[]; class Fl_Table_Type : public Fl_Group_Type { diff --git a/fluid/Fl_Type.h b/fluid/Fl_Type.h index 2fd82f546..3ba2c85e6 100644 --- a/fluid/Fl_Type.h +++ b/fluid/Fl_Type.h @@ -126,6 +126,7 @@ public: virtual void write_properties(); virtual void read_property(const char *); virtual int read_fdesign(const char*, const char*); + virtual void postprocess_read() { } // write code, these are called in order: virtual void write_static(); // write static stuff to .c file @@ -155,6 +156,7 @@ public: virtual int is_menu_item() const {return 0;} virtual int is_menu_button() const {return 0;} virtual int is_group() const {return 0;} + virtual int is_flex() const {return 0;} virtual int is_window() const {return 0;} virtual int is_code() const {return 0;} virtual int is_code_block() const {return 0;} diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx index 5a968c1f9..8a1c0c729 100644 --- a/fluid/Fl_Widget_Type.cxx +++ b/fluid/Fl_Widget_Type.cxx @@ -1614,8 +1614,7 @@ void textcolor_cb(Fl_Button* i, void* v) { void min_w_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { - if (!current_widget->is_window()) {i->parent()->hide(); return;} - i->parent()->show(); + if (!current_widget->is_window()) return; i->value(((Fl_Window_Type*)current_widget)->sr_min_w); } else { int mod = 0; @@ -1717,10 +1716,6 @@ void set_max_size_cb(Fl_Button*, void* v) { void slider_size_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { - if (current_widget->is_window()) - i->parent()->hide(); - else - i->parent()->show(); if (current_widget->is_valuator()<2) {i->deactivate(); return;} i->activate(); i->value(((Fl_Slider*)(current_widget->o))->slider_size()); @@ -1876,6 +1871,271 @@ void value_cb(Fl_Value_Input* i, void* v) { } } +// The following three callbacks cooperate, showing only one of the groups of +// widgets that use the same space in the dialog. + +void values_group_cb(Fl_Group* g, void* v) { + if (v == LOAD) { + if (current_widget->is_flex()) { + g->hide(); + } else if (current_widget->is_window()) { + g->hide(); + } else { + g->show(); + } + propagate_load(g, v); + } +} + +void flex_margin_group_cb(Fl_Group* g, void* v) { + if (v == LOAD) { + if (current_widget->is_flex()) { + g->show(); + } else { + g->hide(); + } + propagate_load(g, v); + } +} + +void size_range_group_cb(Fl_Group* g, void* v) { + if (v == LOAD) { + if (current_widget->is_window()) { + g->show(); + } else { + g->hide(); + } + propagate_load(g, v); + } +} + + +static void flex_margin_cb(Fl_Value_Input* i, void* v, + void (*load_margin)(Fl_Flex*,Fl_Value_Input*), + int (*update_margin)(Fl_Flex*,int)) { + if (v == LOAD) { + if (current_widget->is_flex()) { + load_margin((Fl_Flex*)current_widget->o, i); + } + } else { + int mod = 0; + int new_value = (int)i->value(); + for (Fl_Type *o = Fl_Type::first; o; o = o->next) { + if (o->selected && o->is_flex()) { + Fl_Flex_Type* q = (Fl_Flex_Type*)o; + Fl_Flex* w = (Fl_Flex*)q->o; + if (update_margin(w, new_value)) { + w->layout(); + mod = 1; + } + } + } + if (mod) set_modflag(1); + } +} + +static void load_left_margin(Fl_Flex *w, Fl_Value_Input* i) +{ + int v; + w->margins(&v, NULL, NULL, NULL); + i->value((double)v); +} + +static int update_left_margin(Fl_Flex *w, int new_value) +{ + int l, t, r, b; + w->margins(&l, &t, &r, &b); + if (new_value!=l) { + w->margin(new_value, t, r, b); + return 1; + } else { + return 0; + } +} + +void flex_margin_left_cb(Fl_Value_Input* i, void* v) { + flex_margin_cb(i, v, load_left_margin, update_left_margin); +} + +static void load_top_margin(Fl_Flex *w, Fl_Value_Input* i) +{ + int v; + w->margins(NULL, &v, NULL, NULL); + i->value((double)v); +} + +static int update_top_margin(Fl_Flex *w, int new_value) +{ + int l, t, r, b; + w->margins(&l, &t, &r, &b); + if (new_value!=t) { + w->margin(l, new_value, r, b); + return 1; + } else { + return 0; + } +} + +void flex_margin_top_cb(Fl_Value_Input* i, void* v) { + flex_margin_cb(i, v, load_top_margin, update_top_margin); +} + +static void load_right_margin(Fl_Flex *w, Fl_Value_Input* i) +{ + int v; + w->margins(NULL, NULL, &v, NULL); + i->value((double)v); +} + +static int update_right_margin(Fl_Flex *w, int new_value) +{ + int l, t, r, b; + w->margins(&l, &t, &r, &b); + if (new_value!=r) { + w->margin(l, t, new_value, b); + return 1; + } else { + return 0; + } +} + +void flex_margin_right_cb(Fl_Value_Input* i, void* v) { + flex_margin_cb(i, v, load_right_margin, update_right_margin); +} + +static void load_bottom_margin(Fl_Flex *w, Fl_Value_Input* i) +{ + int v; + w->margins(NULL, NULL, NULL, &v); + i->value((double)v); +} + +static int update_bottom_margin(Fl_Flex *w, int new_value) +{ + int l, t, r, b; + w->margins(&l, &t, &r, &b); + if (new_value!=b) { + w->margin(l, t, r, new_value); + return 1; + } else { + return 0; + } +} + +void flex_margin_bottom_cb(Fl_Value_Input* i, void* v) { + flex_margin_cb(i, v, load_bottom_margin, update_bottom_margin); +} + +static void load_gap(Fl_Flex *w, Fl_Value_Input* i) +{ + int v = w->gap(); + i->value((double)v); +} + +static int update_gap(Fl_Flex *w, int new_value) +{ + int g = w->gap(); + if (new_value!=g) { + w->gap(new_value); + return 1; + } else { + return 0; + } +} + +void flex_margin_gap_cb(Fl_Value_Input* i, void* v) { + flex_margin_cb(i, v, load_gap, update_gap); +} + +void position_group_cb(Fl_Group* g, void* v) { + if (v == LOAD) { + if (Fl_Flex_Type::parent_is_flex(current_widget)) { + g->hide(); + } else { + g->show(); + } + } + propagate_load(g, v); +} + +void flex_size_group_cb(Fl_Group* g, void* v) { + if (v == LOAD) { + if (Fl_Flex_Type::parent_is_flex(current_widget)) { + g->show(); + } else { + g->hide(); + } + } + propagate_load(g, v); +} + +void flex_size_cb(Fl_Value_Input* i, void* v) { + if (v == LOAD) { + if (Fl_Flex_Type::parent_is_flex(current_widget)) { + i->value(Fl_Flex_Type::size(current_widget)); + } + } else { + int mod = 0; + int new_size = (int)i->value(); + for (Fl_Type *o = Fl_Type::first; o; o = o->next) { + if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) { + Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o; + Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o; + int was_fixed = f->set_size(w); + if (new_size==0) { + if (was_fixed) { + f->set_size(w, 0); + f->layout(); + widget_flex_fixed->value(0); + mod = 1; + } + } else { + int old_size = Fl_Flex_Type::size(o); + if (old_size!=new_size || !was_fixed) { + f->set_size(w, new_size); + f->layout(); + widget_flex_fixed->value(1); + mod = 1; + } + } + } + } + if (mod) set_modflag(1); + } +} + +void flex_fixed_cb(Fl_Check_Button* i, void* v) { + if (v == LOAD) { + if (Fl_Flex_Type::parent_is_flex(current_widget)) { + i->value(Fl_Flex_Type::is_fixed(current_widget)); + } + } else { + int mod = 0; + int new_fixed = (int)i->value(); + for (Fl_Type *o = Fl_Type::first; o; o = o->next) { + if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) { + Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o; + Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o; + int was_fixed = f->set_size(w); + if (new_fixed==0) { + if (was_fixed) { + f->set_size(w, 0); + f->layout(); + mod = 1; + } + } else { + if (!was_fixed) { + f->set_size(w, Fl_Flex_Type::size(o)); + f->layout(); + mod = 1; + } + } + } + } + if (mod) set_modflag(1); + } +} + //////////////////////////////////////////////////////////////// // subtypes: @@ -1918,6 +2178,8 @@ void subtype_cb(Fl_Choice* i, void* v) { if (q->subtypes()==m) { if (q->is_spinner()) ((Fl_Spinner*)q->o)->type(n); + else if (q->is_flex()) + ((Fl_Flex_Type*)q)->change_subtype_to(n); else q->o->type(n); q->redraw(); @@ -3048,9 +3310,3 @@ void Fl_Widget_Type::copy_properties() { w->parent()->resizable(o); } -void Fl_Pack_Type::copy_properties() -{ - Fl_Group_Type::copy_properties(); - Fl_Pack *d = (Fl_Pack*)live_widget, *s =(Fl_Pack*)o; - d->spacing(s->spacing()); -} diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index b10da85b5..39a4c84b3 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -20,6 +20,7 @@ #include "Fl_Window_Type.h" +#include "Fl_Group_Type.h" #include "fluid.h" #include "widget_browser.h" #include "undo.h" @@ -54,10 +55,15 @@ inline int fl_min(int a, int b) { return (a < b ? a : b); } // Update the XYWH values in the widget panel... static void update_xywh() { if (current_widget && current_widget->is_widget()) { - widget_x_input->value(((Fl_Widget_Type *)current_widget)->o->x()); - widget_y_input->value(((Fl_Widget_Type *)current_widget)->o->y()); - widget_w_input->value(((Fl_Widget_Type *)current_widget)->o->w()); - widget_h_input->value(((Fl_Widget_Type *)current_widget)->o->h()); + Fl_Widget *o = ((Fl_Widget_Type *)current_widget)->o; + widget_x_input->value(o->x()); + widget_y_input->value(o->y()); + widget_w_input->value(o->w()); + widget_h_input->value(o->h()); + if (Fl_Flex_Type::parent_is_flex(current_widget)) { + widget_flex_size->value(Fl_Flex_Type::size(current_widget)); + widget_flex_fixed->value(Fl_Flex_Type::is_fixed(current_widget)); + } } } @@ -798,7 +804,28 @@ void Fl_Window_Type::draw_overlay() { Fl_Widget_Type* myo = (Fl_Widget_Type*)q; int x,y,r,t; newposition(myo,x,y,r,t); - if (!show_guides || !drag || numselected != 1) fl_rect(x,y,r-x,t-y); + if (!show_guides || !drag || numselected != 1) { + if (Fl_Flex_Type::parent_is_flex(q) && !Fl_Flex_Type::is_fixed(q)) { + if (((Fl_Flex*)((Fl_Flex_Type*)q->parent)->o)->horizontal()) { + int yh = y + (t-y)/2; + fl_begin_loop(); + fl_vertex(x+2, yh); fl_vertex(x+12, yh+5); fl_vertex(x+12, yh-5); + fl_end_loop(); + fl_begin_loop(); + fl_vertex(r-3, yh); fl_vertex(r-13, yh+5); fl_vertex(r-13, yh-5); + fl_end_loop(); + } else { + int xh = x + (r-x)/2; + fl_begin_loop(); + fl_vertex(xh, y+2); fl_vertex(xh+5, y+12); fl_vertex(xh-5, y+12); + fl_end_loop(); + fl_begin_loop(); + fl_vertex(xh, t-3); fl_vertex(xh+5, t-13); fl_vertex(xh-5, t-13); + fl_end_loop(); + } + } + fl_rect(x,y,r-x,t-y); + } if (x < mysx) mysx = x; if (y < mysy) mysy = y; if (r > mysr) mysr = r; @@ -1188,13 +1215,28 @@ void Fl_Window_Type::moveallchildren() for (i=next; i && i->level>level;) { if (i->selected && i->is_widget() && !i->is_menu_item()) { Fl_Widget_Type* myo = (Fl_Widget_Type*)i; - int x,y,r,t; + int x,y,r,t,ow=myo->o->w(),oh=myo->o->h(); newposition(myo,x,y,r,t); myo->o->resize(x,y,r-x,t-y); + if (Fl_Flex_Type::parent_is_flex(myo)) { + Fl_Flex_Type* ft = (Fl_Flex_Type*)myo->parent; + Fl_Flex* f = (Fl_Flex*)ft->o; + if (f->horizontal()) { + if (myo->o->w()!=ow) { + f->set_size(myo->o, myo->o->w()); + f->layout(); + } + } else { + if (myo->o->h()!=oh) { + f->set_size(myo->o, myo->o->h()); + f->layout(); + } + } + } // move all the children, whether selected or not: Fl_Type* p; for (p = myo->next; p && p->level>myo->level; p = p->next) - if (p->is_widget() && !p->is_menu_item()) { + if (p->is_widget() && !p->is_menu_item() && !myo->is_flex()) { Fl_Widget_Type* myo2 = (Fl_Widget_Type*)p; int X,Y,R,T; newposition(myo2,X,Y,R,T); diff --git a/fluid/factory.cxx b/fluid/factory.cxx index d3888c654..4cfa2404c 100644 --- a/fluid/factory.cxx +++ b/fluid/factory.cxx @@ -26,6 +26,7 @@ #include "fluid.h" #include "Fl_Window_Type.h" +#include "Fl_Group_Type.h" #include "pixmaps.h" #include "undo.h" @@ -35,6 +36,7 @@ #include #include #include +#include #include "../src/flstring.h" #include @@ -938,6 +940,7 @@ extern class Fl_Window_Type Fl_Window_type; extern class Fl_Widget_Class_Type Fl_Widget_Class_type; extern class Fl_Group_Type Fl_Group_type; extern class Fl_Pack_Type Fl_Pack_type; +extern class Fl_Flex_Type Fl_Flex_type; extern class Fl_Tabs_Type Fl_Tabs_type; extern class Fl_Scroll_Type Fl_Scroll_type; extern class Fl_Table_Type Fl_Table_type; @@ -976,6 +979,7 @@ static Fl_Type *known_types[] = { (Fl_Type*)&Fl_Window_type, (Fl_Type*)&Fl_Group_type, (Fl_Type*)&Fl_Pack_type, + (Fl_Type*)&Fl_Flex_type, (Fl_Type*)&Fl_Tabs_type, (Fl_Type*)&Fl_Scroll_type, (Fl_Type*)&Fl_Tile_type, @@ -1055,7 +1059,8 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { undo_suspend(); Fl_Type *t = ((Fl_Type*)inPrototype)->make(strategy); if (t) { - if (t->is_widget() && !t->is_window()) { + if (t->is_widget() && !t->is_window()) + { Fl_Widget_Type *wt = (Fl_Widget_Type *)t; // Set font sizes... @@ -1071,7 +1076,9 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { int w = 0, h = 0; wt->ideal_size(w, h); - if (!strcmp(wt->type_name(), "Fl_Menu_Bar")) { + if ((t->parent && t->parent->is_flex())) { + // Do not resize or layout the widget. Flex will need the widget size. + } else if (!strcmp(wt->type_name(), "Fl_Menu_Bar")) { // Move and resize the menubar across the top of the window... wt->o->resize(0, 0, w, h); } else { @@ -1143,6 +1150,7 @@ Fl_Menu_Item New_Menu[] = { {0,0,cb,(void*)&Fl_Window_type}, {0,0,cb,(void*)&Fl_Group_type}, {0,0,cb,(void*)&Fl_Pack_type}, + {0,0,cb,(void*)&Fl_Flex_type}, {0,0,cb,(void*)&Fl_Tabs_type}, {0,0,cb,(void*)&Fl_Scroll_type}, {0,0,cb,(void*)&Fl_Tile_type}, diff --git a/fluid/file.cxx b/fluid/file.cxx index 39768ea2e..fb91a2613 100644 --- a/fluid/file.cxx +++ b/fluid/file.cxx @@ -624,6 +624,7 @@ static void read_children(Fl_Type *p, int paste, Strategy strategy, char skip_op goto REUSE_C; } read_children(t, 0, strategy, skip_options); + t->postprocess_read(); } Fl_Type::current = p; diff --git a/fluid/function_panel.cxx b/fluid/function_panel.cxx index 8e28df2ad..b43ec8056 100644 --- a/fluid/function_panel.cxx +++ b/fluid/function_panel.cxx @@ -856,6 +856,20 @@ Fl_Window* make_widgetbin() { o->when(FL_WHEN_RELEASE); o->image(pixmap[19]); } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(139, 46, 24, 24); + o->tooltip("Flex"); + o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); + o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Flex")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); + o->image(pixmap[56]); + } // Widget_Bin_Button* o { Widget_Bin_Button* o = new Widget_Bin_Button(89, 71, 24, 24); o->tooltip("Tile"); o->box(FL_THIN_UP_BOX); diff --git a/fluid/function_panel.fl b/fluid/function_panel.fl index 0186b9365..f096d323a 100644 --- a/fluid/function_panel.fl +++ b/fluid/function_panel.fl @@ -50,7 +50,7 @@ Function {use_tab_navigation(int, Fl_Text_Editor*)} { Function {make_function_panel()} {open } { Fl_Window function_panel { - label {Function/Method Properties} open + label {Function/Method Properties} xywh {540 418 343 232} type Double hide resizable modal } { Fl_Group {} {open @@ -537,15 +537,15 @@ else add_new_widget_from_user(type_name, kAddAfterCurrent);} {} } -Function {make_widgetbin()} {open selected +Function {make_widgetbin()} {open } { Fl_Window widgetbin_panel { label {Widget Bin} callback {if (Fl::event()==FL_SHORTCUT && Fl::event_key()==FL_Escape) exit_cb((Fl_Widget*)o, v); else - toggle_widgetbin_cb((Fl_Widget*)o, v);} - xywh {449 206 600 102} type Single align 80 hide non_modal + toggle_widgetbin_cb((Fl_Widget*)o, v);} open + xywh {449 206 600 102} type Single align 80 non_modal visible } { Fl_Group {} { label Code open @@ -645,6 +645,13 @@ else code0 {o->image(pixmap[19]);} class Widget_Bin_Button } + Fl_Button {} { + user_data {"Fl_Flex"} + callback type_make_cb selected + tooltip Flex xywh {139 46 24 24} box THIN_UP_BOX + code0 {o->image(pixmap[56]);} + class Widget_Bin_Button + } Fl_Button {} { user_data {"Fl_Tile"} callback type_make_cb diff --git a/fluid/pixmaps.cxx b/fluid/pixmaps.cxx index 58e887999..b79314e36 100644 --- a/fluid/pixmaps.cxx +++ b/fluid/pixmaps.cxx @@ -77,6 +77,7 @@ #include "pixmaps/flInputChoice.xpm" #include "pixmaps/flCheckMenuitem.xpm" #include "pixmaps/flRadioMenuitem.xpm" +#include "pixmaps/flFlex.xpm" Fl_Pixmap *lock_pixmap; Fl_Pixmap *protected_pixmap; @@ -137,8 +138,9 @@ Fl_Pixmap *simple_terminal_pixmap; Fl_Pixmap *input_choice_pixmap; Fl_Pixmap *check_menuitem_pixmap; Fl_Pixmap *radio_menuitem_pixmap; +Fl_Pixmap *flex_pixmap; -Fl_Pixmap *pixmap[56]; +Fl_Pixmap *pixmap[57]; void loadPixmaps() { @@ -211,5 +213,7 @@ void loadPixmaps() pixmap[53] = input_choice_pixmap = new Fl_Pixmap(flInputChoice_xpm); input_choice_pixmap->scale(16, 16); pixmap[54] = check_menuitem_pixmap = new Fl_Pixmap(flCheckMenuitem_xpm); check_menuitem_pixmap->scale(16, 16); pixmap[55] = radio_menuitem_pixmap = new Fl_Pixmap(flRadioMenuitem_xpm); radio_menuitem_pixmap->scale(16, 16); + + pixmap[56] = flex_pixmap = new Fl_Pixmap(flFlex_xpm); flex_pixmap->scale(16, 16); } diff --git a/fluid/pixmaps.h b/fluid/pixmaps.h index fc23a0775..29bb1667e 100644 --- a/fluid/pixmaps.h +++ b/fluid/pixmaps.h @@ -75,6 +75,7 @@ extern Fl_Pixmap *data_pixmap; extern Fl_Pixmap *tree_pixmap; extern Fl_Pixmap *table_pixmap; extern Fl_Pixmap *simple_terminal_pixmap; +extern Fl_Pixmap *flex_pixmap; extern Fl_Pixmap *pixmap[]; diff --git a/fluid/pixmaps/flFlex.xpm b/fluid/pixmaps/flFlex.xpm new file mode 100644 index 000000000..f815663d7 --- /dev/null +++ b/fluid/pixmaps/flFlex.xpm @@ -0,0 +1,45 @@ +/* XPM */ +static const char * const flFlex_xpm[] = { +/* width height ncolors chars_per_pixel */ +"32 32 6 1", +/* colors */ +"a c #606060", +"b c #2020ff", +"c c none", +"d c #999999", +"e c #8080ff", +"f c #000000", +/* pixels */ +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"ffffffffffffffffffffffffffffffcc", +"ffffffffffffffffffffffffffffffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffffffffffffffffffffffffffffffcc", +"ffffffffffffffffffffffffffffffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffffffffffffffffffffffffffffffcc", +"ffffffffffffffffffffffffffffffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffddddddddddddddddddddddddddffcc", +"ffffffffffffffffffffffffffffffcc", +"ffffffffffffffffffffffffffffffcc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc" +}; diff --git a/fluid/widget_panel.cxx b/fluid/widget_panel.cxx index 892fcf14b..c42359ea9 100644 --- a/fluid/widget_panel.cxx +++ b/fluid/widget_panel.cxx @@ -60,6 +60,10 @@ Fluid_Coord_Input *widget_w_input=(Fluid_Coord_Input *)0; Fluid_Coord_Input *widget_h_input=(Fluid_Coord_Input *)0; +Fl_Value_Input *widget_flex_size=(Fl_Value_Input *)0; + +Fl_Check_Button *widget_flex_fixed=(Fl_Check_Button *)0; + Fl_Menu_Item menu_2[] = { {"private", 0, 0, (void*)(0), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, {"public", 0, 0, (void*)(1), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, @@ -260,8 +264,9 @@ Fl_Double_Window* make_widget_panel() { { Fl_Group* o = new Fl_Group(95, 150, 314, 20, "Position:"); o->labelfont(1); o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); + o->callback((Fl_Callback*)position_group_cb); o->align(Fl_Align(FL_ALIGN_LEFT)); + o->hide(); { widget_x_input = new Fluid_Coord_Input(95, 150, 55, 20, "X:"); widget_x_input->tooltip("The X position of the widget."); widget_x_input->box(FL_DOWN_BOX); @@ -329,10 +334,33 @@ ive to the origin at construction time"); } // Fl_Box* o o->end(); } // Fl_Group* o + { Fl_Group* o = new Fl_Group(95, 150, 314, 20, "Flex Parent:"); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)flex_size_group_cb); + o->align(Fl_Align(FL_ALIGN_LEFT)); + { widget_flex_size = new Fl_Value_Input(95, 150, 55, 20, "Size:"); + widget_flex_size->tooltip("Fixed Width or Height for a horizontal or vertical Fl_Flex Parent."); + widget_flex_size->labelsize(11); + widget_flex_size->textsize(11); + widget_flex_size->callback((Fl_Callback*)flex_size_cb); + widget_flex_size->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + } // Fl_Value_Input* widget_flex_size + { widget_flex_fixed = new Fl_Check_Button(155, 150, 55, 20, "fixed"); + widget_flex_fixed->tooltip("If checked, the size of the widget stays fixed."); + widget_flex_fixed->down_box(FL_DOWN_BOX); + widget_flex_fixed->labelsize(11); + widget_flex_fixed->callback((Fl_Callback*)flex_fixed_cb); + } // Fl_Check_Button* widget_flex_fixed + { Fl_Box* o = new Fl_Box(398, 150, 1, 20); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o { Fl_Group* o = new Fl_Group(95, 185, 300, 20, "Values:"); o->labelfont(1); o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); + o->callback((Fl_Callback*)values_group_cb); o->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Value_Input* o = new Fl_Value_Input(95, 185, 55, 20, "Size:"); o->tooltip("The size of the slider."); @@ -375,10 +403,56 @@ ive to the origin at construction time"); } // Fl_Box* o o->end(); } // Fl_Group* o + { Fl_Group* o = new Fl_Group(95, 185, 300, 20, "Margins:"); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)flex_margin_group_cb); + o->align(Fl_Align(FL_ALIGN_LEFT)); + o->hide(); + { Fl_Value_Input* o = new Fl_Value_Input(95, 185, 55, 20, "Left:"); + o->tooltip("Left margin in group."); + o->labelsize(11); + o->textsize(11); + o->callback((Fl_Callback*)flex_margin_left_cb); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + } // Fl_Value_Input* o + { Fl_Value_Input* o = new Fl_Value_Input(155, 185, 55, 20, "Top:"); + o->tooltip("Top margin in group."); + o->labelsize(11); + o->textsize(11); + o->callback((Fl_Callback*)flex_margin_top_cb); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + } // Fl_Value_Input* o + { Fl_Value_Input* o = new Fl_Value_Input(215, 185, 55, 20, "Right:"); + o->tooltip("Right margin in group."); + o->labelsize(11); + o->textsize(11); + o->callback((Fl_Callback*)flex_margin_right_cb); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + } // Fl_Value_Input* o + { Fl_Value_Input* o = new Fl_Value_Input(275, 185, 55, 20, "Bottom:"); + o->tooltip("Bottom margin in group."); + o->labelsize(11); + o->textsize(11); + o->callback((Fl_Callback*)flex_margin_bottom_cb); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + } // Fl_Value_Input* o + { Fl_Value_Input* o = new Fl_Value_Input(335, 185, 55, 20, "Gap:"); + o->tooltip("Gap between children."); + o->labelsize(11); + o->textsize(11); + o->callback((Fl_Callback*)flex_margin_gap_cb); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + } // Fl_Value_Input* o + { Fl_Box* o = new Fl_Box(395, 185, 0, 20); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o { Fl_Group* o = new Fl_Group(95, 185, 300, 20, "Size Range:"); o->labelfont(1); o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); + o->callback((Fl_Callback*)size_range_group_cb); o->align(Fl_Align(FL_ALIGN_LEFT)); o->hide(); { Fl_Value_Input* o = new Fl_Value_Input(95, 185, 55, 20, "Minimum Size:"); diff --git a/fluid/widget_panel.fl b/fluid/widget_panel.fl index 1f0b3b2ad..de82b3871 100644 --- a/fluid/widget_panel.fl +++ b/fluid/widget_panel.fl @@ -23,7 +23,7 @@ comment {// decl {\#include "Fl_Widget_Type.h"} {private global } -decl {\#include "Shortcut_Button.h"} {selected public global +decl {\#include "Shortcut_Button.h"} {public global } Function {make_widget_panel()} { @@ -31,8 +31,8 @@ Function {make_widget_panel()} { } { Fl_Window {} { comment {Use a Double Window to avoid flickering.} open - xywh {500 209 420 400} type Double labelsize 11 align 80 hide resizable hotspot - code0 {o->size_range(o->w(), o->h());} size_range {420 400 0 0} + xywh {500 209 420 400} type Double labelsize 11 align 80 resizable hotspot + code0 {o->size_range(o->w(), o->h());} size_range {420 400 0 0} visible } { Fl_Tabs {} { callback {propagate_load((Fl_Group *)o,v);} open @@ -258,8 +258,8 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 1 te } Fl_Group {} { label {Position:} - callback propagate_load open - xywh {95 150 314 20} labelfont 1 labelsize 11 align 4 + callback position_group_cb open + xywh {95 150 314 20} labelfont 1 labelsize 11 align 4 hide } { Fl_Input widget_x_input { label {X:} @@ -294,9 +294,28 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 1 te xywh {398 150 1 20} resizable } } + Fl_Group {} { + label {Flex Parent:} + callback flex_size_group_cb open + xywh {95 150 314 20} labelfont 1 labelsize 11 align 4 + } { + Fl_Value_Input widget_flex_size { + label {Size:} + callback flex_size_cb + tooltip {Fixed Width or Height for a horizontal or vertical Fl_Flex Parent.} xywh {95 150 55 20} labelsize 11 align 5 textsize 11 + } + Fl_Check_Button widget_flex_fixed { + label fixed + callback flex_fixed_cb selected + tooltip {If checked, the size of the widget stays fixed.} xywh {155 150 55 20} down_box DOWN_BOX labelsize 11 + } + Fl_Box {} { + xywh {398 150 1 20} resizable + } + } Fl_Group {} { label {Values:} - callback propagate_load + callback values_group_cb open xywh {95 185 300 20} labelfont 1 labelsize 11 align 4 } { Fl_Value_Input {} { @@ -328,9 +347,43 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 1 te xywh {395 185 0 20} resizable } } + Fl_Group {} { + label {Margins:} + callback flex_margin_group_cb open + xywh {95 185 300 20} labelfont 1 labelsize 11 align 4 hide + } { + Fl_Value_Input {} { + label {Left:} + callback flex_margin_left_cb + tooltip {Left margin in group.} xywh {95 185 55 20} labelsize 11 align 5 textsize 11 + } + Fl_Value_Input {} { + label {Top:} + callback flex_margin_top_cb + tooltip {Top margin in group.} xywh {155 185 55 20} labelsize 11 align 5 textsize 11 + } + Fl_Value_Input {} { + label {Right:} + callback flex_margin_right_cb + tooltip {Right margin in group.} xywh {215 185 55 20} labelsize 11 align 5 textsize 11 + } + Fl_Value_Input {} { + label {Bottom:} + callback flex_margin_bottom_cb + tooltip {Bottom margin in group.} xywh {275 185 55 20} labelsize 11 align 5 textsize 11 + } + Fl_Value_Input {} { + label {Gap:} + callback flex_margin_gap_cb + tooltip {Gap between children.} xywh {335 185 55 20} labelsize 11 align 5 textsize 11 + } + Fl_Box {} { + xywh {395 185 0 20} resizable + } + } Fl_Group {} { label {Size Range:} - callback propagate_load + callback size_range_group_cb open xywh {95 185 300 20} labelfont 1 labelsize 11 align 4 hide } { Fl_Value_Input {} { diff --git a/fluid/widget_panel.h b/fluid/widget_panel.h index 283b27a3d..8e3b18efe 100644 --- a/fluid/widget_panel.h +++ b/fluid/widget_panel.h @@ -38,6 +38,7 @@ extern void align_cb(Fl_Button*, void*); extern void align_text_image_cb(Fl_Choice*, void*); extern void align_position_cb(Fl_Choice*, void*); #include +extern void position_group_cb(Fl_Group*, void*); extern void x_cb(Fluid_Coord_Input*, void*); extern Fluid_Coord_Input *widget_x_input; extern void y_cb(Fluid_Coord_Input*, void*); @@ -48,12 +49,26 @@ extern void h_cb(Fluid_Coord_Input*, void*); extern Fluid_Coord_Input *widget_h_input; #include extern void wc_relative_cb(Fl_Light_Button*, void*); +extern void flex_size_group_cb(Fl_Group*, void*); #include +extern void flex_size_cb(Fl_Value_Input*, void*); +extern Fl_Value_Input *widget_flex_size; +#include +extern void flex_fixed_cb(Fl_Check_Button*, void*); +extern Fl_Check_Button *widget_flex_fixed; +extern void values_group_cb(Fl_Group*, void*); extern void slider_size_cb(Fl_Value_Input*, void*); extern void min_cb(Fl_Value_Input*, void*); extern void max_cb(Fl_Value_Input*, void*); extern void step_cb(Fl_Value_Input*, void*); extern void value_cb(Fl_Value_Input*, void*); +extern void flex_margin_group_cb(Fl_Group*, void*); +extern void flex_margin_left_cb(Fl_Value_Input*, void*); +extern void flex_margin_top_cb(Fl_Value_Input*, void*); +extern void flex_margin_right_cb(Fl_Value_Input*, void*); +extern void flex_margin_bottom_cb(Fl_Value_Input*, void*); +extern void flex_margin_gap_cb(Fl_Value_Input*, void*); +extern void size_range_group_cb(Fl_Group*, void*); extern void min_w_cb(Fl_Value_Input*, void*); extern void min_h_cb(Fl_Value_Input*, void*); extern void set_min_size_cb(Fl_Button*, void*); diff --git a/src/Fl_Flex.cxx b/src/Fl_Flex.cxx index 028c08d1f..74e9ed13d 100644 --- a/src/Fl_Flex.cxx +++ b/src/Fl_Flex.cxx @@ -236,41 +236,50 @@ void Fl_Flex::end() { If \p size is 0 (zero) or negative the widget size is reset to flexible size. - \param[in] w widget to be affected + \param[in] child widget to be affected \param[in] size width (Fl_Flex::HORIZONTAL) or height (Fl_Flex::VERTICAL) */ -void Fl_Flex::set_size(Fl_Widget *w, int size) { +void Fl_Flex::set_size(Fl_Widget *child, int size) { if (size <= 0) size = 0; - w->resize(0, 0, size, size); + // find w in our fixed size list int idx = -1; for (int i = 0; i < set_size_size_; i++) { - if (set_size_[i] == w) { + if (set_size_[i] == child) { idx = i; break; } } - // remove from array ? + // remove from array, if we want the widget to be flexible, but an entry was found if (size == 0 && idx >= 0) { - for (int i = idx; i < set_size_size_ - 2; i++) { + for (int i = idx; i < set_size_size_ - 1; i++) { set_size_[i] = set_size_[i+1]; } set_size_size_--; return; } + // if w is meant to be flexible, we are done now if (size == 0) return; - // add to array of fixed size widgets - if (set_size_size_ == set_size_alloc_) { - set_size_alloc_ = alloc_size(set_size_alloc_); - set_size_ = (Fl_Widget **)realloc(set_size_, set_size_alloc_ * sizeof(Fl_Widget *)); + // if we have no entry yet, add to array of fixed size widgets + if (idx == -1) { + if (set_size_size_ == set_size_alloc_) { + set_size_alloc_ = alloc_size(set_size_alloc_); + set_size_ = (Fl_Widget **)realloc(set_size_, set_size_alloc_ * sizeof(Fl_Widget *)); + } + set_size_[set_size_size_] = child; + set_size_size_++; } - set_size_[set_size_size_] = w; - set_size_size_++; + + // if the child size is meant to be fixed, set its new size + if (horizontal()) + child->size(size, h()-margin_top_-margin_bottom_-Fl::box_dh(box())); + else + child->size(w()-margin_left_-margin_right_-Fl::box_dw(box()), size); } /**