diff options
| author | engelsman <engelsman@users.noreply.github.com> | 2021-12-08 15:00:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-08 15:00:33 +0100 |
| commit | 2d18c6f650c0001319c8883f8deb819d12984ac0 (patch) | |
| tree | 3fe72b80a2baadf7239cc40d9a0adedf9df9970f | |
| parent | eb7fb00801eb917ca1350d36ea896446cf4e5fb8 (diff) | |
Documentation on widget coordinates and layout, plus new test programs (#304)
Add coordinates and layout section to user manual
add section to user manual to clarify the use of window-relative
coordinates in both Fl_Group and Fl_Window containers, and include
brief descriptions of current layout manager widgets in one place.
add test/coordinates.cxx, test/wizard.cxx and related screenshots
under documentation/src.
update CMakeLists.txt, Makefile and .gitignore for new files.
Co-authored-by: Albrecht Schlosser <albrechts.fltk@online.de>
| -rw-r--r-- | documentation/Doxyfile.in | 1 | ||||
| -rw-r--r-- | documentation/Makefile | 1 | ||||
| -rw-r--r-- | documentation/src/common.dox | 4 | ||||
| -rw-r--r-- | documentation/src/coordinates.dox | 171 | ||||
| -rw-r--r-- | documentation/src/coordinates.png | bin | 0 -> 6913 bytes | |||
| -rw-r--r-- | documentation/src/editor.dox | 2 | ||||
| -rw-r--r-- | documentation/src/index.dox | 2 | ||||
| -rw-r--r-- | documentation/src/pack.png | bin | 0 -> 4041 bytes | |||
| -rw-r--r-- | documentation/src/resize.dox | 6 | ||||
| -rw-r--r-- | documentation/src/wizard.png | bin | 0 -> 1043 bytes | |||
| -rw-r--r-- | test/.gitignore | 2 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | test/coordinates.cxx | 125 | ||||
| -rw-r--r-- | test/wizard.cxx | 66 |
14 files changed, 376 insertions, 6 deletions
diff --git a/documentation/Doxyfile.in b/documentation/Doxyfile.in index 669795747..64d47ddb1 100644 --- a/documentation/Doxyfile.in +++ b/documentation/Doxyfile.in @@ -557,6 +557,7 @@ INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/preface.dox INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/intro.dox INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/basics.dox INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/common.dox +INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/coordinates.dox INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/resize.dox INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/editor.dox INPUT += @CMAKE_CURRENT_SOURCE_DIR@/src/drawing.dox diff --git a/documentation/Makefile b/documentation/Makefile index 43be79ffd..8fc0ca77c 100644 --- a/documentation/Makefile +++ b/documentation/Makefile @@ -29,6 +29,7 @@ HTMLFILES = \ $(SRC_DOCDIR)/intro.dox \ $(SRC_DOCDIR)/basics.dox \ $(SRC_DOCDIR)/common.dox \ + $(SRC_DOCDIR)/coordinates.dox \ $(SRC_DOCDIR)/resize.dox \ $(SRC_DOCDIR)/editor.dox \ $(SRC_DOCDIR)/drawing.dox \ diff --git a/documentation/src/common.dox b/documentation/src/common.dox index 4950065a5..ca2613f32 100644 --- a/documentation/src/common.dox +++ b/documentation/src/common.dox @@ -640,8 +640,8 @@ combined with any modifiers like \p Shift , \p Alt , and \p Control. <a class="el" href="index.html">[Index]</a> </td> <td width="45%" align="RIGHT"> - <a class="el" href="resize.html"> - How does resizing work? + <a class="el" href="coordinates.html"> + Coordinates and Layout Widgets [Next] </a> </td> diff --git a/documentation/src/coordinates.dox b/documentation/src/coordinates.dox new file mode 100644 index 000000000..ca996e64e --- /dev/null +++ b/documentation/src/coordinates.dox @@ -0,0 +1,171 @@ +/** + + \page coordinates Coordinates and Layout Widgets + +This chapter describes the coordinate systems that apply when +positioning widgets manually, and some of the basics of FLTK +layout widgets that are used to position widgets automatically. + + +\section coordinates_coordinates The widget coordinate system + +All widgets have constructors with \p x and \p y parameters to +let the programmer specify the desired initial position of the +top left corner during explicit manual layout within Fl_Window +and Fl_Group container widgets. + +This position is always relative to the enclosing Fl_Window, +which is usually, but not always, the top-level application +window, or a free-floating pop-up dialog window. +In some cases it could also be a subwindow embedded in a +higher-level window, as shown in the figure below. + +\image html coordinates.png "FLTK coordinate system" +\image latex coordinates.png "FLTK coordinate system" width=6cm + +The positions of the TL and BR sub-windows and the TR and BL +groups are all relative to the top-left corner of the main window. +The positions of the boxes inside the TR and BL groups are also +relative to the main window, but the boxes inside the TL and BR +sub-windows are positioned relative to the enclosing sub-window. + +In other words, the widget hierarchy and positions can be summarized as: +<pre> + Fl_Window main window + Fl_Window TL subwindow # x, y relative to main window + Fl_Box tl box # x, y relative to TL subwindow + Fl_Window BR subwindow # x, y relative to main window + Fl_Box br box # x, y relative to BR subwindow + Fl_Group TR group # x, y relative to main window + Fl_Box tr box # x, y relative to main window + Fl_Group BL group # x, y relative to main window + Fl_Box bl box # x, y relative to main window +</pre> + + +\section coordinate_layout Layout and container widgets + +There are four main groups of widgets derived from Fl_Group for +a range of different purposes. + +The first group are composite widgets that each contain a fixed +set of components that work together for a specific purpose, +rather than layout widgets as such, and are not discussed here. + +The second group are basically containers offering the same manual +layout features as Fl_Group, as described above, but which add one +new capability. These widgets are Fl_Scroll, Fl_Tabs and Fl_Wizard. + +The third group are layout managers that relocate and resize the +child widgets added to them in order to satisfy a particular layout +algorithm. These widgets are Fl_Pack and Fl_Tile. + +The final group consists of Fl_Window and its derivatives. +Their special capability is that they can be top-level application +windows and dialogs that interface with the operating system window +manager, but can also be embedded within other windows and groups +as shown in the example above. +Note that the window manager may impose its own constraints on +the position of top-level windows, and the \p x and \p y +position parameters may be treated as hints, or even ignored. +The Fl_Window class has an extra constructor that omits them. + + +\subsection coordinates_pack The Fl_Pack layout widget + +The Fl_Pack widget allows the layout of its direct children as a +single row, or column. +If its type() is set to give the row or horizontal layout, +the children are all resized to have the same height as the Fl_Pack +and are moved next to each other. +If set to give the column or vertical layout, the children are all +resized to have the same width as the Fl_Pack and are then stacked +below each other. +The Fl_Pack then resizes itself to shrink-wrap itself around all +of the children. + +Fl_Pack widgets are often used inside an Fl_Scroll, as shown in the +diagram below, to avoid having to deal with tricky resize behavior +when used with nested widgets. + +\image html pack.png "Fl_Pack test program screenshot" +\image latex pack.png "Fl_Pack test program screenshot" width=8cm + + +\subsection coordinates_scroll The Fl_Scroll container widget + +The Fl_Scroll container widget can hold an assortment of widgets +that may extend beyond its own width and height, in which case +horizontal and/or vertical scrollbars may appear automatically +so that you can scroll and view the entire contents. + +\image html Fl_Scroll.png "Fl_Scroll container widget" +\image latex Fl_Scroll.png "Fl_Scroll container widget" width=4cm + + +\subsection coordinates_tabs The Fl_Tabs container widget + +The Fl_Tabs widget provides a front-to-back stack of individual +panels which usually contain Fl_Group widgets and their children. +The user can switch between panels by clicking on the small +tabs that protrude from the panels. The appearance of each tab +is determined by the child widget's label and related attributes. + +\image html tabs.png "Fl_Tabs container widget" +\image latex tabs.png "Fl_Tabs container widget" width=8cm + + +\subsection coordinates_tile The Fl_Tile layout widget + +The Fl_Tile widget allows the user to resize one or more of its children +by dragging on the border between adjacent child widgets. +However, the programmer must first explicitly layout the child widgets +so that their borders exactly fill the width and height of the Fl_Tile +without having any gaps between them, or at the edges. +Some care is needed when initially positioning the children and setting +the resizable() widget within the Fl_Tile to prevent squeezing a child +to have a zero width or height. +For more information see the Fl_Tile widget manual page, and \ref resize. + + +\image html Fl_Tile.png "The Fl_Tile layout widget" +\image latex Fl_Tile.png "The Fl_Tile layout widget" width=4cm + + +\subsection coordinates_wizard The Fl_Wizard container widget + +The Fl_Wizard widget derives from the Fl_Tabs class, but instead +of having tabs that the user can click to select the corresponding +panel, the programmer uses the prev(), next() or value() methods +to show the appropriate panel. +For example, the user might be able to click on "Next" and "Prev" +navigation buttons or keys, as shown below. + +\image html wizard.png "FL_Wizard container widget" +\image latex wizard.png "FL_Wizard container widget" width=4cm + + +\htmlonly +<hr> +<table summary="navigation bar" width="100%" border="0"> +<tr> + <td width="45%" align="LEFT"> + <a class="el" href="common.html"> + [Prev] + Common Widgets and Attributes + </a> + </td> + <td width="10%" align="CENTER"> + <a class="el" href="index.html">[Index]</a> + </td> + <td width="45%" align="RIGHT"> + <a class="el" href="resize.html"> + How Does Resizing Work? + [Next] + </a> + </td> +</tr> +</table> +\endhtmlonly + +*/ diff --git a/documentation/src/coordinates.png b/documentation/src/coordinates.png Binary files differnew file mode 100644 index 000000000..d712474ef --- /dev/null +++ b/documentation/src/coordinates.png diff --git a/documentation/src/editor.dox b/documentation/src/editor.dox index 8a0eb3cd7..eaafe3aec 100644 --- a/documentation/src/editor.dox +++ b/documentation/src/editor.dox @@ -900,7 +900,7 @@ style_parse(const char *text, <td width="45%" align="LEFT"> <a class="el" href="resize.html"> [Prev] - How does resizing work? + How Does Resizing Work? </a> </td> <td width="10%" align="CENTER"> diff --git a/documentation/src/index.dox b/documentation/src/index.dox index 6e3bb4f53..e50474cce 100644 --- a/documentation/src/index.dox +++ b/documentation/src/index.dox @@ -43,6 +43,8 @@ - \ref common_labels - \ref drawing_images + \subpage coordinates + \subpage resize \subpage editor diff --git a/documentation/src/pack.png b/documentation/src/pack.png Binary files differnew file mode 100644 index 000000000..df87e06ef --- /dev/null +++ b/documentation/src/pack.png diff --git a/documentation/src/resize.dox b/documentation/src/resize.dox index c3b30daf9..29f687997 100644 --- a/documentation/src/resize.dox +++ b/documentation/src/resize.dox @@ -1,6 +1,6 @@ /** - \page resize How does resizing work? + \page resize How Does Resizing Work? This chapter describes the basic mechanism behind the creation of resizable user interface elements in FLTK. @@ -280,9 +280,9 @@ To summarize the key points of the new technique: <table summary="navigation bar" width="100%" border="0"> <tr> <td width="45%" align="LEFT"> - <a class="el" href="common.html"> + <a class="el" href="coordinates.html"> [Prev] - Common Widgets and Attributes + Coordinates and Layout Widgets </a> </td> <td width="10%" align="CENTER"> diff --git a/documentation/src/wizard.png b/documentation/src/wizard.png Binary files differnew file mode 100644 index 000000000..4357648d0 --- /dev/null +++ b/documentation/src/wizard.png diff --git a/test/.gitignore b/test/.gitignore index 53dc8498a..eb25c06d8 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -33,6 +33,7 @@ clipboard clock colbrowser color_chooser +coordinates cube CubeView CubeViewUI.cxx @@ -133,6 +134,7 @@ valuators valuators.cxx valuators.h windowfocus +wizard # macOS binary files diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 13a5f76f4..9169fc776 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -76,6 +76,7 @@ CREATE_EXAMPLE (clipboard clipboard.cxx "fltk_images;fltk") CREATE_EXAMPLE (clock clock.cxx fltk ANDROID_OK) CREATE_EXAMPLE (colbrowser colbrowser.cxx fltk) CREATE_EXAMPLE (color_chooser color_chooser.cxx fltk ANDROID_OK) +CREATE_EXAMPLE (coordinates coordinates.cxx fltk) CREATE_EXAMPLE (cursor cursor.cxx fltk ANDROID_OK) CREATE_EXAMPLE (curve curve.cxx fltk ANDROID_OK) CREATE_EXAMPLE (demo demo.cxx fltk) @@ -146,6 +147,7 @@ CREATE_EXAMPLE (utf8 utf8.cxx fltk) CREATE_EXAMPLE (valuators valuators.fl fltk) CREATE_EXAMPLE (unittests unittests.cxx fltk) CREATE_EXAMPLE (windowfocus windowfocus.cxx fltk) +CREATE_EXAMPLE (wizard wizard.cxx fltk) # create additional test programs (used by developers for testing) if (extra_tests) diff --git a/test/coordinates.cxx b/test/coordinates.cxx new file mode 100644 index 000000000..d888b7d46 --- /dev/null +++ b/test/coordinates.cxx @@ -0,0 +1,125 @@ +// +// Coordinate demonstration program for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2021 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 <FL/Fl.H> +#include <FL/Fl_Box.H> +#include <FL/Fl_Window.H> +#include <stdio.h> + +class Box : public Fl_Box { +public: + Box(int X, int Y, int W, int H, Fl_Color C, const char* T) + : Fl_Box(X, Y, W, H, T) { + align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER); + box(FL_DOWN_BOX); + labelcolor(C); + labelsize(11); + } +}; + +class Title : public Fl_Box { +public: + Title(int X, int Y, int W, int H, Fl_Color C, const char* T) + : Fl_Box(X, Y, W, H, T) { + align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER | FL_ALIGN_TOP); + box(FL_NO_BOX); + labelcolor(C); + labelsize(12); + } +}; + +class MainWindow : public Fl_Window { +public: + MainWindow(int X, int Y, const char* T) + : Fl_Window(X, Y, T) { + + Fl_Window* tl_window = new Fl_Window(0, 0, 250, 100); + tl_window->box(FL_ENGRAVED_BOX); + Title* tl_title = new Title(10, 10, 230, 40, FL_RED, + "Fl_Window TL(0, 0, 250, 100)\nx, y relative to main window"); + Box* tl_box = new Box(25, 50, 200, 40, FL_RED, + "Fl_Box tl(25, 50, 200, 40)\nx, y relative to TL window"); + tl_window->end(); + + Fl_Window* br_window = new Fl_Window(250, 100, 250, 100); + br_window->box(FL_ENGRAVED_BOX); + Title* br_title = new Title(10, 10, 230, 40, FL_MAGENTA, + "Fl_Window BR(250, 100, 250, 100)\nx, y relative to main window"); + Box* br_box = new Box(25, 50, 200, 40, FL_MAGENTA, + "Fl_Box br(25, 50, 200, 40)\nx, y relative to BR window"); + br_window->end(); + + Fl_Group* tr_group = new Fl_Group(250, 0, 250, 100); + tr_group->box(FL_ENGRAVED_BOX); + Title* tr_title = new Title(260, 10, 230, 40, FL_BLUE, + "Fl_Group TR(250, 0, 250, 100)\nx, y relative to main window"); + Box* tr_box = new Box(275, 50, 200, 40, FL_BLUE, + "Fl_Box tr(275, 50, 200, 40)\nx, y relative to main window"); + tr_group->end(); + + Fl_Group* bl_group = new Fl_Group(0, 100, 250, 100); + bl_group->box(FL_ENGRAVED_BOX); + Title* bl_title = new Title(10, 110, 230, 40, FL_BLACK, + "Fl_Group BL(0, 100, 250, 100)\nx, y relative to main window"); + Box* bl_box = new Box(25, 150, 200, 40, FL_BLACK, + "Fl_Box bl(25, 150, 200, 40)\nx, y relative to main window"); + bl_group->end(); + + // member variable + message_box = new Fl_Box(0, 201, 500, 30); + message_box->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER); + message_box->box(FL_ENGRAVED_BOX); + message_box->labelfont(FL_COURIER); + message_box->labelsize(12); + + end(); + } + +protected: + int handle(int event) { + static char buffer[128]; + static const char* fmt = "Mouse position relative to main window: %3d,%3d"; + int result = Fl_Window::handle(event); + switch (event) { + case FL_ENTER: + case FL_LEAVE: + result = 1; + message_box->copy_label(""); + break; + case FL_MOVE: + case FL_DRAG: + result = 1; + if (0 < Fl::event_x() && Fl::event_x() < w() && + 0 < Fl::event_y() && Fl::event_y() < h()) { + snprintf(buffer, 128-1, fmt, Fl::event_x(), Fl::event_y()); + message_box->copy_label(buffer); + } else message_box->copy_label(""); + break; + default: + break; + } + return result; + } + +private: + Fl_Box* message_box; +}; + +int main(int argc, char** argv) { + MainWindow window(500, 232, "FLTK Coordinate Systems"); + window.show(argc, argv); + return Fl::run(); +} diff --git a/test/wizard.cxx b/test/wizard.cxx new file mode 100644 index 000000000..3baa051dc --- /dev/null +++ b/test/wizard.cxx @@ -0,0 +1,66 @@ +#include <FL/Fl.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Wizard.H> + +class Panel : public Fl_Group { +public: + Panel(int X, int Y, int W, int H, Fl_Color C, const char* T) + : Fl_Group(X, Y, W, H, T) { + align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER); + box(FL_ENGRAVED_BOX); + labelcolor(C); + labelsize(20); + end(); + } +}; + +class Wizard : public Fl_Wizard { +public: + Wizard(int X, int Y, int W, int H, const char* T=0) + : Fl_Wizard(X, Y, W, H, T) { + p1 = new Panel(X, Y, W, H, FL_RED, "Panel 1"); + p2 = new Panel(X, Y, W, H, FL_MAGENTA, "Panel 2"); + p3 = new Panel(X, Y, W, H, FL_BLUE, "Panel 3"); + value(p1); + } + void next_panel() { + Panel* p = (Panel*)value(); + if (p == p3) value(p1); else next(); + } + void prev_panel() { + Panel* p = (Panel*)value(); + if (p == p1) value(p3); else prev(); + } +private: + Panel *p1, *p2, *p3; +}; + +void next_callback(Fl_Widget *widget, void *data) { + Wizard *pWizard = (Wizard*)data; + pWizard->next_panel(); +} + +void prev_callback(Fl_Widget *widget, void *data) { + Wizard *pWizard = (Wizard*)data; + pWizard->prev_panel(); +} + +int main(int argc, char** argv) { + Fl_Window window(300, 165, "Fl_Wizard test"); + Wizard wizard(5, 5, 290, 100); + wizard.end(); + Fl_Group buttons(5, 110, 290, 50); + buttons.box(FL_ENGRAVED_BOX); + Fl_Button prev_button( 15, 120, 110, 30, "@< Prev Panel"); + prev_button.callback(prev_callback, (void*)&wizard); + prev_button.align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER | FL_ALIGN_LEFT); + Fl_Button next_button(175, 120, 110, 30, "Next Panel @>"); + next_button.align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER | FL_ALIGN_RIGHT); + next_button.callback(next_callback, (void*)&wizard); + buttons.end(); + window.end(); + window.show(argc, argv); + return Fl::run(); +} + |
