resizable question

38 views
Skip to first unread message

Greg Ercolano

unread,
Nov 20, 2020, 4:12:27 PM11/20/20
to fltkg...@googlegroups.com
Is there a way to use FLTK's resize abilities to do this:

 ________________    _________    ________________
|                |  |         |  |                |
|     Box A      |  |  Box B  |  |     Box C      |
|________________|  |_________|  |________________|


The goal is to have boxes A and C horizontally stretch to fit the window during resizing,
and Box B remains a fixed width and centered.

I've thought about this a bit and can't think of a way to do it other than to overload resize()
and do it with code, but would like to use FLTK's resizing abilities if it's possible.

Ian MacArthur

unread,
Nov 20, 2020, 5:41:39 PM11/20/20
to fltkg...@googlegroups.com
Hi Greg,

Without actually writing any code to test this (and you have probably considered this already anyway...) my gut reaction is to put A and B into a group, and make A the resizable of that group...
That would then “fix” the width of B (I think) and allow A and C to resize. Though I do not think they would resize evenly... Hmm... I might have to write some code now, after all...


Ian MacArthur

unread,
Nov 20, 2020, 5:59:24 PM11/20/20
to fltkg...@googlegroups.com
Hmm, yeah, that kinda works.
As I suspected, A and C scale slightly differently in width, but overall it is no too heinous... Dunno...
Code follows:

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Box.H>

static Fl_Double_Window *main_win=(Fl_Double_Window *)0;
static Fl_Group *ab_grp=(Fl_Group *)0;
static Fl_Box *box_a=(Fl_Box *)0;
static Fl_Box *box_b=(Fl_Box *)0;
static Fl_Box *box_c=(Fl_Box *)0;

int main(int argc, char **argv)
{
main_win = new Fl_Double_Window(492, 137, "Resize Test");
main_win->begin();

ab_grp = new Fl_Group(25, 24, 245, 37);
ab_grp->begin();
box_a = new Fl_Box(25, 24, 165, 37, "A");
box_a->box(FL_BORDER_BOX);

box_b = new Fl_Box(195, 24, 70, 37, "B");
box_b->box(FL_BORDER_BOX);

ab_grp->end();
ab_grp->resizable(box_a);

box_c = new Fl_Box(270, 24, 170, 37, "C");
box_c->box(FL_BORDER_BOX);

main_win->end();
main_win->resizable(main_win);
main_win->show(argc, argv);

return Fl::run();
}

// end of file //





Albrecht Schlosser

unread,
Nov 20, 2020, 6:02:19 PM11/20/20
to fltkg...@googlegroups.com
On 11/20/20 11:41 PM Ian MacArthur wrote:
>
>
>> On 20 Nov 2020, at 21:12, Greg Ercolano wrote:
>>
>> Is there a way to use FLTK's resize abilities to do this:
>>
>> ________________ _________ ________________
>> | | | | | |
>> | Box A | | Box B | | Box C |
>> |________________| |_________| |________________|
>>
>> The goal is to have boxes A and C horizontally stretch to fit the window during resizing,
>> and Box B remains a fixed width and centered.
>>
>> I've thought about this a bit and can't think of a way to do it other than to overload resize()
>> and do it with code, but would like to use FLTK's resizing abilities if it's possible.

My first thought was that there's no way but maybe ...

> ... my gut reaction is to put A and B into a group, and make A the resizable of that group...
> That would then “fix” the width of B (I think) and allow A and C to resize. Though I do not think they would resize evenly... Hmm... I might have to write some code now, after all...

Thinking model this further ...

If you put A and B in a group D as Ian suggested (with A being the
resizable of group D) you obviously need (i.e. you already have) a group
sourrounding D + C, let's say group G.

If you make one of these (D or C) the resizable of G only one of them
can resize. But what if you add another invisible box E to G that
overlaps both groups D and C? That would for sure make D and C resize
and A would resize together with D (B would still be fixed width).

The question I can't answer off the top of my head is whether D and C
would resize evenly. If they did, then A and C would resize evenly as well.

Albrecht Schlosser

unread,
Nov 20, 2020, 6:22:41 PM11/20/20
to fltkg...@googlegroups.com
On 11/21/20 12:02 AM Albrecht Schlosser wrote:
>
> Thinking this model this further ...
>
> If you put A and B in a group D as Ian suggested (with A being the
> resizable of group D) you obviously need (i.e. you already have) a group
> sourrounding D + C, let's say group G.
>
> If you make one of these (D or C) the resizable of G only one of them
> can resize. But what if you add another invisible box E to G that
> overlaps both groups D and C? That would for sure make D and C resize
> and A would resize together with D (B would still be fixed width).
>
> The question I can't answer off the top of my head is whether D and C
> would resize evenly. If they did, then A and C would resize evenly as well.

I started with Ian's code and tried my idea but it doesn't seem to work
as requested. Maybe the position and size of this invisible box (box_i)
can be changed to get the correct relations but I don't know. Would need
to look into the resizing code to see how the relations are calculated
(but not tonight).

See attached file r.cxx.
r.cxx

Greg Ercolano

unread,
Nov 20, 2020, 7:10:49 PM11/20/20
to fltkg...@googlegroups.com
On 2020-11-20 14:59, Ian MacArthur wrote:
>
>>> ________________ _________ ________________
>>> | | | | | |
>>> | Box A | | Box B | | Box C |
>>> |________________| |_________| |________________|
>>>
>>> [..] my gut reaction is to put A and B into a group, and make A the resizable of that group...
>>> That would then “fix” the width of B (I think) and allow A and C to resize. Though I do not think
>>> they would resize evenly...

    Ya, that's the problem to solve; the bit about resizing symmetrically..

    I just can't think of a way to do it.. perhaps it can't be.

    I was trying to think of a simple Fl_Group derived class that could fill this need,  but it's not clear to me how to keep it "simple".

    I could see making a fully flexible packing widget like an HTML table,  where widgets (like table cells) can have width and height specified as either a percentage, pixel width, or unspecified (for auto-scaling), and alignment flags for left/center/right and top/middle/bottom.


Greg Ercolano

unread,
Nov 20, 2020, 7:21:20 PM11/20/20
to fltkg...@googlegroups.com
On 2020-11-20 14:59, Ian MacArthur wrote:
[..]

   Thanks for the example BTW.
    I did play with it for a bit to see if I could fix the resizing, but couldn't keep things symmetrical.


On 2020-11-20 16:10, Greg Ercolano wrote:
I could see making a fully flexible packing widget like an HTML table..


    I should probably review this TableBox widget in our Links pages, which sounds like it's exactly that:


TableBox

The TableBox manages a group of widgets that are arranged in rows and columns, making it easy to align many widgets next to each other, horizontally and vertically. The size of a table can be changed using the Size() method. Widgets can be added to a table using the Attach() method. The gaps between all rows or columns can be changed by calling the Gap() method.

Supports both row and column expanding, filling, spanning and aligning in both X and Y directions. The whole project was inspired by HTML table and GTK+ table widget.



Greg Ercolano

unread,
Nov 20, 2020, 7:29:53 PM11/20/20
to fltkg...@googlegroups.com
On 2020-11-20 15:22, Albrecht Schlosser wrote:
>
> I started with Ian's code and tried my idea but it doesn't seem to work
> as requested. Maybe the position and size of this invisible box (box_i)
> can be changed to get the correct relations but I don't know. Would need
> to look into the resizing code to see how the relations are calculated
> (but not tonight).
>
> See attached file r.cxx.

    Thanks -- yes, I just don't think it's possible to keep B centered doing any of the resizable
    tricks we're normally used to.

    I could change the layout of the app, but it makes sense to keep B in the middle and of
    fixed size.

Albrecht Schlosser

unread,
Nov 20, 2020, 8:31:49 PM11/20/20
to fltkg...@googlegroups.com
On 11/21/20 1:29 AM Greg Ercolano wrote:
> On 2020-11-20 15:22, Albrecht Schlosser wrote:
>>
>> I started with Ian's code and tried my idea but it doesn't seem to work
>> as requested. Maybe the position and size of this invisible box (box_i)
>> can be changed to get the correct relations but I don't know. Would need
>> to look into the resizing code to see how the relations are calculated
>> (but not tonight).

I couldn't resist and did it...
;-
>> See attached file r.cxx.
>
>     Thanks -- yes, I just don't think it's possible to keep B centered doing any of the resizable
>     tricks we're normally used to.

Well, it *is* possible! :-)

See attached new version of 'r.cxx'. Running it and resizing makes the
layout look familiar - like test/cube.cxx which I know was the reason
you asked. ;-)

The "secret" (revealed by a little math and the code in
Fl_Group::resize()) is to put the invisible box centered over the border
between the two boxes B and C. As long as the overlap is equal on both
sides the two boxes (ab_grp and box_c) resize by the same amount and
therefore A and C resize symmetrically.

For simplicity I made all the boxes adjacent with widths 200, 100, 200,
resp. and put the invisible box on x = 250 with width = 100 (50 left of
the border and 50 right of the border). That's it!
r.cxx

duncan

unread,
Nov 20, 2020, 8:49:16 PM11/20/20
to fltk.general
I did wonder if you could achieve the desired visible effect with overlapping groups,
ignoring potential problems with input and focus, but I don't think it can be done with
the current proportional resizing based on a single resizable widget per group. The
fact that boxB is not resizable means that scaling of the other widgets is not linear.

You could
a. derive your own group class and override the redraw/resize to adjust positions/sizes
b. derive your own group class and provide a second resizable that takes an array/list
c. derive your own group class and provide a "nonresizable()" method that does (a)

D.
resize.cxx

duncan

unread,
Nov 20, 2020, 9:14:54 PM11/20/20
to fltk.general
Nice. It even works if you increase the width of the window and the width of box C.
It's the combination of width of B and starting at the middle of B that does it.
I'd thought of two groups meeting at the middle of B, but foresaw dragons

That'll teach me to make sweeping statements way past my bedtime :-)

D.

Albrecht Schlosser

unread,
Nov 20, 2020, 9:41:33 PM11/20/20
to fltkg...@googlegroups.com
On 11/21/20 3:14 AM duncan wrote:
> Nice. It even works if you increase the width of the window and the
> width of box C.
> It's the combination of width of B and starting at the middle of B that
> does it.

Well, yes, that does it. I apologize if the following sounds like
nitpicking, but to make sure the mechanics are clear:

It has nothing to do with the width of B and the width of the invisible
box (if that's what you meant): they are not related. The condition that
must be met is that the invisible box is centered over the border
between B and C. That's all.

You'll see this if you replace the relevant code of my 2nd version with
this:


int d = 1;
box_i = new Fl_Box(300-d, 24, 2*d, 37, ""); // invisible box
box_i->box(FL_NO_BOX);
main_win->resizable(box_i);

where X = 300 - d and W = 2 * d to center it between B and C (at 300).
You can vary d in a sensible range (1 - 200) but something goes awry if
you make it larger than 200 because it crosses the window borders.

Greg Ercolano

unread,
Nov 21, 2020, 3:24:54 AM11/21/20
to fltk.general
Holy crap, cool! Thanks Albrecht, I'll have to look closely at what you did, it's the end of day here, but I just compiled this and it seems to work fine.

This'll help with issue #157, as I didn't like the patch because I was using a procedural resize(). I'll be sure to credit this technique to you in the comments. This technique should be woven into the resizable() article, I'll see if I can do that too, unless you want to. Don't want to loose this valuable info..

duncan

unread,
Nov 21, 2020, 5:10:44 AM11/21/20
to fltk.general
I played around with your example and found it still worked if I increased
the width of the window and box C so that A and C are not symmetrical,
but once you introduce padding between the boxes, things go a bit awry.

See the attached, where I've also moved/coloured box I to make it visible.
The fix might be obvious to you if you've been looking at the resize code.

D.
r2.cxx

Albrecht Schlosser

unread,
Nov 21, 2020, 5:17:30 AM11/21/20
to fltkg...@googlegroups.com
On 11/21/20 9:24 AM Greg Ercolano wrote:
> Holy crap, cool! Thanks Albrecht, I'll have to look closely at what you
> did, it's the end of day here, but I just compiled this and it seems to
> work fine.

As I wrote before, bringing it to the point:

(1) The group (ab_grp) around A + B and its resizable() A make B fixed
width.

(2) The invisible box "around" the border between B (ab_grp) and C as
the window's resizable() make both ab_grp and C resize.

(3) The resizing of ab_grp and C is distributed proportionally to the
overlapping widths of the invisible box (box_i) with ab_grp and C,
respectively. If we choose the overlap width equal on both sides, they
resize evenly.

(4) Since box B is fixed width, the resizing of ab_grp is applied to box
A and this makes the whole interface resize symmetrically.

I modified the source code to make it shorter (removed the globals) and
adjusted box sizes slightly. I also added a size_range() to achieve a
well-defined minimal window size. See attached 3rd version of 'r.cxx'.

> This technique should be woven into the resizable()
> article, I'll see if I can do that too, unless you want to. Don't want
> to loose this valuable info..

I'd appreciate if you could do this. I'm not that good at writing docs
and I'm currently busy developing other FLTK stuff and trying to fix
STR's and issues.

The demo program could also be added to the examples folder with
appropriate comments or perhaps included in the resizing chapter of the
docs.
r.cxx

Albrecht Schlosser

unread,
Nov 21, 2020, 5:57:30 AM11/21/20
to fltkg...@googlegroups.com
On 11/21/20 11:10 AM duncan wrote:
> I played around with your example and found it still worked if I increased
> the width of the window and box C so that A and C are not symmetrical,
> but once you introduce padding between the boxes, things go a bit awry.
>
> See the attached, where I've also moved/coloured box I to make it visible.
> The fix might be obvious to you if you've been looking at the resize code.

If you want padding between the boxes I suggest to add another group
around box C and make box C the resizable in this box. If I understood
you correctly.

See attached r2a.cxx with my solution (again, if that's what you wanted
to achieve). The groups are now colored (red and green). I'm aware that
the padding is not equal everywhere but I'm leaving this as an exercise
to the reader. ;-)
r2a.cxx

duncan

unread,
Nov 21, 2020, 6:40:11 AM11/21/20
to fltk.general
If you want padding between the boxes I suggest to add another group
around box C and make box C the resizable in this box. If I understood
you correctly.

See attached r2a.cxx with my solution (again, if that's what you wanted
to achieve). The groups are now colored (red and green). I'm aware that
the padding is not equal everywhere but I'm leaving this as an exercise
to the reader. ;-)

Yes, that seems to do the trick, and works if box C is wider than box A so
the overall layout is not symmetrical. I think the padding's correct too.
I was sure that knowledge of the resize code would help :-)

D.

PS. Sorry for the top-posting before, I forgot to expand the ellipsis ... :-(

Greg Ercolano

unread,
Nov 21, 2020, 9:11:29 AM11/21/20
to fltkg...@googlegroups.com
On 2020-11-20 16:10, Greg Ercolano wrote:
I could see making a fully flexible packing widget like an HTML table..


    I should probably review this TableBox widget in our Links pages, which sounds like it's exactly that..


TableBox

The TableBox manages a group of widgets that are arranged in rows and columns, making it easy to align many widgets next to each other [..]The whole project was inspired by HTML table and GTK+ table widget.



    I did research that a bit; unfortunately that widget is fltk2.

    I was unable to get the old fltk2 project to build on my machine, so I couldn't explore it.
    But I did make a
very rough port that works with fltk 1.x, tossing the result on github
    in case anyone wants to try to fix it/take it further with a fork.

    The TableBox demo in my port runs and very interesting resizing behavior happens, but I don't
    think I got it fully working as intended. I can't remember fully how fltk2's layout() system
    worked, so it could be a problem with how I ported that.

    I think layout() was called on first drawing to reposition/size the widgets, and then
    Ialso called during any kind of resize().  I emulated that in the port, since TableBox
    overloads layout() to do its work, but not sure I got all that right; didn't have time
    to really dig in.

duncan

unread,
Nov 21, 2020, 11:19:07 AM11/21/20
to fltk.general
See attached r2a.cxx with my solution (again, if that's what you wanted
to achieve). The groups are now colored (red and green). I'm aware that
the padding is not equal everywhere but I'm leaving this as an exercise
to the reader. ;-)

The attached files can be dropped into the test directory and compiled
with fltk-config, and are in the style of the existing resize examples.
The #include resize-arrows.cxx for ease of fltk-config build which would
need to be changed if they become official test/documentation examples.

After tweaking these blindly for a while, they should probably be changed
to remove the padding completely, because I can't quite get it to work as
expected. I think that you actually need some more groups within the
C group to handle the padding as invisible boxes...

D.




resize-example5c.cxx
resize-example5b.cxx
resize-example5a.cxx

Albrecht Schlosser

unread,
Nov 21, 2020, 12:00:09 PM11/21/20
to fltkg...@googlegroups.com
On 11/21/20 5:19 PM duncan wrote:
>
> See attached r2a.cxx with my solution (again, if that's what you wanted
> to achieve). The groups are now colored (red and green). I'm aware that
> the padding is not equal everywhere but I'm leaving this as an exercise
> to the reader. ;-)
>
>
> The attached files can be dropped into the test directory and compiled
> with fltk-config, and are in the style of the existing resize examples.
> The #include resize-arrows.cxx for ease of fltk-config build which would
> need to be changed if they become official test/documentation examples.

Thanks for the code, I took a short look but I can't follow-up with much
more (no time to test right now).

> After tweaking these blindly for a while, they should probably be changed
> to remove the padding completely, because I can't quite get it to work as
> expected. I think that you actually need some more groups within the
> C group to handle the padding as invisible boxes...

Hmm, I'm not sure what "as expected" is in this case. However, WRT
padding I think you missed to make the C box the resizable() widget. I
added at line ~64 in resize-example5b.cxx:

m_groupR->end();
+ m_groupR->resizable(m_boxC);

int d = 20;

Is this maybe the missing piece?

PS: Greg's original question/issue resulted from the cube demo which
didn't resize as expected (issue #157). In that demo program vertical
resizing is required as well (as it was in my short demo code). I see
that your examples are resizing only horizontally and I don't know if
this was intended.
Message has been deleted
Message has been deleted

Paul Hahn

unread,
Nov 21, 2020, 12:35:09 PM11/21/20
to fltk.general
Just deleted my previous posts which were rambling and not correct. Ignore them if you already got them. Sorry.

Greg Ercolano

unread,
Nov 21, 2020, 1:35:25 PM11/21/20
to fltkg...@googlegroups.com
On 2020-11-21 06:11, Greg Ercolano wrote:
 

TableBox

The TableBox manages a group of widgets that are arranged in rows and columns, making it easy to align many widgets next to each other [..]The whole project was inspired by HTML table and GTK+ table widget.


    [..] I did make a very rough port that works with fltk 1.x, tossing the result on github

    in case anyone wants to try to fix it/take it further with a fork.


    The TableBox demo in my port runs and very interesting resizing behavior happens, but I don't
    think I got it fully working as intended.


    Followup: played around with that code a bit more and got it working more like intended I think.
    Seems interesting and perhaps worth persuing as a widget to add to FLTK; it's pretty "small+light".

    The original author posted it as GPL v2 though, which might be a problem for FLTK inclusion unless
    we can get the author's OK to allow its inclusion in fltk, otherwise a complete rewrite could be done
    I suppose..

Greg Ercolano

unread,
Nov 21, 2020, 1:52:10 PM11/21/20
to fltk.general
On Saturday, November 21, 2020 at 8:19:07 AM UTC-8 duncan wrote:
The attached files can be dropped into the test directory and compiled
with fltk-config, and are in the style of the existing resize examples.

Nice, the arrows really help for comprehension.
I can see the padding is slipping, but sounds like Albrecht has some advice for that.

I got sidetracked into looking over that TableBox widget, back porting it to fltk1.x
and seeing if it could maybe be brought into shape as something for FLTK inclusion.

But I do plan to use Albrecth's example in the issue #157.

duncan

unread,
Nov 21, 2020, 2:52:57 PM11/21/20
to fltk.general
Hmm, I'm not sure what "as expected" is in this case. However, WRT
padding I think you missed to make the C box the resizable() widget. I
added at line ~64 in resize-example5b.cxx:

m_groupR->end();
+ m_groupR->resizable(m_boxC);

Thanks Albrecht, that was indeed the critical part that I missed.
I thought it more likely that I had got a width or an offset wrong.

To indicate that it's a resizable in resize-example5b.cxx it also needs
  + m_boxC->color(FL_YELLOW);

D.


Greg Ercolano

unread,
Nov 23, 2020, 5:07:07 AM11/23/20
to fltkg...@googlegroups.com

So given your recent r.cxx (Nov 21 2020), I ended up with this to rough out the cube.cxx application issue #157, including symmetrical horizontal margins:



Ascii art in the code describes the arrangements.
Thanks everyone!



cube-resize.cxx
Reply all
Reply to author
Forward
0 new messages