From f37aca15e9786a7192e36ea4b0295ab4dc12819f Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Thu, 28 Jul 2022 18:26:07 +0200 Subject: [PATCH] Add Fl_Flex widget from Karsten Pedersen (issue #255) This work is based on the repository and latest commit: https://github.com/osen/FL_Flex.git commit 36e4ed75a00daac825b87e81295818b4650991f5 Author: Karsten Pedersen <...> Date: Fri Apr 23 12:06:16 2021 +0000 Added Fltk (LGPL) license. This widget is similar to Fl_Pack and supports either one row or one column of widgets but has some more features. Test and demo programs are included: test/flex_login.cxx: simple "login window" demo program test/flex_demo.cxx: slightly more complex demo program The original demo programs can still be compiled and built with the new widget provided you '#include '. Backwards compatible methods are included (except debug()). The original widget has been modified to match FLTK standards and enhanced in several ways, including: - support box frames - add HORIZONTAL and VERTICAL enum values (as in Fl_Pack) - add horizontal() method (as in Fl_Pack) - use type() rather than internal 'direction' variable - add standard widget constructor (x, y, w, h, label) - add margin and gap accessors rather than hard coding constants - improve test and demo programs - add documentation - replace with array as required by FLTK CMP - rename camelCase method names, keeping old names for compatibility: - change 'setSize(Fl_Widget*, int)' to 'set_size(Fl_Widget*, int)' - change 'bool isSetSize(Fl_Widget*)' to 'int set_size(Fl_Widget*)' - remove debug() method - add a way to "unset" fixed size: set_size(Fl_Widget *, 0) - add layout() method to force recalculation of children - unify resizeRow() and resizeCol() methods to avoid code duplication - improve widget size calculation. --- FL/Fl_Flex.H | 161 +++++++++++++++++++++ src/CMakeLists.txt | 1 + src/Fl_Flex.cxx | 332 ++++++++++++++++++++++++++++++++++++++++++++ src/Makefile | 1 + src/makedepend | 2 + test/.gitignore | 2 + test/CMakeLists.txt | 2 + test/Makefile | 8 ++ test/flex_demo.cxx | 168 ++++++++++++++++++++++ test/flex_login.cxx | 131 +++++++++++++++++ test/makedepend | 40 ++++++ 11 files changed, 848 insertions(+) create mode 100644 FL/Fl_Flex.H create mode 100644 src/Fl_Flex.cxx create mode 100644 test/flex_demo.cxx create mode 100644 test/flex_login.cxx diff --git a/FL/Fl_Flex.H b/FL/Fl_Flex.H new file mode 100644 index 000000000..3d3784492 --- /dev/null +++ b/FL/Fl_Flex.H @@ -0,0 +1,161 @@ +// +// Fl_Flex widget header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 2020 by Karsten Pedersen +// Copyright 2022 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 +// + +#ifndef Fl_Flex_H +#define Fl_Flex_H + +#include + +class FL_EXPORT Fl_Flex : public Fl_Group { + + int margin_; + int gap_; + int set_size_size_; + int set_size_alloc_; + Fl_Widget **set_size_; + +public: + + enum { // values for type(int) + VERTICAL = 0, ///< vertical layout (one column) + HORIZONTAL = 1, ///< horizontal layout (one row) + COLUMN = 0, ///< alias for VERTICAL + ROW = 1 ///< alias for HORIZONTAL + }; + + // FLTK standard constructor + Fl_Flex(int X, int Y, int W, int H, const char *L = 0); + + // original Fl_Flex constructors: + // backwards compatible if direction *names* { ROW | COLUMN } are used + + Fl_Flex(int direction); + Fl_Flex(int w, int h, int direction); + Fl_Flex(int x, int y, int w, int h, int direction); + + virtual ~Fl_Flex(); + + virtual void end(); + virtual void resize(int x, int y, int w, int h); + + void set_size(Fl_Widget *w, int size); + int set_size(Fl_Widget *w); + +protected: + + void init(int t = VERTICAL); + + int alloc_size(int size); + +public: + + /** Return the margin size of the widget. + \return margin size. + */ + int margin() { return margin_; } + + /** Set the margin and optionally the gap size of the widget. + This method can be used to set both the margin and the gap size. + + If you don't use the second parameter \p g or supply a negative value + the gap size is not changed. + + The margin is some free space inside the widget border \b around all child + widgets. It has the same size at all four edges of the Fl_Flex widget. + + The gap size \p g is some free space \b between child widgets. + + \param[in] m margin size, must be \>= 0 + \param[in] g gap size, must be \>= 0, or will be ignored (if negative) + + \see gap(int) + */ + + void margin(int m, int g = -1) { + margin_ = m < 0 ? 0 : m; + if (g >= 0) + gap_ = g; + } + + /** Return the gap size of the widget. + \return gap size between all child widgets. + */ + int gap() { return gap_; } + + /** + Set the gap size of the widget. + + The gap size is some free space \b between child widgets. + The size must be \>= 0. Negative values are clamped to 0. + + \param[in] g gap size + */ + void gap(int g) { + gap_ = g < 0 ? 0 : g; + } + + /** Returns non-zero (true) if Fl_Flex alignment is horizontal (row mode). + + \returns non-zero if Fl_Flex alignment is horizontal + \retval 1 if type() == Fl_Flex::HORIZONTAL + \retval 0 if type() == Fl_Flex::VERTICAL + + See class Fl_Flex documentation for details. + */ + int horizontal() const { + return type() == Fl_Flex::HORIZONTAL ? 1 : 0; + } + + /** + Calculates the layout of the widget and redraws it. + + If you change widgets in the Fl_Flex container you should call this method + to force recalculation of child widget sizes and positions. This can be + useful (necessary) if you hide(), show(), add() or remove() children. + + This method also calls redraw() on the Fl_Flex widget. + */ + void layout() { + resize(x(), y(), w(), h()); + redraw(); + } + +#if (1) + + // Additional methods for backwards compatibility with "original" Fl_Flex widget + + /** + Deprecated. + \deprecated Please use set_size(Fl_Widget *) instead. + */ + bool isSetSize(Fl_Widget *w) { + return (bool)set_size(w); + } + + /** + Set the horizontal or vertical size of a child widget. + \deprecated Please use set_size(Fl_Widget *, int) instead. + */ + void setSize(Fl_Widget *w, int size) { + set_size(w, size); + } + +#endif + +}; + +#endif // Fl_Flex_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 405dd302b..63b5b8399 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,6 +39,7 @@ set (CPPFILES Fl_File_Chooser2.cxx Fl_File_Icon.cxx Fl_File_Input.cxx + Fl_Flex.cxx Fl_Graphics_Driver.cxx Fl_Group.cxx Fl_Help_View.cxx diff --git a/src/Fl_Flex.cxx b/src/Fl_Flex.cxx new file mode 100644 index 000000000..ac1a8551f --- /dev/null +++ b/src/Fl_Flex.cxx @@ -0,0 +1,332 @@ +// +// Fl_Flex widget implementation for the Fast Light Tool Kit (FLTK). +// +// Copyright 2020 by Karsten Pedersen +// Copyright 2022 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 +#include + +/** + Construct a new Fl_Flex widget with the given position, size, and label. + + Fl_Flex is a container (layout) widget that provides flexible positioning + of its children either in one row or in one column. Fl_Flex containers can + be nested so you can create flexible layouts with multiple columns and rows. + + Fl_Flex is designed to be as simple as possible. You can set particular + widget sizes or let Fl_Flex position and size the widgets to fit the container. + + You can set the margin \b around all children at the inner side the box frame + (if any). This margin has the same size on top, bottom, and both sides. + The default margin size is 3. + + You can set the gap size \b between all children. The gap size is the same between + all children. This is similar to the 'spacing' of Fl_Pack. + The default gap size is 3. + + Fl_Flex can either consist of a single row, i.e. type() = Fl_Flex::HORIZONTAL, + or a single column, i.e. type() = Fl_Flex::VERTICAL. The default value is + \p VERTICAL for consistency with Fl_Pack but you can use \p type() to assign + a row (\p HORIZONTAL) layout. + + If type() == Fl_Flex::HORIZONTAL widgets are resized horizontally to fit in + the container and their height is the full Fl_Flex height minus border size + and margin. You can set a fixed widget width by using set_size(). + + If type() == Fl_Flex::VERTICAL the above description applies equivalently + to the row layout, i.e. widget heights can be set etc. + + Alternate constructors let you specify the layout as Fl_Flex::HORIZONTAL or + Fl_Flex::VERTICAL directly. Fl_Flex::ROW is an alias of Fl_Flex::HORIZONTAL + and Fl_Flex::COLUMN is an alias of Fl_Flex::VERTICAL. + + \note Please use the names (enum) rather than numerical values for + the type() argument and the \p direction parameter of the alternate + constructors. These constructors are backwards compatible with older + versions of Fl_Flex. + + \param[in] X,Y position + \param[in] W,H size (width and height) + \param[in] L label (optional) + + \see Fl_Flex::Fl_Flex(int direction) + \see Fl_Flex::Fl_Flex(int w, int h, int direction) + \see Fl_Flex::Fl_Flex(int x, int y, int w, int h, int direction) + \see Fl_Flex::Fl_Flex(int x, int y, int w, int h, const char *L) +*/ +Fl_Flex::Fl_Flex(int X, int Y, int W, int H, const char *L) + : Fl_Group(X, Y, W, H, L) { + init(); + } + +// special Fl_Flex constructors w/o label (backwards compatible with original Fl_Flex widget) + +/** + Construct a new Fl_Flex object specifying its layout. + + Use Fl_Flex::HORIZONTAL (aka Fl_Flex::ROW) or Fl_Flex::VERTICAL + (aka Fl_Flex::COLUMN) as the \p direction argument. + + This constructor sets the position and size to (0, 0, 0, 0) which is suitable + for nested Fl_Flex widgets. Use one of the other constructors to set the + desired position and size as well. + + \param[in] direction horizontal (row) or vertical (column) layout + + \see Fl_Flex::Fl_Flex(int w, int h, int direction) + \see Fl_Flex::Fl_Flex(int x, int y, int w, int h, int direction) + \see Fl_Flex::Fl_Flex(int x, int y, int w, int h, const char *L) +*/ +Fl_Flex::Fl_Flex(int direction) + : Fl_Group(0, 0, 0, 0, 0) { + init(direction); +} + +/** + Construct a new Fl_Flex object specifying its layout and size. + + Use Fl_Flex::HORIZONTAL (aka Fl_Flex::ROW) or Fl_Flex::VERTICAL + (aka Fl_Flex::COLUMN) as the \p direction argument. + + This constructor sets the position to (x = 0, y = 0) which is suitable + for nested Fl_Flex widgets. Use one of the other constructors to set the + desired position as well. + + + \param[in] w,h widget size + \param[in] direction horizontal (row) or vertical (column) layout + + \see Fl_Flex::Fl_Flex(int direction) + \see Fl_Flex::Fl_Flex(int x, int y, int w, int h, int direction) + \see Fl_Flex::Fl_Flex(int x, int y, int w, int h, const char *L) + +*/ +Fl_Flex::Fl_Flex(int w, int h, int direction) + : Fl_Group(0, 0, w, h, 0) { + init(direction); +} + + +/** + Construct a new Fl_Flex object specifying its layout, position, and size. + + Use Fl_Flex::HORIZONTAL (aka Fl_Flex::ROW) or Fl_Flex::VERTICAL + (aka Fl_Flex::COLUMN) as the \p direction argument. + + This constructor sets the position and size of the widget which is suitable + for outer Fl_Flex widgets but does not set a widget label. + Use Fl_Widget::label() to set one if required. + + \param[in] x,y widget position + \param[in] w,h widget size + \param[in] direction horizontal (row) or vertical (column) layout + + \see Fl_Flex::Fl_Flex(int direction) + \see Fl_Flex::Fl_Flex(int w, int h, int direction) + \see Fl_Flex::Fl_Flex(int x, int y, int w, int h, const char *L) + +*/ + +Fl_Flex::Fl_Flex(int x, int y, int w, int h, int direction) + : Fl_Group(x, y, w, h, 0) { + init(direction); +} + +void Fl_Flex::init(int t) { + gap_ = 3; // default gap size + margin_ = 3; // default margin size + set_size_ = 0; // array of fixed size widgets + set_size_size_ = 0; // number of fixed size widgets + set_size_alloc_ = 0; // allocated size of array of fixed size widgets + type(HORIZONTAL); + if (t == VERTICAL) + type(VERTICAL); +} + +Fl_Flex::~Fl_Flex() { + if (set_size_) + free(set_size_); +} + +void Fl_Flex::resize(int x, int y, int w, int h) { + + Fl_Widget::resize(x, y, w, h); + + int cc = children(); + + int dx = Fl::box_dx(box()); + int dy = Fl::box_dy(box()); + int dw = Fl::box_dw(box()); + int dh = Fl::box_dh(box()); + + // Calculate total space minus gaps + int gaps = cc > 1 ? cc - 1 : 0; + int hori = horizontal(); + int space = (hori ? w - dw : h - dh) - 2 * margin_; + + // set x and y (start) position, calculate widget sizes + int xp = x + dx + margin_; + int yp = y + dy + margin_; + int hh = h - dh - margin_ * 2; // if horizontal: constant height of widgets + int vw = w - dw - margin_ * 2; // if vertical: constant width of widgets + + int fw = cc; // number of flexible widgets + + // Precalculate remaining space that can be distributed + + for (int i = 0; i < cc; i++) { + Fl_Widget *c = child(i); + if (c->visible()) { + if (set_size(c)) { + space -= (hori ? c->w() : c->h()); + fw--; + } + } else { // hidden widget + fw--; + gaps--; + } + } + + if (gaps > 0) + space -= gaps * gap_; + + // Set children to shared width/height of remaining space + + int sp = 0; // width or height of flexible widget + int rem = 0; // remainder (to be distributed evenly) + if (fw > 0) { + sp = space / fw; + rem = space % fw; + if (rem) // adjust space for first 'rem' widgets + sp++; + } + + for (int i = 0; i < cc; i++) { + Fl_Widget *c = child(i); + if (!c->visible()) + continue; + + if (hori) { + if (set_size(c)) { + c->resize(xp, yp, c->w(), hh); + } else { + c->resize(xp, yp, sp, hh); + if (--rem == 0) sp--; + } + xp += c->w() + gap_; + } else { + if (set_size(c)) { + c->resize(xp, yp, vw, c->h()); + } else { + c->resize(xp, yp, vw, sp); + if (--rem == 0) sp--; + } + yp += c->h() + gap_; + } + } + +} // resize() + +/** + Ends automatic child addition and resizes all children. + + This calculates the layout depending on all children and whether + they have been assigned fix sizes or not. +*/ +void Fl_Flex::end() { + Fl_Group::end(); + resize(x(), y(), w(), h()); +} + +/** + Set the horizontal or vertical size of a child widget. + + This sets either the width or height of a child widget, depending on the + type() of the Fl_Flex container (Fl_Flex::HORIZONTAL or Fl_Flex::VERTICAL). + The other dimension is set to the full width or height of the Fl_Flex widget. + + This can be used to set a fixed widget width or height of children + of Fl_Flex so they are not resized dynamically. + + If \p size is 0 (zero) or negative the widget size is reset to flexible size. + + \param[in] w widget to be affected + \param[in] size width (Fl_Flex::HORIZONTAL) or height (Fl_Flex::VERTICAL) +*/ +void Fl_Flex::set_size(Fl_Widget *w, int size) { + if (size <= 0) + size = 0; + w->resize(0, 0, size, size); + + int idx = -1; + for (int i = 0; i < set_size_size_; i++) { + if (set_size_[i] == w) { + idx = i; + break; + } + } + + // remove from array ? + if (size == 0 && idx >= 0) { + for (int i = idx; i < set_size_size_ - 2; i++) { + set_size_[i] = set_size_[i+1]; + } + set_size_size_--; + return; + } + + // add to array of fixed size widgets + if (set_size_size_ == set_size_alloc_) { + set_size_alloc_ = alloc_size(set_size_alloc_); + set_size_ = (Fl_Widget **)realloc(set_size_, set_size_alloc_ * sizeof(Fl_Widget *)); + } + set_size_[set_size_size_] = w; + set_size_size_++; +} + +/** + Return whether the given widget has a fixed size or resizes dynamically. + + \param[in] w widget + \return whether the widget has a fixed size + \retval 1 the widget has a fixed size + \retval 0 the widget resizes dynamically +*/ +int Fl_Flex::set_size(Fl_Widget *w) { + for (int i = 0; i < set_size_size_; i++) { + if (w == set_size_[i]) { + return 1; + } + } + return 0; +} + +/** + Return new size to be allocated for array of fixed size widgets. + + This method is called when the array of fixed size widgets needs to be + expanded. The current \p size is provided (size can be 0). The default + method adds 8 to the current size. + + This can be used in derived classes to change the allocation strategy. + Note that this method only \p queries the new size which shall be allocated + but does not allocate the memory. + + \param[in] size current size + \return int new size (to be allocated) +*/ +int Fl_Flex::alloc_size(int size) { + return size + 8; +} diff --git a/src/Makefile b/src/Makefile index c33847790..2a305394b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -42,6 +42,7 @@ CPPFILES = \ Fl_File_Chooser2.cxx \ Fl_File_Icon.cxx \ Fl_File_Input.cxx \ + Fl_Flex.cxx \ Fl_Graphics_Driver.cxx \ Fl_Group.cxx \ Fl_Help_View.cxx \ diff --git a/src/makedepend b/src/makedepend index bb4413ba5..78d0bc800 100644 --- a/src/makedepend +++ b/src/makedepend @@ -1828,6 +1828,8 @@ Fl_File_Input.o: ../FL/Fl_Window.H Fl_File_Input.o: ../FL/platform_types.h Fl_File_Input.o: flstring.h Fl_File_Input.o: Fl_System_Driver.H +Fl_Flex.o: ../FL/Fl_Flex.H +Fl_Flex.o: ../FL/Fl_Group.H fl_font.o: ../config.h fl_font.o: ../FL/Enumerations.H fl_font.o: ../FL/Fl.H diff --git a/test/.gitignore b/test/.gitignore index 6947a6d0c..49b1817e0 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -41,6 +41,8 @@ doublebuffer editor fast_slow file_chooser +flex_demo +flex_login fltk-versions fonts forms diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7e295e879..cfc189168 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -81,6 +81,8 @@ CREATE_EXAMPLE (doublebuffer doublebuffer.cxx fltk) CREATE_EXAMPLE (editor "editor.cxx;editor.plist" fltk) CREATE_EXAMPLE (fast_slow fast_slow.fl fltk) CREATE_EXAMPLE (file_chooser file_chooser.cxx "fltk_images;fltk") +CREATE_EXAMPLE (flex_demo flex_demo.cxx fltk) +CREATE_EXAMPLE (flex_login flex_login.cxx fltk) CREATE_EXAMPLE (fltk-versions fltk-versions.cxx fltk) CREATE_EXAMPLE (fonts fonts.cxx fltk) CREATE_EXAMPLE (forms forms.cxx "fltk_forms;fltk") diff --git a/test/Makefile b/test/Makefile index 49d56e7be..4b4f5691e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -74,6 +74,8 @@ CPPFILES =\ editor.cxx \ fast_slow.cxx \ file_chooser.cxx \ + flex_demo.cxx \ + flex_login.cxx \ fltk-versions.cxx \ fonts.cxx \ forms.cxx \ @@ -163,6 +165,8 @@ ALL = \ editor$(EXEEXT) \ fast_slow$(EXEEXT) \ file_chooser$(EXEEXT) \ + flex_demo$(EXEEXT) \ + flex_login$(EXEEXT) \ fltk-versions$(EXEEXT) \ fonts$(EXEEXT) \ forms$(EXEEXT) \ @@ -420,6 +424,10 @@ file_chooser$(EXEEXT): file_chooser.o $(IMGLIBNAME) $(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) file_chooser.o -o $@ $(LINKFLTKIMG) $(LDLIBS) $(OSX_ONLY) ../fltk-config --post $@ +flex_demo$(EXEEXT): flex_demo.o + +flex_login$(EXEEXT): flex_login.o + fltk-versions$(EXEEXT): fltk-versions.o fonts$(EXEEXT): fonts.o diff --git a/test/flex_demo.cxx b/test/flex_demo.cxx new file mode 100644 index 000000000..fb2b73cef --- /dev/null +++ b/test/flex_demo.cxx @@ -0,0 +1,168 @@ +// +// Fl_Flex demo program for the Fast Light Tool Kit (FLTK). +// +// Copyright 2020 by Karsten Pedersen +// Copyright 2022 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 +#include +#include +#include +#include +#include + +#define DEBUG_GROUP (0) + +void debug_group(Fl_Group *g) { +#if (DEBUG_GROUP) + printf("\nFl_Group (%p) has %d children:\n", g, g->children()); + for (int i = 0; i < g->children(); i++) { + Fl_Widget *c = g->child(i); + printf(" child %2d: hidden = %-5s, (x,y,w,h) = (%3d, %3d, %3d, %3d), label = '%s'\n", + i, c->visible() ? "false" : "true", c->x(), c->y(), c->w(), c->h(), + c->label() ? c->label() : "(null)"); + } +#endif +} // debug_group + +Fl_Button *createButton(const char *caption) { + Fl_Button *rtn = new Fl_Button(0, 0, 120, 30, caption); + rtn->color(fl_rgb_color(225, 225, 225)); + return rtn; +} + +void toggle_cb(Fl_Widget *w, void *v) { + static Fl_Box *b = 0; + Fl_Widget *o = (Fl_Widget *)v; + Fl_Flex *flex = (Fl_Flex *)o->parent(); + if (o->visible()) { + o->hide(); + w->label("show OK button"); + flex->child(1)->hide(); // hide Box + } else { + o->show(); + w->label("hide OK button"); + flex->child(1)->show(); // show Box + } + flex->layout(); + + debug_group(flex); + + // Yet another test: modify the first (top) Fl_Flex widget + + flex = (Fl_Flex *)(flex->parent()->child(0)); + Fl_Group::current(0); + if (!b) { + b = new Fl_Box(0, 0, 0, 0, "Box3"); + flex->insert(*b, flex->children() - 1); + } else { + delete b; + b = 0; + } + flex->layout(); + debug_group(flex); +} + +Fl_Flex *createRow() { + Fl_Flex *row = new Fl_Flex(Fl_Flex::ROW); + { + Fl_Button *toggle = createButton("hide OK button"); + toggle->tooltip("hide() or show() OK button"); + Fl_Box *box2 = new Fl_Box(0, 0, 120, 10, "Box2"); + Fl_Button * okay = createButton("OK"); + new Fl_Input(0, 0, 120, 10, ""); + + toggle->callback(toggle_cb, okay); + + Fl_Flex *col2 = new Fl_Flex(Fl_Flex::COLUMN); + { + createButton("Top2"); + createButton("Bottom2"); + col2->end(); + col2->margin(0, 5); + col2->box(FL_FLAT_BOX); + col2->color(fl_rgb_color(255, 128, 128)); + } + + row->set_size(box2, 50); + row->set_size(col2, 100); + row->end(); + + // TEST + row->box(FL_DOWN_BOX); + row->color(FL_GREEN); + } + + return row; +} + +int main(int argc, char **argv) { + + Fl_Window *window = new Fl_Double_Window(100, 100, "Simple GUI Example"); + { + Fl_Flex *col = new Fl_Flex(5, 5, 90, 90, Fl_Flex::COLUMN); + { + Fl_Flex *row = new Fl_Flex(Fl_Flex::ROW); + row->color(FL_YELLOW); + row->box(FL_FLAT_BOX); + { + createButton("Cancel"); + new Fl_Box(0, 0, 120, 10, "Box1"); + createButton("OK"); + new Fl_Input(0, 0, 120, 10, ""); + + Fl_Flex *col1 = new Fl_Flex(Fl_Flex::COLUMN); + { + createButton("Top1"); + createButton("Bottom1"); + col1->end(); + col1->box(FL_FLAT_BOX); + col1->color(fl_rgb_color(255, 128, 128)); + col1->margin(5, 5); + } + + row->end(); + } + col->set_size(createRow(), 90); + createButton("Something1"); + row = new Fl_Flex(Fl_Flex::ROW); + { + Fl_Button *cancel = createButton("Cancel"); + Fl_Button *ok = createButton("OK"); + new Fl_Input(0, 0, 120, 10, ""); + + row->set_size(cancel, 100); + row->set_size(ok, 100); + row->end(); + } + createButton("Something2"); + + col->set_size(row, 30); + col->margin(0, 6); + col->end(); + } + window->resizable(col); + window->color(fl_rgb_color(160, 180, 240)); + window->box(FL_FLAT_BOX); + window->end(); + } + + window->size_range(550, 330); + window->resize(0, 0, 640, 480); + window->show(argc, argv); + + int ret = Fl::run(); + delete window; + return ret; +} diff --git a/test/flex_login.cxx b/test/flex_login.cxx new file mode 100644 index 000000000..3923bcde3 --- /dev/null +++ b/test/flex_login.cxx @@ -0,0 +1,131 @@ +// +// Fl_Flex demo program for the Fast Light Tool Kit (FLTK). +// +// Copyright 2020 by Karsten Pedersen +// Copyright 2022 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 +#include +#include +#include +#include +#include + +Fl_Button *createButton(const char *caption) { + Fl_Button *rtn = new Fl_Button(0, 0, 100, 25, caption); + rtn->color(fl_rgb_color(225, 225, 225)); + return rtn; +} + +void buttonsPanel(Fl_Flex *parent) { + new Fl_Box(0, 0, 0, 0, ""); + Fl_Box *w = new Fl_Box(0, 0, 0, 0, "Welcome to Flex Login"); + + Fl_Flex *urow = new Fl_Flex(Fl_Flex::ROW); + { + Fl_Box *b = new Fl_Box(0, 0, 0, 0, "Username:"); + b->align(FL_ALIGN_INSIDE | FL_ALIGN_RIGHT); + Fl_Input *username = new Fl_Input(0, 0, 0, 0, ""); + + urow->set_size(username, 180); + urow->end(); + } + + Fl_Flex *prow = new Fl_Flex(Fl_Flex::ROW); + { + Fl_Box *b = new Fl_Box(0, 0, 0, 0, "Password:"); + b->align(FL_ALIGN_INSIDE | FL_ALIGN_RIGHT); + Fl_Input *password = new Fl_Input(0, 0, 0, 0, ""); + + prow->set_size(password, 180); + prow->end(); + } + + Fl_Box *pad = new Fl_Box(0, 0, 0, 0, ""); + + Fl_Flex *brow = new Fl_Flex(Fl_Flex::ROW); + { + new Fl_Box(0, 0, 0, 0, ""); + Fl_Button *reg = createButton("Register"); + Fl_Button *login = createButton("Login"); + + brow->set_size(reg, 80); + brow->set_size(login, 80); + brow->gap(20); + + brow->end(); + } + + Fl_Box *b = new Fl_Box(0, 0, 0, 0, ""); + + parent->set_size(w, 60); + parent->set_size(urow, 30); + parent->set_size(prow, 30); + parent->set_size(pad, 1); + parent->set_size(brow, 30); + parent->set_size(b, 30); +} + +void middlePanel(Fl_Flex *parent) { + new Fl_Box(0, 0, 0, 0, ""); + + Fl_Box *box = new Fl_Box(0, 0, 0, 0, "Image"); + box->box(FL_BORDER_BOX); + box->color(fl_rgb_color(0, 200, 0)); + Fl_Box *spacer = new Fl_Box(0, 0, 0, 0, ""); + + Fl_Flex *bp = new Fl_Flex(Fl_Flex::COLUMN); + buttonsPanel(bp); + bp->end(); + + new Fl_Box(0, 0, 0, 0, ""); + + parent->set_size(box, 200); + parent->set_size(spacer, 10); + parent->set_size(bp, 300); +} + +void mainPanel(Fl_Flex *parent) { + new Fl_Box(0, 0, 0, 0, ""); + + Fl_Flex *mp = new Fl_Flex(Fl_Flex::ROW); + middlePanel(mp); + mp->end(); + + new Fl_Box(0, 0, 0, 0, ""); + + parent->set_size(mp, 200); +} + +int main(int argc, char **argv) { + + Fl_Window *window = new Fl_Double_Window(100, 100, "Simple GUI Example"); + { + Fl_Flex *col = new Fl_Flex(5, 5, 90, 90, Fl_Flex::COLUMN); + mainPanel(col); + col->end(); + + window->resizable(col); + window->color(fl_rgb_color(250, 250, 250)); + window->end(); + } + + window->resize(0, 0, 640, 480); + window->size_range(550, 250); + window->show(argc, argv); + + int ret = Fl::run(); + delete window; + return ret; +} diff --git a/test/makedepend b/test/makedepend index 3fbcd2262..a3e88fdd3 100644 --- a/test/makedepend +++ b/test/makedepend @@ -857,6 +857,46 @@ file_chooser.o: ../FL/Fl_Valuator.H file_chooser.o: ../FL/Fl_Widget.H file_chooser.o: ../FL/Fl_Window.H file_chooser.o: ../FL/platform_types.h +flex_demo.o: ../FL/Enumerations.H +flex_demo.o: ../FL/Fl.H +flex_demo.o: ../FL/Fl_Bitmap.H +flex_demo.o: ../FL/Fl_Box.H +flex_demo.o: ../FL/Fl_Button.H +flex_demo.o: ../FL/Fl_Cairo.H +flex_demo.o: ../FL/fl_casts.H +flex_demo.o: ../FL/fl_config.h +flex_demo.o: ../FL/Fl_Double_Window.H +flex_demo.o: ../FL/Fl_Export.H +flex_demo.o: ../FL/Fl_Flex.H +flex_demo.o: ../FL/Fl_Group.H +flex_demo.o: ../FL/Fl_Image.H +flex_demo.o: ../FL/Fl_Input.H +flex_demo.o: ../FL/Fl_Input_.H +flex_demo.o: ../FL/fl_types.h +flex_demo.o: ../FL/fl_utf8.h +flex_demo.o: ../FL/Fl_Widget.H +flex_demo.o: ../FL/Fl_Window.H +flex_demo.o: ../FL/platform_types.h +flex_login.o: ../FL/Enumerations.H +flex_login.o: ../FL/Fl.H +flex_login.o: ../FL/Fl_Bitmap.H +flex_login.o: ../FL/Fl_Box.H +flex_login.o: ../FL/Fl_Button.H +flex_login.o: ../FL/Fl_Cairo.H +flex_login.o: ../FL/fl_casts.H +flex_login.o: ../FL/fl_config.h +flex_login.o: ../FL/Fl_Double_Window.H +flex_login.o: ../FL/Fl_Export.H +flex_login.o: ../FL/Fl_Flex.H +flex_login.o: ../FL/Fl_Group.H +flex_login.o: ../FL/Fl_Image.H +flex_login.o: ../FL/Fl_Input.H +flex_login.o: ../FL/Fl_Input_.H +flex_login.o: ../FL/fl_types.h +flex_login.o: ../FL/fl_utf8.h +flex_login.o: ../FL/Fl_Widget.H +flex_login.o: ../FL/Fl_Window.H +flex_login.o: ../FL/platform_types.h fltk-versions.o: ../FL/Enumerations.H fltk-versions.o: ../FL/Fl.H fltk-versions.o: ../FL/fl_ask.H