summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorengelsman <engelsman@users.noreply.github.com>2021-12-08 15:00:33 +0100
committerGitHub <noreply@github.com>2021-12-08 15:00:33 +0100
commit2d18c6f650c0001319c8883f8deb819d12984ac0 (patch)
tree3fe72b80a2baadf7239cc40d9a0adedf9df9970f
parenteb7fb00801eb917ca1350d36ea896446cf4e5fb8 (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.in1
-rw-r--r--documentation/Makefile1
-rw-r--r--documentation/src/common.dox4
-rw-r--r--documentation/src/coordinates.dox171
-rw-r--r--documentation/src/coordinates.pngbin0 -> 6913 bytes
-rw-r--r--documentation/src/editor.dox2
-rw-r--r--documentation/src/index.dox2
-rw-r--r--documentation/src/pack.pngbin0 -> 4041 bytes
-rw-r--r--documentation/src/resize.dox6
-rw-r--r--documentation/src/wizard.pngbin0 -> 1043 bytes
-rw-r--r--test/.gitignore2
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/coordinates.cxx125
-rw-r--r--test/wizard.cxx66
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
new file mode 100644
index 000000000..d712474ef
--- /dev/null
+++ b/documentation/src/coordinates.png
Binary files differ
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
new file mode 100644
index 000000000..df87e06ef
--- /dev/null
+++ b/documentation/src/pack.png
Binary files differ
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
new file mode 100644
index 000000000..4357648d0
--- /dev/null
+++ b/documentation/src/wizard.png
Binary files differ
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();
+}
+