Article #415: How does resizing work?

   
  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 03:19 Mar 29, 2005 by matt

Last modified at 16:31 Apr 23, 2005

FLTK uses a simple, but very versatile system to resize event 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:

*=================================*
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
*=================================*

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:

*=========================================*
H *=====* *=============================* H
H H  !  H H   Out of memory Error.      H H
H *=====* *=============================* H
H                              *========* H
H                              H Darn!  H H
H                              *========* H
*=========================================*

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:

*=========================================*
H---------*=============================* H
H H  !  H H   Out of memory Error.      H H
H---------*=============================* H
H         |                    *========| H
H         |                    H Darn!  | H
H         |                    *========| H
*=========================================*

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 doe we stop that from happening? Simple: put it in a box and make another widgets resizable:

             *===========================*
             H   *===*         *========*H
             H   H R H         H Darn!  HH
             H   *===*         *========*H
             *===========================*

Now, the box marked 'R' takes all the horizontal resizing and the 'Darn!' box will stay at 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,);
    ok = new Fl_Button(200, 50, 100, 50, "Darn!");
    r = new Fl_Widget(50, 50, 150, 50);
    r->hide();
  btns->resizable(r);
  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, 14: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, 15: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, 18: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 orenz, 12: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-2012 by Bill Spitzak and others. This project is hosted by Seriss Corporation. Please report site problems to 'erco@seriss.com'.