diff --git a/documentation/src/resize-example5a.png b/documentation/src/resize-example5a.png
new file mode 100644
index 000000000..0bb170688
Binary files /dev/null and b/documentation/src/resize-example5a.png differ
diff --git a/documentation/src/resize-example5b.png b/documentation/src/resize-example5b.png
new file mode 100644
index 000000000..165a2c43e
Binary files /dev/null and b/documentation/src/resize-example5b.png differ
diff --git a/documentation/src/resize-example5c.png b/documentation/src/resize-example5c.png
new file mode 100644
index 000000000..78a96f635
Binary files /dev/null and b/documentation/src/resize-example5c.png differ
diff --git a/documentation/src/resize.dox b/documentation/src/resize.dox
index 348625cf9..c3b30daf9 100644
--- a/documentation/src/resize.dox
+++ b/documentation/src/resize.dox
@@ -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 "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 "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 hide() 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 "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
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 160efe21a..1ae931910 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -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)
diff --git a/test/demo.menu b/test/demo.menu
index f53b0ede3..c865fe5d4 100644
--- a/test/demo.menu
+++ b/test/demo.menu
@@ -106,3 +106,5 @@
@ir:Example\n3c:resize-example3c
@ir:Example\n4a:resize-example4a
@ir:Example\n4b:resize-example4b
+ @ir:Example\n5a:resize-example5a
+ @ir:Example\n5b:resize-example5b
diff --git a/test/makedepend b/test/makedepend
index 0a24d8603..3eac520e7 100644
--- a/test/makedepend
+++ b/test/makedepend
@@ -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
diff --git a/test/resize-example5a.cxx b/test/resize-example5a.cxx
new file mode 100644
index 000000000..e3e8b7709
--- /dev/null
+++ b/test/resize-example5a.cxx
@@ -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
+
+// 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();
+}
diff --git a/test/resize-example5b.cxx b/test/resize-example5b.cxx
new file mode 100644
index 000000000..62680b6dc
--- /dev/null
+++ b/test/resize-example5b.cxx
@@ -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
+
+// 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();
+}
diff --git a/test/resize-example5c.cxx b/test/resize-example5c.cxx
new file mode 100644
index 000000000..b824009fe
--- /dev/null
+++ b/test/resize-example5c.cxx
@@ -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
+
+// 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();
+}