Add new resize example to test and dox (PR #165)

add example(s) showing Albrecht's innovative overlap resizable
technique to the "How does resizing work?" documentation and tests

See "resizable question" original discussion thread under:
https://www.fltk.org/newsgroups.php?gfltk.general+v:39635
This commit is contained in:
Duncan Gibson 2020-11-24 01:07:37 +01:00 committed by Albrecht Schlosser
parent 76a3ded549
commit 7407d9c8d0
9 changed files with 469 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -19,11 +19,11 @@ resizing behavior of that group is determined by its
group = new Fl_Group(xg, yg, wg, hg, "No Resizing");
child1 = new Fl_Box(xb, yb, wb, hb, "B"); // or other widget type
. . .
group->resizable(0); // no resizing
group->resizable((Fl_Widget*)0); // no resizing
group->end()
\endcode
The \p resizable may be set to zero,
The \p resizable may be set to the NULL pointer,
which means that the group will not resize.
Note that this is the default behavior for Fl_Window and Fl_Pack
derived widgets, and therefore the programmer must explicitly set
@ -125,7 +125,7 @@ Setting the \p resizable to be the icon box won't give us what we want:
The message text area would be the logical choice so that the user
can expand the dialog to see if there is more of an explanation below
the short error message. This results in the behaviour shown in the
the short error message. This results in the behavior shown in the
diagram below.
\image html resize-example3b.png "Resizing dialog example (b)"
@ -189,6 +189,91 @@ It might take some thought to achieve exactly what you want and
sometimes it is necessary to introduce parallel hierarchies in
order to get widgets in different groups to resize together.
Imagine you have a group containing three widgets in a row,
and you want the widget in the middle to stay the same size
when the group is stretched and the ones on either side and
the padding between them to resize symmetrically.
As described earlier, the default resizing behavior for a group
results in proportional resizing of the child widgets (and also
of the margins and padding between them) as shown below, which
is clearly not what you want.
\image html resize-example5a.png "Figure 6.8: Resizing a row of widgets (a)"
\image latex resize-example5a.png "Resizing a row of widgets (a)" width=12cm
Simply adding a group around A and B and setting its \p resizable
to A, as in the previous btn-input example, will mean that B stays
the same size, but the other widgets won't resize symmetrically,
so what else is needed?
It isn't immediately obvious how to solve this problem, even for
experienced FLTK users.
This is possibly because users are generally advised to design
widgets so that they don't overlap.
Albrecht Schlosser proposed an innovative technique that involves
an invisible box that deliberately overlaps others to achieve the
desired behavior.
For the current example, this means inserting two new groups
into the existing group and adding a hidden resizable widget.
The first group, shown in red below, extends from the left
edge of the parent group to the middle of the gap between
boxes B and C on the right.
This first group contains boxes A and B,
where A is the first group's \p resizable attribute.
The second group, shown in blue, extends from the right edge
of the first group to the right edge of the parent group.
This second group contains box C, where C is
the second group's \p resizable.
The extra box widget is added to the parent group
and is set as the group's \p resizable.
The three \p resizable widgets are shown in yellow.
The clever bit is that this extra box widget is not horizontally
aligned with any of the existing groups and widgets in the usual
way, but instead overlaps the right and left parts of the two new
groups by the same small amount, which means that its midpoint
is aligned with the edge between the groups.
Note that, for clarity, the height of the original group has
been increased to allow space for the additional annotation
and to highlight the extra resizable box in the extra space
at the bottom of the group.
This is fine for the horizontal-only resizing shown here, but
means that widgets A, B and C will never change height because
the extra resizable box does not overlap them vertically.
Only the padding below them will be resized.
\image html resize-example5b.png "Figure 6.9: Resizing a row of widgets (b)"
\image latex resize-example5b.png "Resizing a row of widgets (b)" width=12cm
In a real application, you probably want to allow widgets A,
B and C to resize vertically while the height of any padding
or widgets above or below remains fixed, so the extra resizable
box has to lie within the height of widgets A, B and C.
Obviously after calling <tt>hide()</tt> on the box it is no
longer visible, and may therefore be the same height as the
other widgets, or a fraction of the height, as shown below.
\image html resize-example5c.png "Figure 6.10: Resizing a row of widgets (c)"
\image latex resize-example5c.png "Resizing a row of widgets (c)" width=12cm
To summarize the key points of the new technique:
\li The new resizable widget must overlap the widgets on each
side by exactly the same amount.
\li The width of the new resizable widget is not fixed, but should
probably be a relatively small value to avoid potential problems.
\li The total width of the two new groups must equal the width
of the existing group and there can be no offsets or gaps
between them because margins and gaps will affect the
resizing behavior.
\li The same principles apply to vertical resizing.
\htmlonly
<hr>

View File

@ -126,6 +126,9 @@ CREATE_EXAMPLE (resize-example3b "resize-example3b.cxx;resize-arrows.cxx" fltk)
CREATE_EXAMPLE (resize-example3c "resize-example3c.cxx;resize-arrows.cxx" fltk)
CREATE_EXAMPLE (resize-example4a "resize-example4a.cxx;resize-arrows.cxx" fltk)
CREATE_EXAMPLE (resize-example4b "resize-example4b.cxx;resize-arrows.cxx" fltk)
CREATE_EXAMPLE (resize-example5a "resize-example5a.cxx;resize-arrows.cxx" fltk)
CREATE_EXAMPLE (resize-example5b "resize-example5b.cxx;resize-arrows.cxx" fltk)
CREATE_EXAMPLE (resize-example5c "resize-example5c.cxx;resize-arrows.cxx" fltk)
CREATE_EXAMPLE (rotated_text rotated_text.cxx fltk)
CREATE_EXAMPLE (scroll scroll.cxx fltk)
CREATE_EXAMPLE (subwindow subwindow.cxx fltk)

View File

@ -1794,6 +1794,51 @@ resize-example4b.o: ../FL/Fl_Widget.H
resize-example4b.o: ../FL/Fl_Window.H
resize-example4b.o: ../FL/platform_types.h
resize-example4b.o: resize-arrows.h
resize-example5a.o: ../FL/abi-version.h
resize-example5a.o: ../FL/Enumerations.H
resize-example5a.o: ../FL/Fl.H
resize-example5a.o: ../FL/Fl_Bitmap.H
resize-example5a.o: ../FL/Fl_Box.H
resize-example5a.o: ../FL/Fl_Double_Window.H
resize-example5a.o: ../FL/Fl_Export.H
resize-example5a.o: ../FL/Fl_Group.H
resize-example5a.o: ../FL/Fl_Image.H
resize-example5a.o: ../FL/fl_types.h
resize-example5a.o: ../FL/fl_utf8.h
resize-example5a.o: ../FL/Fl_Widget.H
resize-example5a.o: ../FL/Fl_Window.H
resize-example5a.o: ../FL/platform_types.h
resize-example5a.o: resize-arrows.h
resize-example5b.o: ../FL/abi-version.h
resize-example5b.o: ../FL/Enumerations.H
resize-example5b.o: ../FL/Fl.H
resize-example5b.o: ../FL/Fl_Bitmap.H
resize-example5b.o: ../FL/Fl_Box.H
resize-example5b.o: ../FL/Fl_Double_Window.H
resize-example5b.o: ../FL/Fl_Export.H
resize-example5b.o: ../FL/Fl_Group.H
resize-example5b.o: ../FL/Fl_Image.H
resize-example5b.o: ../FL/fl_types.h
resize-example5b.o: ../FL/fl_utf8.h
resize-example5b.o: ../FL/Fl_Widget.H
resize-example5b.o: ../FL/Fl_Window.H
resize-example5b.o: ../FL/platform_types.h
resize-example5b.o: resize-arrows.h
resize-example5c.o: ../FL/abi-version.h
resize-example5c.o: ../FL/Enumerations.H
resize-example5c.o: ../FL/Fl.H
resize-example5c.o: ../FL/Fl_Bitmap.H
resize-example5c.o: ../FL/Fl_Box.H
resize-example5c.o: ../FL/Fl_Double_Window.H
resize-example5c.o: ../FL/Fl_Export.H
resize-example5c.o: ../FL/Fl_Group.H
resize-example5c.o: ../FL/Fl_Image.H
resize-example5c.o: ../FL/fl_types.h
resize-example5c.o: ../FL/fl_utf8.h
resize-example5c.o: ../FL/Fl_Widget.H
resize-example5c.o: ../FL/Fl_Window.H
resize-example5c.o: ../FL/platform_types.h
resize-example5c.o: resize-arrows.h
resize.o: ../FL/abi-version.h
resize.o: ../FL/Enumerations.H
resize.o: ../FL/Fl.H

97
test/resize-example5a.cxx Normal file
View File

@ -0,0 +1,97 @@
//
// Resize example for use in the Fast Light Tool Kit (FLTK) documentation.
//
// See Article #415: How does resizing work?
// https://www.fltk.org/articles.php?L415
//
// Copyright 1998-2020 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#include "resize-arrows.h"
#include <FL/Fl_Double_Window.H>
// window, simplex and arrow dimensions
int TLx = 35, TRx = 320, TLw = 260, Ww = 620;
int TLy = 35, LGy = 100, TLh = 65, LGh = 70, LAh = 35, Wh = 175;
Fl_Double_Window *window = 0;
class Simplex : public Fl_Group {
public:
Simplex(int X, int Y, int W, int H, const char *T = 0);
Fl_Box *m_boxA, *m_boxB, *m_boxC;
Fl_Group *m_group;
};
Simplex::Simplex(int X, int Y, int W, int H, const char *T)
: Fl_Group(X, Y, W, H, T) {
this->box(FL_UP_BOX);
m_group = new Fl_Group(X + 10, Y + 10, 240, 45);
m_group->box(FL_UP_BOX);
m_boxA = new Fl_Box(X + 20, Y + 20, 80, 25, "A");
m_boxA->box(FL_UP_BOX);
m_boxB = new Fl_Box(X + 110, Y + 20, 40, 25, "B");
m_boxB->box(FL_UP_BOX);
m_boxC = new Fl_Box(X + 160, Y + 20, 80, 25, "C");
m_boxC->box(FL_UP_BOX);
m_group->color(FL_YELLOW);
m_group->end();
this->resizable(m_group);
this->end();
}
class Resizables : public Fl_Group {
public:
Resizables(int X, int Y, int W, int H, const char *T = 0);
Simplex *TL, *TR; // top left, top right
Harrow *LA, *RA; // left arrow, right arrow
};
Resizables::Resizables(int X, int Y, int W, int H, const char *T)
: Fl_Group(X, Y, W, H, T) {
TL = new Simplex(X + TLx, Y + TLy, TLw, TLh, "Original");
TL->align(FL_ALIGN_TOP_LEFT);
TR = new Simplex(X + TRx, Y + TLy, TLw, TLh, "Horizontally Resized");
TR->align(FL_ALIGN_TOP_LEFT);
Fl_Group *LG = new Fl_Group(X + TLx, Y + LGy, TLw, LGh);
LG->box(FL_NO_BOX);
LG->color(FL_WHITE);
LA = new Harrow(TL->m_group->x(), LG->y(), TL->m_group->w(), LAh, "Initial\nwidth");
LG->resizable(LA);
LG->end();
Fl_Group *RG = new Fl_Group(X + TRx, Y + LGy, TLw, LGh);
RG->box(FL_NO_BOX);
RG->color(FL_WHITE);
RA = new Harrow(TR->m_group->x(), RG->y(), TR->m_group->w(), LAh, "Resized\nwidth");
RG->resizable(RA);
RG->end();
this->resizable(TR);
this->end();
}
int main(int argc, char **argv) {
window = new Fl_Double_Window(Ww, Wh, "resize-example5a");
window->color(FL_WHITE);
Resizables *resizables = new Resizables(0, 0, Ww, Wh);
window->end();
window->resizable(resizables);
window->size_range(Ww, Wh);
window->show(argc, argv);
window->size(Ww + 90, Wh);
return Fl::run();
}

122
test/resize-example5b.cxx Normal file
View File

@ -0,0 +1,122 @@
//
// Resize example for use in the Fast Light Tool Kit (FLTK) documentation.
//
// See Article #415: How does resizing work?
// https://www.fltk.org/articles.php?L415
//
// Copyright 1998-2020 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#include "resize-arrows.h"
#include <FL/Fl_Double_Window.H>
// window, simplex and arrow dimensions
int TLx = 35, TRx = 320, TLw = 260, Ww = 620;
int TLy = 35, LGy = 125, TLh = 90, LGh = 70, LAh = 35, Wh = 200;
Fl_Double_Window *window = 0;
class Simplex : public Fl_Group {
public:
Simplex(int X, int Y, int W, int H, const char *T = 0);
Fl_Box *m_boxA, *m_boxB, *m_boxC, *m_boxI;
Fl_Group *m_group, *m_groupL, *m_groupR;
};
Simplex::Simplex(int X, int Y, int W, int H, const char *T)
: Fl_Group(X, Y, W, H, T) {
this->box(FL_UP_BOX);
m_group = new Fl_Group(X + 10, Y + 10, 240, 70);
m_group->box(FL_UP_BOX);
m_groupL = new Fl_Group(X + 10, Y + 15, 145, 35, "AB group");
m_groupL->align(FL_ALIGN_BOTTOM_LEFT);
m_groupL->box(FL_UP_BOX);
m_groupL->color(FL_RED);
m_groupL->labelcolor(FL_RED);
m_boxA = new Fl_Box(X + 20, Y + 20, 80, 25, "A");
m_boxA->box(FL_UP_BOX);
m_boxA->color(FL_YELLOW);
m_boxB = new Fl_Box(X + 110, Y + 20, 40, 25, "B");
m_boxB->box(FL_UP_BOX);
m_groupL->resizable(m_boxA);
m_groupL->end();
m_groupR = new Fl_Group(X + 155, Y + 15, 95, 35, "C group");
m_groupR->align(FL_ALIGN_BOTTOM_RIGHT);
m_groupR->box(FL_UP_BOX);
m_groupR->color(FL_BLUE);
m_groupR->labelcolor(FL_BLUE);
m_boxC = new Fl_Box(X + 160, Y + 20, 80, 25, "C");
m_boxC->box(FL_UP_BOX);
m_boxC->color(FL_YELLOW);
m_groupR->resizable(m_boxC);
m_groupR->end();
int d = 20;
m_boxI = new Fl_Box(X + 155 - d, Y + 55, 2 * d, 10);
m_boxI->box(FL_UP_BOX);
m_boxI->color(FL_YELLOW);
m_group->resizable(m_boxI);
m_group->end();
this->resizable(m_group);
this->end();
}
class Resizables : public Fl_Group {
public:
Resizables(int X, int Y, int W, int H, const char *T = 0);
Simplex *TL, *TR; // top left, top right
Harrow *LA, *RA; // left arrow, right arrow
};
Resizables::Resizables(int X, int Y, int W, int H, const char *T)
: Fl_Group(X, Y, W, H, T) {
TL = new Simplex(X + TLx, Y + TLy, TLw, TLh, "Original");
TL->align(FL_ALIGN_TOP_LEFT);
TR = new Simplex(X + TRx, Y + TLy, TLw, TLh, "Horizontally Resized");
TR->align(FL_ALIGN_TOP_LEFT);
Fl_Group *LG = new Fl_Group(X + TLx, Y + LGy, TLw, LGh);
LG->box(FL_NO_BOX);
LG->color(FL_WHITE);
LA = new Harrow(TL->m_boxI->x(), LG->y(), TL->m_boxI->w(), LAh, "Initial\nwidth");
LG->resizable(LA);
LG->end();
Fl_Group *RG = new Fl_Group(X + TRx, Y + LGy, TLw, LGh);
RG->box(FL_NO_BOX);
RG->color(FL_WHITE);
RA = new Harrow(TR->m_boxI->x(), RG->y(), TR->m_boxI->w(), LAh, "Resized\nwidth");
RG->resizable(RA);
RG->end();
this->resizable(TR);
this->end();
}
int main(int argc, char **argv) {
window = new Fl_Double_Window(Ww, Wh, "resize-example5b");
window->color(FL_WHITE);
Resizables *resizables = new Resizables(0, 0, Ww, Wh);
window->end();
window->resizable(resizables);
window->size_range(Ww, Wh);
window->show(argc, argv);
window->size(Ww + 90, Wh);
return Fl::run();
}

114
test/resize-example5c.cxx Normal file
View File

@ -0,0 +1,114 @@
//
// Resize example for use in the Fast Light Tool Kit (FLTK) documentation.
//
// See Article #415: How does resizing work?
// https://www.fltk.org/articles.php?L415
//
// Copyright 1998-2020 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#include "resize-arrows.h"
#include <FL/Fl_Double_Window.H>
// window, simplex and arrow dimensions
int TLx = 35, TRx = 320, TLw = 260, Ww = 620;
int TLy = 35, LGy = 100, TLh = 65, LGh = 70, LAh = 35, Wh = 175;
Fl_Double_Window *window = 0;
class Simplex : public Fl_Group {
public:
Simplex(int X, int Y, int W, int H, const char *T = 0);
Fl_Box *m_boxA, *m_boxB, *m_boxC, *m_boxI;
Fl_Group *m_group, *m_groupL, *m_groupR;
};
Simplex::Simplex(int X, int Y, int W, int H, const char *T)
: Fl_Group(X, Y, W, H, T) {
this->box(FL_UP_BOX);
m_group = new Fl_Group(X + 10, Y + 10, 240, 45);
m_group->box(FL_UP_BOX);
m_groupL = new Fl_Group(X + 10, Y + 15, 145, 35);
m_groupL->box(FL_NO_BOX);
m_boxA = new Fl_Box(X + 20, Y + 20, 80, 25, "A");
m_boxA->box(FL_UP_BOX);
m_boxB = new Fl_Box(X + 110, Y + 20, 40, 25, "B");
m_boxB->box(FL_UP_BOX);
m_groupL->resizable(m_boxA);
m_groupL->end();
m_groupR = new Fl_Group(X + 155, Y + 15, 95, 35);
m_groupR->box(FL_NO_BOX);
m_boxC = new Fl_Box(X + 160, Y + 20, 80, 25, "C");
m_boxC->box(FL_UP_BOX);
m_groupR->resizable(m_boxC);
m_groupR->end();
int d = 20;
m_boxI = new Fl_Box(X + 155 - d, Y + 40, 2 * d, 5);
m_boxI->box(FL_FLAT_BOX);
m_boxI->color(FL_YELLOW);
m_group->resizable(m_boxI);
m_group->end();
this->resizable(m_group);
this->end();
}
class Resizables : public Fl_Group {
public:
Resizables(int X, int Y, int W, int H, const char *T = 0);
Simplex *TL, *TR; // top left, top right
Harrow *LA, *RA; // left arrow, right arrow
};
Resizables::Resizables(int X, int Y, int W, int H, const char *T)
: Fl_Group(X, Y, W, H, T) {
TL = new Simplex(X + TLx, Y + TLy, TLw, TLh, "Original");
TL->align(FL_ALIGN_TOP_LEFT);
TR = new Simplex(X + TRx, Y + TLy, TLw, TLh, "Horizontally Resized");
TR->align(FL_ALIGN_TOP_LEFT);
Fl_Group *LG = new Fl_Group(X + TLx, Y + LGy, TLw, LGh);
LG->box(FL_NO_BOX);
LG->color(FL_WHITE);
LA = new Harrow(TL->m_boxI->x(), LG->y(), TL->m_boxI->w(), LAh, "Initial\nwidth");
LG->resizable(LA);
LG->end();
Fl_Group *RG = new Fl_Group(X + TRx, Y + LGy, TLw, LGh);
RG->box(FL_NO_BOX);
RG->color(FL_WHITE);
RA = new Harrow(TR->m_boxI->x(), RG->y(), TR->m_boxI->w(), LAh, "Resized\nwidth");
RG->resizable(RA);
RG->end();
this->resizable(TR);
this->end();
}
int main(int argc, char **argv) {
window = new Fl_Double_Window(Ww, Wh, "resize-example5c");
window->color(FL_WHITE);
Resizables *resizables = new Resizables(0, 0, Ww, Wh);
window->end();
window->resizable(resizables);
window->size_range(Ww, Wh);
window->show(argc, argv);
window->size(Ww + 90, Wh);
return Fl::run();
}