Discussion:
Fl_tile: don't shrink, just shift
dirac
2013-04-20 21:04:37 UTC
Permalink
Hi guys,

I'm building a stack of horizontal widgets, like that (I hope the ASCII
art works):

+---Fl_tile-------------------+
| +-------------------------+ |
| | widget 0 | |
| +-------------------------+ |
| +-------------------------+ |
| | widget 1 | |
| +-------------------------+ |
| +-------------------------+ |
| | widget 2 | |
| +-------------------------+ |
|+----------------------------+

I would like to make each widget vertically resizable, so an Fl_tile
seems a good choice for a container.
Unfortunately I've noticed that Fl_tile shrinks the other widgets: for
example if I enlarge Widget 0 completely to the very bottom, "widget 1"
and "widget 2" disappear, i.e. their height becomes zero.

My question: is there a way to extend Fl_tile so that it shifts the
other widgets below Widget 0, instead of shrink them? Possibly Fl_tile
should also expand itself vertically to make room for the other widgets.

Many thanks in advance for your time!


John
Ian MacArthur
2013-04-21 09:03:48 UTC
Permalink
Post by dirac
I'm building a stack of horizontal widgets, like that (I hope the ASCII
+---Fl_tile-------------------+
| +-------------------------+ |
| | widget 0 | |
| +-------------------------+ |
| +-------------------------+ |
| | widget 1 | |
| +-------------------------+ |
| +-------------------------+ |
| | widget 2 | |
| +-------------------------+ |
|+----------------------------+
I would like to make each widget vertically resizable, so an Fl_tile
seems a good choice for a container.
Though I suspect that initial reaction may be misleading...
Post by dirac
Unfortunately I've noticed that Fl_tile shrinks the other widgets: for
example if I enlarge Widget 0 completely to the very bottom, "widget 1"
and "widget 2" disappear, i.e. their height becomes zero.
Yup, the issue here is (I think) that Fl_Tile, like many container widgets, is striving to maintain a fixed outer dimension, so as "widget 1" grows, the other widgets in the container need to shrink...

I guess that what you want is a container widget that will grow/shrink as it's children grow/shrink.

And that's not quite the same thing as an Fl_Tile.
Post by dirac
My question: is there a way to extend Fl_tile so that it shifts the
other widgets below Widget 0, instead of shrink them? Possibly Fl_tile
should also expand itself vertically to make room for the other widgets.
Yes, though Fl_Tile may be the wrong place to start. I'd probably just start form an Fl_Group then modify the resize behaviour to match the changing sizes of the groups children...

Hmm, now, I seem to recall that Jason Bryan's "FLU" widget extensions for fltk had something like that - they would be worth a look.

OK; his pages at OSC.edu appear to be down, but there's a mirror here that still seems to work:

http://src.gnu-darwin.org/ports/x11-toolkits/flu/work/FLU_2.14/


Maybe his "collapsible group" widget might give you some starting hints?
Martin Kroeker
2013-04-21 10:38:23 UTC
Permalink
Hmm, now, I seem to recall that Jason Bryan's "FLU" widget extensions =
for fltk had something like that - they wo uld be worth a look.
OK; his pages at OSC.edu appear to be down, but there's a mirror here =
This came up a year ago - check STR2795
Latest FLU is hosted on sourceforge http://sourceforge.net/projects/flufltk/
Jason gave permission to integrate them, Fabien Constantini reported
that he had ported the full FLU2.14 widget set to 1.3 and volunteered
to integrate (at least?) its Fl_Tree implementation in 1.3/3.0

Martin
MacArthur, Ian (Selex ES, UK)
2013-04-22 08:22:39 UTC
Permalink
Post by Martin Kroeker
Post by Ian MacArthur
Hmm, now, I seem to recall that Jason Bryan's "FLU" widget extensions
=
Post by Ian MacArthur
for fltk had something like that - they wo uld be worth a look.
OK; his pages at OSC.edu appear to be down, but there's a mirror here
=
This came up a year ago - check STR2795
Latest FLU is hosted on sourceforge
http://sourceforge.net/projects/flufltk/
Thanks Martin; I did not know about that Sourceforge location. That could be handy.

Though... does that actually work for anyone? I just tried, and there don't seem to be any files to download there?
Probably I'm doing something stupid again...
Post by Martin Kroeker
Jason gave permission to integrate them, Fabien Constantini reported
that he had ported the full FLU2.14 widget set to 1.3 and volunteered
to integrate (at least?) its Fl_Tree implementation in 1.3/3.0
Though we now have Greg's tree widget implemented anyway, so the need is less pressing now!



Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************
Duncan Gibson
2013-04-21 10:54:12 UTC
Permalink
Post by dirac
I would like to make each widget vertically resizable, so an Fl_tile
seems a good choice for a container.
IIRC, Fl_Tile imposes some constraints on how its children resize.

For a general description of how resizing works in FLTK, see
"resizable() " at http://fltk.org/doc-1.3/classFl__Group.html

and then there's also Article #415: How does resizing work?
http://fltk.org/articles.php?L415

D.
Greg Ercolano
2013-04-21 17:50:18 UTC
Permalink
Post by dirac
Hi guys,
I'm building a stack of horizontal widgets, like that (I hope the ASCII
+---Fl_tile-------------------+
| +-------------------------+ |
| | widget 0 | |
| +-------------------------+ |
| +-------------------------+ |
| | widget 1 | |
| +-------------------------+ |
| +-------------------------+ |
| | widget 2 | |
| +-------------------------+ |
|+----------------------------+
I would like to make each widget vertically resizable, so an Fl_tile
seems a good choice for a container.
Unfortunately I've noticed that Fl_tile shrinks the other widgets: for
example if I enlarge Widget 0 completely to the very bottom, "widget 1"
and "widget 2" disappear, i.e. their height becomes zero.
My question: is there a way to extend Fl_tile so that it shifts the
other widgets below Widget 0, instead of shrink them? Possibly Fl_tile
should also expand itself vertically to make room for the other widgets.
I made one of these once; in my case I didn't use a tile,
just used a regular Fl_Group in which the widgets were positioned,
and put a thin widget between each that acted as a 'resizer' which:

1) enlarged/shrunk the widget above it
2) enlarged/shrunk the parent group
3) moved all the children below it up/down

The resizer class responded to FL_MOVE so that the cursor would
turn into a "north/south" cursor, and responded to FL_DRAG to handle
Post by dirac
+---Fl_tile-------------------+
| +-------------------------+ |
| | | |
| | widget 0 | |
| | | |
| +-------------------------+ |
| | resizer | |
| +-------------------------+ |
| | | |
| | widget 1 | |
| | | |
| +-------------------------+ |
| | resizer | |
| +-------------------------+ |
| | | |
| | widget 2 | |
| | | |
| +-------------------------+ |
+-----------------------------+
You can either have resizer make assumptions about parent() being
an Fl_Group and assume all widgets within that parent are inspected
to see if the widgets are above or below the current 'resizer' being
moved, so that only the widget immediately above is resized, and widgets
below are moved, and all the other child widgets are left alone.
Then just call the parent's init_sizes() to let it know the children
have changed size.

I suppose you could then put this entire group inside an Fl_Scroll, so
that if the children resize off the screen, a scroller will appear..
Greg Ercolano
2013-04-22 11:01:58 UTC
Permalink
Post by Greg Ercolano
I made one of these once; in my case I didn't use a tile,
just used a regular Fl_Group in which the widgets were positioned,
1) enlarged/shrunk the widget above it
2) enlarged/shrunk the parent group
3) moved all the children below it up/down
Post by dirac
+---Fl_tile-------------------+
| +-------------------------+ |
| | | |
| | widget 0 | |
| | | |
| +-------------------------+ |
| | resizer | |
| +-------------------------+ |
| | | |
| | widget 1 | |
| | | |
| +-------------------------+ |
| | resizer | |
| +-------------------------+ |
| | | |
| | widget 2 | |
| | | |
| +-------------------------+ |
+-----------------------------+
Here's an example implementation of the above based on an older work.

This assumes the parent is an *Fl_Scroll*.
This is so that widgets off-screen can be reached with a scroll bar.

The ResizerButton class is what you would use in your app.
The main() below it shows how to use it.

The example code creates 10 Fl_Box widgets with a resizer below each.
You can drag the resizers around to change the size of the widget above;
the other widgets below will be moved around inside the scroller to accommodate.
Scrollbars will appear for widgets that are off-screen.

--- snip
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/fl_draw.h>
#include <stdio.h>

//
// Demonstrate a resizer class for widgets in an Fl_Scroll
// erco 1.0 ??/??/04 - original test program
// erco 1.1 04/21/13 - modernized
//

// CLASS FOR HANDLING A 'RESIZER' BETWEEN WIDGETS IN AN Fl_Scroll
//
// > Shows a resize cursor when hovered over
// > Assumes: * Parent is an Fl_Scroll
// * All children of Fl_Scroll are vertically arranged
// * The widget above us has a bottom edge touching our top edge
// ie. (w->y()+w->h() == this->y())
//
// > When this widget is dragged:
// * The widget above us (with a common edge) will be /resized/ vertically
// * All children below us will be /moved/ vertically
//
class ResizerButton : public Fl_Button {
int orig_h;
int last_y;
int min_h; // min height for widget above us
void HandleDrag(int diff) {
Fl_Scroll *grp = (Fl_Scroll*)parent();
int top = y();
int bot = y()+h();
// First pass: find widget directly above us with common edge
// Possibly clamp 'diff' if widget would get too small..
//
for ( int t=0; t<grp->children(); t++ ) {
Fl_Widget *w = grp->child(t);
if ( (w->y()+w->h()) == top ) { // found widget directly above?
if ( (w->h()+diff) < min_h ) diff = w->h() - min_h; // clamp
w->resize(w->x(), w->y(), w->w(), w->h()+diff); // change height
break; // done with first pass
}
}
// Second pass: find widgets below us, move based on clamped diff
for ( int t=0; t<grp->children(); t++ ) {
Fl_Widget *w = grp->child(t);
if ( w->y() >= bot ) // found widget below us?
w->resize(w->x(), w->y()+diff, w->w(), w->h()); // change position
}
// Change our position last
resize(x(),y()+diff,w(),h());
grp->init_sizes();
grp->redraw();
}
public:
ResizerButton(int X,int Y,int W,int H) : Fl_Button(X,Y,W,H,"///////") {
orig_h = H;
last_y = 0;
min_h = 10;
align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
labelfont(FL_COURIER);
labelsize(6);
}
void SetMinHeight(int val) { min_h = val; }
int GetMinHeight() const { return min_h; }
int handle(int e) {
int ret = 0;
int this_y = Fl::event_y_root();
switch (e) {
case FL_FOCUS: ret = 1; break;
case FL_ENTER: ret = 1; fl_cursor(FL_CURSOR_NS); break;
case FL_LEAVE: ret = 1; fl_cursor(FL_CURSOR_DEFAULT); break;
case FL_PUSH: ret = 1; last_y = this_y; break;
case FL_DRAG:
HandleDrag(this_y-last_y);
last_y = this_y;
ret = 1;
break;
default: break;
}
return(Fl_Button::handle(e) | ret);
}
void resize(int X,int Y,int W,int H) {
Fl_Button::resize(X,Y,W,orig_h); // height of resizer stays constant size
}
};

// Demonstrate the ResizerButton class above
// Creates 10 Fl_Box widgets with a resizer below each.
// User can drag the resizers around to change the size of the widget above it.
// The other widgets below will be moved around inside the scroller to accommodate.
//
int main(int argc, char** argv) {
Fl_Window win(220,400);
win.begin();
Fl_Scroll scr(0,0,220,400);
scr.begin();
// Create 10 boxes with resizer between each
for ( int i=0; i<10; i++ ) {
// Create a box..
char s[10]; sprintf(s, "%c%c%c", 'A'+i,'a'+i,'a'+i); // 'unique' label
Fl_Box *b = new Fl_Box (0,i*50,200,40);
b->copy_label(s);
b->box(FL_FLAT_BOX);
b->color(FL_WHITE);
b->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
// And put a Resizer directly below it with a common edge. (The common edge is important)
new ResizerButton(0,b->y()+b->h(),200,10);
}
scr.end();
win.end();
win.resizable(scr);
win.show();
return(Fl::run());
}

dirac
2013-04-21 20:08:01 UTC
Permalink
Thank you all so much for your hints: now I understand the real purpose and design of Fl_tile!
I think I'll opt for a derived Fl_Group as suggested by Ian and Greg.

All the best,

John
MacArthur, Ian (Selex ES, UK)
2013-04-22 08:25:14 UTC
Permalink
Post by dirac
Thank you all so much for your hints: now I understand the real purpose
and design of Fl_tile!
I think I'll opt for a derived Fl_Group as suggested by Ian and Greg.
Mainly by Greg, I thought his description was pretty good.
I might be tempted to make his "resizer" widget out of a group, so that it could contain the widget(s) that it was resizing, without have to search quite so much for them.

Or... that might be a bad idea. Dunno...

Let us know what happens!



Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************
Duncan Gibson
2013-04-22 09:16:47 UTC
Permalink
Post by MacArthur, Ian (Selex ES, UK)
Post by Martin Kroeker
... Jason Bryan's "FLU" widget extensions
... OK; his pages at OSC.edu appear to be down,
This came up a year ago - check STR2795
Latest FLU is hosted on sourceforge
http://sourceforge.net/projects/flufltk/
... does that actually work for anyone? I just tried, and there
don't seem to be any files to download there?
If you click on the blue Browse Code button then you can certainly
peruse the individual files, don't know about svn checkout though,

BUT if you click on the web site link you get redirected to some
wierd site which doesn't appear to have anything to do with it. So
unclear if a site has been hijacked or expired and re-acquired...

D.
Continue reading on narkive:
Loading...