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>
This commit is contained in:
parent
eb7fb00801
commit
2d18c6f650
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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>
|
||||
|
171
documentation/src/coordinates.dox
Normal file
171
documentation/src/coordinates.dox
Normal file
@ -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
|
||||
|
||||
*/
|
BIN
documentation/src/coordinates.png
Normal file
BIN
documentation/src/coordinates.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
@ -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">
|
||||
|
@ -43,6 +43,8 @@
|
||||
- \ref common_labels
|
||||
- \ref drawing_images
|
||||
|
||||
\subpage coordinates
|
||||
|
||||
\subpage resize
|
||||
|
||||
\subpage editor
|
||||
|
BIN
documentation/src/pack.png
Normal file
BIN
documentation/src/pack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
@ -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">
|
||||
|
BIN
documentation/src/wizard.png
Normal file
BIN
documentation/src/wizard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
2
test/.gitignore
vendored
2
test/.gitignore
vendored
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
125
test/coordinates.cxx
Normal file
125
test/coordinates.cxx
Normal file
@ -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();
|
||||
}
|
66
test/wizard.cxx
Normal file
66
test/wizard.cxx
Normal file
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user