FLTK logo

Article #415: How does resizing work?

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 Home  |  Articles & FAQs  |  Bugs & Features  |  Documentation  |  Download  |  Screenshots  ]
 

Return to Articles | Show Comments | Submit Comment ]

Article #415: How does resizing work?

Created at 00:19 Mar 29, 2005 by matt

Note: This article has been superseded by the chapter "How does resizing work?" in the official FLTK documentation. The article is still valid but you may want to read the docs instead.

Thanks to Matt for the original article and all who contributed comments and suggestions, and last but not least to Duncan who ported it to the docs and created the screenshots.

Albrecht-S, July 2020

------------

FLTK uses a simple, but very versatile system to resize even the most complex dialogs and interfaces. A window is made resizable by setting exactly one of its children to be resizable.

Every group or window has either no resizable widget, in which case all children resize proportionally, or exactly one resizable widget, which becomes the reference for all other widgets inside the same group. Resizing could be seen as a cross inside the group:

    :::::::::::::::::::::::::::::::::::::
    ::       :             :           ::
    ::   E   :   <- A ->   :     F     ::
    ::       :             :           ::
    ::.......:::::::::::::::...........::
    ::       ::           ::           ::
    ::   ^   ::           ::     ^     ::
    ::   C   ::     R     ::     D     ::
    ::   v   ::           ::     v     ::
    ::       ::           ::           ::
    ::.......:::::::::::::::...........::
    ::       :             :           ::
    ::   G   :   <- B ->   :     H     ::
    ::       :             :           ::
    ::       :             :           ::
    :::::::::::::::::::::::::::::::::::::

In the graphics above, 'R' is the resizable widget of the group 'G'. The resizing behavior is as follows: all other children of 'G' that lay inside of 'G' resize proportionally to 'R'. Now imagine some lines to the left and right of 'R'. All widgets that lay within area 'A' and 'B' will resize horizontally (but not vertically), and all the rest will not resize horizontally at all.

The same is true for vertical resizing: imagine two horizontal lines on top and below 'R'. Now everything within 'C' and 'D' will resize vertically. Areas 'E', 'F', 'G', and 'H' will never resize.

Why is this so powerful, you may ask. Well, every group can have a completely independent resizing behavior, so if you put a group inside of 'B', you can apply all of the above rules all over again, creating very complex layouts.

Let's do an example, a simple dialog box:

...........................................
: ....... ............................... :
: :  !  : :   Out of memory Error.      : :
: :.....: :.............................: :
:                              .......... :
:                              :  Darn! : :
:                              :........: :
:.........................................:

Which box should be the resizable one? The error text box would be great, so the user can expand the dialog and maybe there is more of an explanation below the short error message. This gives us this behavior:

........................................................
: ....... ............................................ :
: :  !  : :   Out of memory Error.                   : :
: :     : :                                          : :
: :     : :                                          : :
: :.....: :..........................................: :
:                              ....................... :
:                              :         Darn!       : :
:                              :.....................: :
:......................................................:

Which is close to what we want, but not quite: the '!' box will not resize horizontally, but vertically, the text box will fully resize, and the 'Darn' button will - wait a minute - resize horizontally? That's ugly. How do we stop that from happening? Simple: put it in a group (G) and make an invisible widget the resizable:

             ..............................
             :   .....         .......... :
             :   : R :         : Darn!  : :
             :   :...:         .........: :
             :............................:
                          ^
                         /|\
                          |
                       Group 'G'

Now, the invisible box marked 'R' takes all the horizontal resizing and the 'Darn!' box will stay as is. Here's the code:

dialog = new Fl_Window(300, 100);
  icon = new Fl_Box(0, 0, 50, 50, "!");
  msg  = new Fl_Box(50, 0, 250, 50, "No Memory");
  btns = new Fl_Group(50, 50, 250, 50,); // parenting group
    ok = new Fl_Button(200, 50, 100, 50, "Darn!");
     r = new Fl_Box(50, 50, 150, 50);    // "invisible" box "R"
     r->hide();                          // make sure it's invisible
  btns->resizable(r);                    // make "R" parent grp's resizable
  btns->end();
dialog->resizable(msg);
dialog->end();

PS:

Q: I have a group that has a button, and input field, another button, another input field, all next to each other. I want the input fields to resize, but not the buttons. How?

 ,-----. ,-------. ,-----. ,-------. 
 | btn | | input | | btn | | input | 
 `-----' `-------' `-----' `-------' 

A: Create a main group. Inside the main group, create two more groups, 'g_left' and 'g_right', but don't set either of the two resizable. Now both subgroups should resize equally. Put the first button and input next to each other into 'g_left' and make the input resizable, then put the second button and input field into 'g_right' and again make the input resizable. Tada.
    

+=================+ +=================+
H,-----. ,-------.H H,-----. ,-------.H 
H| btn | | input |H H| btn | | input |H 
H`-----' `-------'H H`-----' `-------'H 
+=================+ +=================+

Listing ]


Comments

Submit Comment ]

From greg.ercolano, 11:33 Jan 30, 2011 (score=3)

One simple thing that's easy to forget is that you can make a group
and set its resizable to 0, and then that group (and everything in it) won't resize.

So If you have a bunch of widgets, some that you want to resize,
and some that you don't, just put all the widgets you /don't/ want
to resize in a group of their own, and set that group's resizable to 0.

As an example, I wanted a window that looked like this:

                        window
   ...................................................
   : .................  ............................. :
   : :               :  :      Sliders / Controls   : :
   : :               :  :    _________   _________  : :
   : :               :  :   |_________| |_________| : :
   : :               :  :    _________   _________  : :
   : :     Tree      :  :   |_________| |_________| : :
   : :               :  :    _________   _________  : :
   : :               :  :   |_________| |_________| : :
   : :               :  :                           : :
   : :...............:  :...........................: :
   :...................................................

..where window resizing would only affect the 'tree';
the sliders+controls would remain a fixed size.

The easy solution was to make the window->resizable(tree),
and to make a group around all the "sliders+controls"
and set group->resizable(0);

It was also useful with this arrangement to prevent the window
from being resized smaller than the designed size, which was
as easy as: window->size_range(window->w(), window->h(), 0, 0);

Reply ]

From greg.ercolano, 12:05 Oct 05, 2007 (score=3)

Some examples of 'do it yourself' resizing behavior,
if you want to override FLTK's default resizing/resizable() stuff:

http://seriss.com/people/erco/fltk/#ScrollableWidgetBrowser
http://fltk.org/newsgroups.php?gfltk.general+v:13522


Reply ]

From d.zimmer, 15:48 Mar 30, 2005 (score=3)

A desperately needed document. Kudos.

Some images would be easier to grasp than the ASCII, though.

I would recommend that this be included in the HTML documentation for the library.

Don.


Reply ]

From greg.ercolano, 22:47 Nov 10, 2017 (score=3)

Perhaps I can make all the ascii art examples for this article into actual images on the server somewhere, and refer to them.

I too would like to see this article's contents added to the docs. I've made STR #3433 for this, to ensure it gets done "someday":
http://www.fltk.org/str.php?L3433

I did just now modify the first ascii art image a bit so that it doesn't use the same letters for drawing edges as it does for the example group names ("H"), as I think that was throwing people off. Here's Matt's original ascii art, for the record:

*=================================*
H       |             |           H
H   E   |  <- A ->    |     F     H
H       |             |           H
H-------+=============+-----------H
H   ^   H             H     ^     H
H   C   H     R       H     D     H
H   v   H             H     v     H
H       H             H           H
H-------+=============+-----------H
H       |             |           H
H   G   |  <- B ->    |     H     H
H       |             |           H
H       |             |           H
*=================================*
[EDIT: I also made some other small fixes to Matt's text just now for clarity. Such as the text for adding a group and invisible box "R" to the dialog to prevent the Darn! button from scaling. I don't think we keep a diff history, so unfortunately I can't show what was changed easily. Also added comments to his example code for this, and changed  "R" from an Fl_Widget to an Fl_Box, because trying to create an Fl_Widget throws an error; Fl_Widget::draw() is an unimplemented virtual.]


Reply ]

From greg.ercolano, 08:49 Aug 04, 2020 (score=3)

Made a few more tweaks to the original article's ascii art, because to me it wasn't clear what was being shown in the "Out of memory Error." diagrams.

Here's a pic of old vs. new:


Reply ]

From orenz, 09:47 Mar 29, 2005 (score=3)

finally...

A short, to the point, article about how the resize works!

great!

thx
Reply ]

 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.