Add a widget to an Fl_Group and then resize the group

339 views
Skip to first unread message

monocasual laboratories

unread,
Dec 25, 2014, 7:25:40 PM12/25/14
to fltkg...@googlegroups.com
Hi guys,

I'm having some troubles with a Fl_Group from FLTK 1.3.3.

I would like to add a new widget (which is, in turn, another group) to an Fl_Group and then resize the outer Fl_Group, but if I call resize() on it after the addition, the group itself messes up its content. Maybe I'm dealing with the Fl_Group in a wrong way...

What follows is a working example of what I'm trying to reach. Just uncomment the piece of code inside the callback to reproduce the issue. 

Thanks in advance for your time and help!

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


Fl_Window *win;
Fl_Group  *container;
Fl_Button *button;


class Element : public Fl_Group
{
public:
 
Element(int X, int Y) : Fl_Group(X, Y, 80, 20)
 
{
   
Fl_Box *b = new Fl_Box(X, Y, w(), h(), "element");
    b
->box(FL_BORDER_BOX);
   
end();
 
}
};


void add_cb(Fl_Widget *w, void *data)
{
 
int pos = container->y() + (container->children() * 20);
  container
->add(new Element(10, pos));

 
/* uncomment this */
 
/*container->resize(
      container->x(),
      container->y(),
      container->w(),
      container->children() * 20);*/


  container
->redraw();
};


int main(int argc, char **argv)
{
  win      
= new Fl_Window(640, 480);
  button    
= new Fl_Button(10, 10, 120, 30, "Add element");
  container
= new Fl_Group(10, 50, 620, 420);

  container
->box(FL_BORDER_BOX);
  button
->callback(add_cb);

  win
->end();
  win
->show();
 
return(Fl::run());
}


Greg Ercolano

unread,
Dec 25, 2014, 8:16:42 PM12/25/14
to fltkg...@googlegroups.com
On 12/25/14, 7:25 PM, monocasual laboratories wrote:
> What follows is a working example of what I'm trying to reach.

With your code uncommented, find this line:

container->box(FL_BORDER_BOX);

..and add the following below it:

container->resizable(0);

This disables the default resize behavior that scales the children.

For more info, see the docs for Fl_Group::resizable(), the test/resizebox demo,
and article 415 on resizing: http://www.fltk.org/articles.php?L415


monocasual laboratories

unread,
Dec 26, 2014, 4:55:20 AM12/26/14
to fltkg...@googlegroups.com, erco_...@seriss.com
Hi Greg,

Thanks for the links and the hint: with container->resizable(0); the glitch is fixed. In my real life app however I would like to keep the outer container horizontally resizable. Should I override its default resize behavior?

Albrecht Schlosser

unread,
Dec 27, 2014, 8:52:44 AM12/27/14
to fltkg...@googlegroups.com
On 26.12.2014 21:42 monocasual laboratories wrote:
> Hi Greg,
>
> Thanks for the links and the hint: with container->resizable(0); the
> glitch is fixed. In my real life app however I would like to keep the
> outer container horizontally resizable. Should I override its default
> resize behavior?

There are a few things to look at in your code. I tried to add some
statements marked with [n]. See below for notes.

Here's my modified code:

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

Fl_Window *win;
Fl_Group *container;
Fl_Button *button;

class Element : public Fl_Group
{
public:
Element(int X, int Y) : Fl_Group(X, Y, 80, 20)
{
Fl_Box *b = new Fl_Box(X, Y, w(), h(), "element");
b->box(FL_BORDER_BOX);
end();
}
};

void add_cb(Fl_Widget *w, void *data)
{
int pos = container->y() + (container->children() * 20);
container->add(new Element(10, pos));

Fl_Widget *r = container->resizable(); // [1]
container->resizable(0); // [1] (see also Greg's post)
container->resize(
container->x(),
container->y(),
container->w(),
container->children() * 20);
container->resizable(r); // [1]
container->init_sizes(); // [2]
container->parent()->init_sizes(); // [3]

container->redraw();
};

int main(int argc, char **argv)
{
win = new Fl_Window(640, 480);
button = new Fl_Button(10, 10, 120, 30, "Add element");
Fl_Box *rbox = new Fl_Box(140, 0, 10, 10); // [4]
rboy->hide(); // [4]
container = new Fl_Group(10, 50, 620, 420);

container->box(FL_BORDER_BOX);
button->callback(add_cb);

win->end();
win->resizable(rbox); // [4]
win->size_range(640,480,0,480); // [5]
win->show();
return(Fl::run());
}

Notes:

[1] as Greg suggested, you can prevent resizing of children during your
layout changes, but I suggest to save and restore the resizable(). So
you can keep the default resize behavior you asked for (see below).

[2] if you want default resizing to work as expected you must also tell
FLTK that the layout of your group was changed intentionally. This is
done here. You must do this after you change the layout and before the
next resize() call, whenever this will happen (maybe by the user).

[3] The same applies to the container's parent group. And maybe the
parent's parent and so on...

[4] You asked for horizontal resizing of the container. Although you may
set the container as the resizable, the hidden rbox widget will prevent
resizing of the button.

[5] This is a simple method to make resizing only horizontal. There are
other ways to achieve this (see the links in Greg's posting).


This modified program works "better", but may not be what you want.
Note the different sizes of the added boxes if you add some before and
some after resizing the window (container).

If you really want a specialized resize behavior and keep the layout as
you designed it throughout resizing and adding elements you might indeed
need to override the container's resize methode, i.e. derive your own
"container" class as well.

Reply all
Reply to author
Forward
0 new messages