Add Fl_Grid widget and test and demo programs
- FL/Fl_Grid.H: header file - src/Fl_Grid.cxx: implementation - examples/grid-simple.cxx: simple example program - test/cube.cxx: use Fl_Grid for layout - test/grid_alignment.cxx: test cell alignment and other functions - test/grid_buttons.cxx: demo program as discussed in fltk.general - test/grid_login.cxx: like test/flex_login.cxx but with Fl_Grid - test/flex_login.cxx: modified to match test/grid_login.cxx
This commit is contained in:
parent
e7b790ae31
commit
38871c5b31
333
FL/Fl_Grid.H
Normal file
333
FL/Fl_Grid.H
Normal file
@ -0,0 +1,333 @@
|
||||
//
|
||||
// Fl_Grid widget header for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021-2022 by Albrecht Schlosser.
|
||||
// Copyright 2022-2023 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_FL_GRID_H_
|
||||
#define _FL_FL_GRID_H_
|
||||
|
||||
/** \file FL/Fl_Grid.H
|
||||
Fl_Grid container widget.
|
||||
*/
|
||||
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/Fl_Rect.H>
|
||||
|
||||
/** Fl_Grid type for child widget alignment control. */
|
||||
typedef unsigned short Fl_Grid_Align;
|
||||
|
||||
/** Align the widget in the middle of the cell (default). */
|
||||
const Fl_Grid_Align FL_GRID_CENTER = 0x0000;
|
||||
|
||||
/** Align the widget at the top of the cell. */
|
||||
const Fl_Grid_Align FL_GRID_TOP = 0x0001;
|
||||
|
||||
/** Align the widget at the bottom of the cell. */
|
||||
const Fl_Grid_Align FL_GRID_BOTTOM = 0x0002;
|
||||
|
||||
/** Align the widget at the left side of the cell. */
|
||||
const Fl_Grid_Align FL_GRID_LEFT = 0x0004;
|
||||
|
||||
/** Align the widget at the right side of the cell. */
|
||||
const Fl_Grid_Align FL_GRID_RIGHT = 0x0008;
|
||||
|
||||
/** Stretch the widget horizontally to fill the cell. */
|
||||
const Fl_Grid_Align FL_GRID_HORIZONTAL = 0x0010;
|
||||
|
||||
/** Stretch the widget vertically to fill the cell. */
|
||||
const Fl_Grid_Align FL_GRID_VERTICAL = 0x0020;
|
||||
|
||||
/** Stretch the widget in both directions to fill the cell. */
|
||||
const Fl_Grid_Align FL_GRID_FILL = 0x0030;
|
||||
|
||||
/** Stretch the widget proportionally. */
|
||||
const Fl_Grid_Align FL_GRID_PROPORTIONAL = 0x0040;
|
||||
|
||||
const Fl_Grid_Align FL_GRID_TOP_LEFT = FL_GRID_TOP | FL_GRID_LEFT;
|
||||
const Fl_Grid_Align FL_GRID_TOP_RIGHT = FL_GRID_TOP | FL_GRID_RIGHT;
|
||||
const Fl_Grid_Align FL_GRID_BOTTOM_LEFT = FL_GRID_BOTTOM | FL_GRID_LEFT;
|
||||
const Fl_Grid_Align FL_GRID_BOTTOM_RIGHT = FL_GRID_BOTTOM | FL_GRID_RIGHT;
|
||||
|
||||
/**
|
||||
Fl_Grid is a container (layout) widget with multiple columns and rows.
|
||||
|
||||
This container widget features very flexible layouts in columns and rows
|
||||
w/o the need to position each child widget in x/y coordinates.
|
||||
|
||||
Widgets are assigned to grid cells (column, row) with their minimal sizes
|
||||
in \p w() and \p h(). The \p x() and \p y() positions are ignored and can
|
||||
be (0, 0). Fl_Grid calculates widget positions and resizes the widgets to
|
||||
fit into the grid. It is possible to create a single row or column of
|
||||
widgets with Fl_Grid.
|
||||
|
||||
You should design your grid with the smallest possible sizes of all widgets
|
||||
in mind. Fl_Grid will automatically assign additional space to cells
|
||||
according to some rules (described later) when resizing the Fl_Grid widget.
|
||||
|
||||
\b Hint: You should set a minimum window size to make sure the Fl_Grid is
|
||||
never resized below its minimal sizes. Resizing below the given widget
|
||||
sizes results in undefined behavior.
|
||||
|
||||
Fl_Grid and other container widgets (e.g. Fl_Group) can be nested. One main
|
||||
advantage of this usage is that widget coordinates in embedded Fl_Group
|
||||
widgets become relative to the group and will be positioned as expected.
|
||||
\todo This (relative group coordinates of nested groups of Fl_Grid)
|
||||
needs explanation and maybe an example.
|
||||
|
||||
Fl_Grid child widgets are handled by its base class Fl_Group but Fl_Grid
|
||||
stores additional data corresponding to each widget in internal grid cells.
|
||||
|
||||
Fl_Grid children are allowed to span multiple columns and rows like HTML
|
||||
\<table\> cells. Individual children can have fixed sizes or be aligned
|
||||
inside their cells (left, right, top, bottom, and more) and/or follow
|
||||
their cell sizes when the Fl_Grid container is resized.
|
||||
|
||||
Note to resizing: since Fl_Grid uses its own layout algorithm the normal
|
||||
Fl_Group::resizable() widget is ignored (if set). Calling init_sizes()
|
||||
is not necessary.
|
||||
|
||||
\note Fl_Grid is, as of FLTK 1.4.0, still in experimental state and
|
||||
should be used with caution. The API can still be changed although it is
|
||||
assumed to be almost stable - as stable as possible for a first release.
|
||||
|
||||
Example: Simple 3x3 Fl_Grid with five buttons:
|
||||
\n
|
||||
\code
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Grid.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Fl_Double_Window *win = new Fl_Double_Window(320, 180, "3x3 Fl_Grid with Buttons");
|
||||
// create the Fl_Grid container with five buttons
|
||||
Fl_Grid *grid = new Fl_Grid(0, 0, win->w(), win->h());
|
||||
grid->layout(3, 3, 10, 10);
|
||||
grid->color(FL_WHITE);
|
||||
Fl_Button *b0 = new Fl_Button(0, 0, 0, 0, "New");
|
||||
Fl_Button *b1 = new Fl_Button(0, 0, 0, 0, "Options");
|
||||
Fl_Button *b3 = new Fl_Button(0, 0, 0, 0, "About");
|
||||
Fl_Button *b4 = new Fl_Button(0, 0, 0, 0, "Help");
|
||||
Fl_Button *b6 = new Fl_Button(0, 0, 0, 0, "Quit");
|
||||
// assign buttons to grid positions
|
||||
grid->widget(b0, 0, 0);
|
||||
grid->widget(b1, 0, 2);
|
||||
grid->widget(b3, 1, 1);
|
||||
grid->widget(b4, 2, 0);
|
||||
grid->widget(b6, 2, 2);
|
||||
grid->show_grid(0); // 1 to display grid helper lines
|
||||
win->end();
|
||||
win->resizable(grid);
|
||||
win->size_range(300, 100);
|
||||
win->show(argc, argv);
|
||||
return Fl::run();
|
||||
}
|
||||
\endcode
|
||||
|
||||
\image html Fl_Grid.png
|
||||
\image latex Fl_Grid.png "Simple 3x3 Fl_Grid" width=7cm
|
||||
*/
|
||||
class Fl_Grid : public Fl_Group {
|
||||
|
||||
public:
|
||||
class Cell {
|
||||
friend class Fl_Grid;
|
||||
private:
|
||||
Cell *next_; // next cell in row
|
||||
short row_; // row number
|
||||
short col_; // column number
|
||||
short rowspan_; // row span (1 - n)
|
||||
short colspan_; // column span (1 - n)
|
||||
Fl_Grid_Align align_; // widget alignment in its cell
|
||||
Fl_Widget *widget_; // assigned widget
|
||||
int w_; // minimal widget width
|
||||
int h_; // minimal widget height
|
||||
|
||||
public:
|
||||
|
||||
Cell(int row, int col) {
|
||||
next_ = NULL;
|
||||
row_ = row;
|
||||
col_ = col;
|
||||
rowspan_ = 1;
|
||||
colspan_ = 1;
|
||||
widget_ = NULL;
|
||||
w_ = 0;
|
||||
h_ = 0;
|
||||
align_ = 0;
|
||||
}
|
||||
|
||||
~Cell() {}
|
||||
|
||||
Fl_Widget *widget() { return widget_; }
|
||||
void align(Fl_Grid_Align align) {
|
||||
align_ = align;
|
||||
}
|
||||
}; // class Cell
|
||||
|
||||
private:
|
||||
class Row;
|
||||
class Col;
|
||||
short rows_;
|
||||
short cols_;
|
||||
|
||||
short margin_left_; // left margin
|
||||
short margin_top_; // top margin
|
||||
short margin_right_; // right margin
|
||||
short margin_bottom_; // bottom margin
|
||||
short gap_row_; // gap between rows
|
||||
short gap_col_; // gap between columns
|
||||
Fl_Rect old_size; // only for resize callback (TBD)
|
||||
Col *Cols_; // array of columns
|
||||
Row *Rows_; // array of rows
|
||||
bool need_layout_; // true if layout needs to be calculated
|
||||
|
||||
protected:
|
||||
Fl_Color grid_color; // color for drawing the grid lines (design helper)
|
||||
bool draw_grid_; // draw the grid for testing / design
|
||||
|
||||
private:
|
||||
void init();
|
||||
Cell *add_cell(int row, int col);
|
||||
void remove_cell(int row, int col);
|
||||
|
||||
public:
|
||||
Fl_Grid(int X, int Y, int W, int H, const char *L = 0);
|
||||
virtual ~Fl_Grid();
|
||||
|
||||
// define and manage the layout and resizing
|
||||
|
||||
virtual void layout(int rows, int cols, int margin = -1, int gap = -1);
|
||||
virtual void layout();
|
||||
virtual void clear_layout();
|
||||
virtual void resize(int X, int Y, int W, int H) FL_OVERRIDE;
|
||||
|
||||
/**
|
||||
Request or reset the request to calculate the layout of children.
|
||||
|
||||
If called with \p true (1) this calls redraw() to schedule a
|
||||
full draw(). When draw is eventually called, the layout is
|
||||
(re)calculated before actually drawing the widget.
|
||||
|
||||
\param[in] set 1 to request layout calculation,\n
|
||||
0 to reset the request
|
||||
*/
|
||||
void need_layout(int set) {
|
||||
if (set) {
|
||||
need_layout_ = true;
|
||||
redraw();
|
||||
}
|
||||
else {
|
||||
need_layout_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Return whether layout calculation is required.
|
||||
*/
|
||||
bool need_layout() const {
|
||||
return need_layout_;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void draw() FL_OVERRIDE;
|
||||
void on_remove(int) FL_OVERRIDE;
|
||||
virtual void draw_grid(); // draw grid lines for debugging
|
||||
|
||||
public:
|
||||
|
||||
// set individual margins
|
||||
|
||||
virtual void margin(int left, int top = -1, int right = -1, int bottom = -1);
|
||||
|
||||
// set default row and column gaps for all rows and columns, respectively
|
||||
|
||||
virtual void gap(int row_gap, int col_gap = -1); // set default row and column gap(s)
|
||||
|
||||
// find cells, get cell pointers
|
||||
|
||||
Fl_Grid::Cell* cell(int row, int col) const;
|
||||
Fl_Grid::Cell* cell(Fl_Widget *widget) const;
|
||||
|
||||
// assign a widget to a cell
|
||||
|
||||
Fl_Grid::Cell* widget(Fl_Widget *wi, int row, int col, Fl_Grid_Align align = FL_GRID_FILL);
|
||||
Fl_Grid::Cell* widget(Fl_Widget *wi, int row, int col, int rowspan, int colspan, Fl_Grid_Align align = FL_GRID_FILL);
|
||||
|
||||
// set minimal column and row sizes (widths and heights, respectively),
|
||||
// set row and column specific gaps and weights
|
||||
|
||||
void col_width(int col, int value);
|
||||
void col_width(const int *value, size_t size);
|
||||
|
||||
void col_weight(int col, int value);
|
||||
void col_weight(const int *value, size_t size);
|
||||
|
||||
void col_gap(int col, int value);
|
||||
void col_gap(const int *value, size_t size);
|
||||
|
||||
void row_height(int row, int value);
|
||||
void row_height(const int *value, size_t size);
|
||||
|
||||
void row_weight(int row, int value);
|
||||
void row_weight(const int *value, size_t size);
|
||||
|
||||
void row_gap(int row, int value);
|
||||
void row_gap(const int *value, size_t size);
|
||||
|
||||
/**
|
||||
Enable or disable drawing of the grid helper lines for visualization.
|
||||
|
||||
Use this method during the design stage of your Fl_Grid widget or
|
||||
for debugging if widgets are not positioned as intended.
|
||||
|
||||
The default is a light green color but you can change it for better
|
||||
contrast if needed, see show_grid(int set, Fl_Color col).
|
||||
|
||||
\note You can define the environment variable \c FLTK_GRID_DEBUG=1
|
||||
to set show_grid(1) for all Fl_Grid widgets at construction time.
|
||||
This enables you to debug the grid layout w/o changing code.
|
||||
|
||||
\param[in] set 1 (true) = draw, 0 = don't draw the grid
|
||||
|
||||
\see show_grid(int set, Fl_Color col)
|
||||
*/
|
||||
void show_grid(int set) {
|
||||
draw_grid_ = set ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
Enable or disable drawing of the grid helper lines for visualization.
|
||||
|
||||
This method also sets the color used for the helper lines.
|
||||
|
||||
The default is a light green color but you can change it to any color
|
||||
for better contrast if needed.
|
||||
|
||||
\param[in] set 1 (true) = draw, 0 = don't draw the grid
|
||||
\param[in] col color to use for the grid helper lines
|
||||
|
||||
\see show_grid(int set)
|
||||
*/
|
||||
void show_grid(int set, Fl_Color col) {
|
||||
draw_grid_ = set ? true : false;
|
||||
grid_color = col;
|
||||
}
|
||||
|
||||
void debug(int level = 127);
|
||||
|
||||
}; // class Fl_Grid
|
||||
|
||||
#endif // _FL_FL_GRID_H_
|
BIN
documentation/src/Fl_Grid.png
Normal file
BIN
documentation/src/Fl_Grid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
1
examples/.gitignore
vendored
1
examples/.gitignore
vendored
@ -12,6 +12,7 @@ callbacks
|
||||
cairo-draw-x
|
||||
chart-simple
|
||||
draggable-group
|
||||
grid-simple
|
||||
howto-add_fd-and-popen
|
||||
howto-browser-with-icons
|
||||
howto-drag-and-drop
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# CMakeLists.txt used to build example apps by the CMake build system
|
||||
#
|
||||
# Copyright 2020-2022 by Bill Spitzak and others.
|
||||
# Copyright 2020-2023 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
|
||||
@ -31,10 +31,11 @@ file (MAKE_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||
############################################################
|
||||
|
||||
set (SIMPLE_SOURCES
|
||||
chart-simple
|
||||
callbacks
|
||||
browser-simple
|
||||
callbacks
|
||||
chart-simple
|
||||
draggable-group
|
||||
grid-simple
|
||||
howto-add_fd-and-popen
|
||||
howto-browser-with-icons
|
||||
howto-drag-and-drop
|
||||
@ -45,8 +46,8 @@ set (SIMPLE_SOURCES
|
||||
howto-remap-numpad-keyboard-keys
|
||||
howto-text-over-image-button
|
||||
menubar-add
|
||||
nativefilechooser-simple-app
|
||||
nativefilechooser-simple
|
||||
nativefilechooser-simple-app
|
||||
progress-simple
|
||||
shapedwindow
|
||||
simple-terminal
|
||||
|
@ -31,6 +31,7 @@ ALL = animgifimage$(EXEEXT) \
|
||||
callbacks$(EXEEXT) \
|
||||
chart-simple$(EXEEXT) \
|
||||
draggable-group$(EXEEXT) \
|
||||
grid-simple$(EXEEXT) \
|
||||
howto-add_fd-and-popen$(EXEEXT) \
|
||||
howto-browser-with-icons$(EXEEXT) \
|
||||
howto-drag-and-drop$(EXEEXT) \
|
||||
|
49
examples/grid-simple.cxx
Normal file
49
examples/grid-simple.cxx
Normal file
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Fl_Grid Example Program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021-2022 by Albrecht Schlosser.
|
||||
// Copyright 2022-2023 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
|
||||
//
|
||||
|
||||
// This example program is also included in the documentation.
|
||||
// See FL/Fl_Grid.H
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Grid.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Fl_Double_Window *win = new Fl_Double_Window(320, 180, "3x3 Fl_Grid with Buttons");
|
||||
// create the Fl_Grid container with five buttons
|
||||
Fl_Grid *grid = new Fl_Grid(0, 0, win->w(), win->h());
|
||||
grid->layout(3, 3, 10, 10);
|
||||
grid->color(FL_WHITE);
|
||||
Fl_Button *b0 = new Fl_Button(0, 0, 0, 0, "New");
|
||||
Fl_Button *b1 = new Fl_Button(0, 0, 0, 0, "Options");
|
||||
Fl_Button *b3 = new Fl_Button(0, 0, 0, 0, "About");
|
||||
Fl_Button *b4 = new Fl_Button(0, 0, 0, 0, "Help");
|
||||
Fl_Button *b6 = new Fl_Button(0, 0, 0, 0, "Quit");
|
||||
// assign buttons to grid positions
|
||||
grid->widget(b0, 0, 0);
|
||||
grid->widget(b1, 0, 2);
|
||||
grid->widget(b3, 1, 1);
|
||||
grid->widget(b4, 2, 0);
|
||||
grid->widget(b6, 2, 2);
|
||||
// grid->show_grid(1); // enable to display grid helper lines
|
||||
win->end();
|
||||
win->resizable(grid);
|
||||
win->size_range(300, 100);
|
||||
win->show(argc, argv);
|
||||
return Fl::run();
|
||||
}
|
@ -41,6 +41,7 @@ set (CPPFILES
|
||||
Fl_File_Input.cxx
|
||||
Fl_Flex.cxx
|
||||
Fl_Graphics_Driver.cxx
|
||||
Fl_Grid.cxx
|
||||
Fl_Group.cxx
|
||||
Fl_Help_View.cxx
|
||||
Fl_Image.cxx
|
||||
|
1108
src/Fl_Grid.cxx
Normal file
1108
src/Fl_Grid.cxx
Normal file
File diff suppressed because it is too large
Load Diff
@ -45,6 +45,7 @@ CPPFILES = \
|
||||
Fl_File_Input.cxx \
|
||||
Fl_Flex.cxx \
|
||||
Fl_Graphics_Driver.cxx \
|
||||
Fl_Grid.cxx \
|
||||
Fl_Group.cxx \
|
||||
Fl_Help_View.cxx \
|
||||
Fl_Image.cxx \
|
||||
|
@ -2238,6 +2238,11 @@ Fl_Graphics_Driver.o: ../FL/platform.H
|
||||
Fl_Graphics_Driver.o: ../FL/platform_types.h
|
||||
Fl_Graphics_Driver.o: ../FL/x11.H
|
||||
Fl_Graphics_Driver.o: Fl_Screen_Driver.H
|
||||
Fl_Grid.o: ../FL/fl_draw.H
|
||||
Fl_Grid.o: ../FL/Fl_Grid.H
|
||||
Fl_Grid.o: ../FL/Fl_Group.H
|
||||
Fl_Grid.o: ../FL/Fl_Rect.H
|
||||
Fl_Grid.o: ../FL/Fl_Widget.H
|
||||
Fl_Group.o: ../FL/Enumerations.H
|
||||
Fl_Group.o: ../FL/Fl.H
|
||||
Fl_Group.o: ../FL/fl_attr.h
|
||||
|
3
test/.gitignore
vendored
3
test/.gitignore
vendored
@ -52,6 +52,9 @@ fullscreen
|
||||
gl_overlay
|
||||
glpuzzle
|
||||
glut_test
|
||||
grid_alignment
|
||||
grid_buttons
|
||||
grid_login
|
||||
handle_events
|
||||
hello
|
||||
help_dialog
|
||||
|
@ -92,6 +92,10 @@ if (OPENGL_FOUND)
|
||||
CREATE_EXAMPLE (glut_test glut_test.cxx "fltk_gl;fltk")
|
||||
endif()
|
||||
|
||||
CREATE_EXAMPLE (grid_alignment grid_alignment.cxx fltk)
|
||||
CREATE_EXAMPLE (grid_buttons grid_buttons.cxx fltk)
|
||||
CREATE_EXAMPLE (grid_login grid_login.cxx fltk)
|
||||
|
||||
if (OPENGL_FOUND)
|
||||
CREATE_EXAMPLE (handle_events handle_events.cxx "fltk_gl;fltk") # opt. Fl_Gl_Window
|
||||
else()
|
||||
|
@ -76,6 +76,9 @@ CPPFILES =\
|
||||
gl_overlay.cxx \
|
||||
glpuzzle.cxx \
|
||||
glut_test.cxx \
|
||||
grid_alignment \
|
||||
grid_buttons \
|
||||
grid_login \
|
||||
hello.cxx \
|
||||
help_dialog.cxx \
|
||||
icon.cxx \
|
||||
@ -161,6 +164,9 @@ ALL = \
|
||||
fltk-versions$(EXEEXT) \
|
||||
fonts$(EXEEXT) \
|
||||
forms$(EXEEXT) \
|
||||
grid_alignment$(EXEEXT) \
|
||||
grid_buttons$(EXEEXT) \
|
||||
grid_login$(EXEEXT) \
|
||||
hello$(EXEEXT) \
|
||||
help_dialog$(EXEEXT) \
|
||||
icon$(EXEEXT) \
|
||||
@ -437,6 +443,12 @@ forms$(EXEEXT): forms.o
|
||||
$(CXX) $(ARCHFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ forms.o $(LINKFLTKFORMS) $(LDLIBS)
|
||||
$(OSX_ONLY) ../fltk-config --post $@
|
||||
|
||||
grid_alignment$(EXEEXT): grid_alignment.o
|
||||
|
||||
grid_buttons$(EXEEXT): grid_buttons.o
|
||||
|
||||
grid_login$(EXEEXT): grid_login.o
|
||||
|
||||
hello$(EXEEXT): hello.o
|
||||
|
||||
help_dialog$(EXEEXT): help_dialog.o $(IMGLIBNAME)
|
||||
|
239
test/cube.cxx
239
test/cube.cxx
@ -3,7 +3,7 @@
|
||||
//
|
||||
// Modified to have 2 cubes to test multiple OpenGL contexts
|
||||
//
|
||||
// Copyright 1998-2021 by Bill Spitzak and others.
|
||||
// Copyright 1998-2023 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
|
||||
@ -26,7 +26,7 @@
|
||||
#include <FL/Fl_Slider.H>
|
||||
#include <FL/Fl_Sys_Menu_Bar.H>
|
||||
#include <FL/Fl_Printer.H> // demo printing
|
||||
|
||||
#include <FL/Fl_Grid.H> // grid layout
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !HAVE_GL
|
||||
@ -39,8 +39,6 @@ public:
|
||||
cube_box(int x,int y,int w,int h,const char *l=0) :Fl_Box(FL_DOWN_BOX,x,y,w,h,l) {
|
||||
label("This demo does\nnot work without GL");
|
||||
}
|
||||
void begin() {}
|
||||
void end() {}
|
||||
};
|
||||
#else
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
@ -120,11 +118,8 @@ void cube_box::draw() {
|
||||
gl_draw(wire ? "Cube: wire" : "Cube: flat", -4.5f, -4.5f );
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// if an OpenGL graphics driver is installed, give it a chance
|
||||
// to draw additional graphics
|
||||
#if HAVE_GL
|
||||
// draw additional FLTK widgets and graphics
|
||||
Fl_Gl_Window::draw();
|
||||
#endif
|
||||
}
|
||||
|
||||
int cube_box::handle(int e) {
|
||||
@ -135,121 +130,128 @@ int cube_box::handle(int e) {
|
||||
return Fl_Gl_Window::handle(e);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Fl_Window *form;
|
||||
Fl_Slider *speed, *size;
|
||||
Fl_Button *exit_button, *wire, *flat;
|
||||
cube_box *lt_cube, *rt_cube;
|
||||
|
||||
int done = 0; // set to 1 in exit button callback
|
||||
|
||||
// exit button callback
|
||||
void exit_cb(Fl_Widget *, void *) {
|
||||
done = 1;
|
||||
}
|
||||
|
||||
// print screen demo
|
||||
void print_cb(Fl_Widget *w, void *data)
|
||||
{
|
||||
Fl_Printer printer;
|
||||
Fl_Window *win = Fl::first_window();
|
||||
if(!win) return;
|
||||
if( printer.start_job(1) ) return;
|
||||
if( printer.start_page() ) return;
|
||||
printer.scale(0.5,0.5);
|
||||
printer.print_widget( win );
|
||||
printer.end_page();
|
||||
printer.end_job();
|
||||
}
|
||||
|
||||
// Create a form that allows resizing for A and C (GL windows) with B fixed size/centered:
|
||||
//
|
||||
// lt_grp rt_grp
|
||||
// |<--------------------------------------->|<---------------------->|
|
||||
// . lt_cube ct_grp : rt_cube .
|
||||
// . 350 100 : 350 .
|
||||
// . |<------------------->| |<-------->| |<------------------->| .
|
||||
// ....................................................................
|
||||
// : ....................... ............ ....................... :
|
||||
// : : : : : : : :
|
||||
// : : A : : B : : C : :
|
||||
// : : : : : : : :
|
||||
// : :.....................: :..........: :.....................: : __
|
||||
// :..................................................................: __ MARGIN
|
||||
//
|
||||
// | |
|
||||
// MARGIN
|
||||
//
|
||||
|
||||
#define MENUBAR_H 25 // menubar height
|
||||
#define MARGIN 20 // fixed margin around widgets
|
||||
#define MARGIN2 (MARGIN*2)
|
||||
#define MARGIN3 (MARGIN*3)
|
||||
|
||||
// callback for overlay button (Fl_Button on OpenGL scene)
|
||||
void show_info_cb(Fl_Widget*, void*) {
|
||||
fl_message("This is an example of using FLTK widgets inside OpenGL windows.\n"
|
||||
"Multiple widgets can be added to Fl_Gl_Windows. They will be\n"
|
||||
"rendered as overlays over the scene.");
|
||||
}
|
||||
|
||||
// overlay a button onto an OpenGL window (cube_box)
|
||||
void overlay_button(cube_box *cube) {
|
||||
cube->begin();
|
||||
Fl_Widget *w = new Fl_Button(10, 10, 120, 30, "FLTK over GL");
|
||||
w->color(FL_FREE_COLOR);
|
||||
w->box(FL_BORDER_BOX);
|
||||
w->callback(show_info_cb);
|
||||
cube->end();
|
||||
}
|
||||
|
||||
#endif // HAVE_GL
|
||||
|
||||
Fl_Window *form;
|
||||
Fl_Slider *speed, *size;
|
||||
Fl_Button *exit_button, *wire, *flat;
|
||||
cube_box *lt_cube, *rt_cube;
|
||||
int done = 0; // set to 1 in exit button callback
|
||||
|
||||
// exit button callback
|
||||
void exit_cb(Fl_Widget *w, void *) {
|
||||
done = 1;
|
||||
w->window()->hide(); // necessary if built w/o GL
|
||||
}
|
||||
|
||||
// print screen demo
|
||||
void print_cb(Fl_Widget *w, void *data) {
|
||||
Fl_Printer printer;
|
||||
Fl_Window *win = Fl::first_window();
|
||||
if (!win) return;
|
||||
if (printer.start_job(1)) return;
|
||||
if (printer.start_page()) return;
|
||||
printer.scale(0.5, 0.5);
|
||||
printer.print_widget(win);
|
||||
printer.end_page();
|
||||
printer.end_job();
|
||||
}
|
||||
|
||||
// Create a form that allows resizing for A and C (GL windows) with B fixed size/centered:
|
||||
//
|
||||
// |<--------------------------------------->|<---------------------->|
|
||||
// . lt_cube center : rt_cube .
|
||||
// . 350 100 : 350 .
|
||||
// . |<------------------->| |<-------->| |<------------------->| .
|
||||
// ....................................................................
|
||||
// : ....................... ............ ....................... : __
|
||||
// : : : : : : : :
|
||||
// : : A : : B : : C : : h = 350
|
||||
// : : : : : : : :
|
||||
// : :.....................: :..........: :.....................: : __
|
||||
// :..................................................................: __ MARGIN
|
||||
//
|
||||
// | | | | | |
|
||||
// MARGIN GAP GAP
|
||||
|
||||
#define MENUBAR_H 25 // menubar height
|
||||
#define MARGIN 20 // fixed margin around widgets
|
||||
#define GAP 20 // fixed gap between widgets
|
||||
|
||||
void makeform(const char *name) {
|
||||
// Widget's XYWH's
|
||||
int form_w = 800 + 4 * MARGIN; // main window width
|
||||
int form_w = 800 + 2 * MARGIN + 2 * GAP; // main window width
|
||||
int form_h = 350 + MENUBAR_H + 2 * MARGIN; // main window height
|
||||
int me_bar_x=0, me_bar_y=0, me_bar_w=form_w, me_bar_h=MENUBAR_H; // menubar
|
||||
int lt_grp_x=0, lt_grp_y=MENUBAR_H+MARGIN, lt_grp_w=350+100+MARGIN3, lt_grp_h=form_h-MENUBAR_H-MARGIN2; // left group
|
||||
int lt_cub_x=lt_grp_x+MARGIN, lt_cub_y=lt_grp_y, lt_cub_w=350, lt_cub_h=lt_grp_h; // left cube box (GL)
|
||||
int ct_grp_x=lt_grp_x+350+MARGIN2, ct_grp_y=lt_grp_y, ct_grp_w=100, ct_grp_h=lt_grp_h; // center group
|
||||
int rt_grp_x=lt_grp_x+lt_grp_w, rt_grp_y=lt_grp_y, rt_grp_w=350+MARGIN, rt_grp_h=lt_grp_h; // right group
|
||||
int rt_cub_x=rt_grp_x, rt_cub_y=lt_grp_y, rt_cub_w=350, rt_cub_h=lt_grp_h; // right cube box (GL)
|
||||
|
||||
// main window
|
||||
form = new Fl_Window(form_w, form_h, name);
|
||||
form->begin();
|
||||
// menu bar
|
||||
Fl_Sys_Menu_Bar *menubar = new Fl_Sys_Menu_Bar(me_bar_x, me_bar_y, me_bar_w, me_bar_h);
|
||||
menubar->add("File/Print window", FL_COMMAND+'p', print_cb);
|
||||
menubar->add("File/Quit", FL_COMMAND+'q', exit_cb);
|
||||
// left group
|
||||
Fl_Group *lt_grp = new Fl_Group(lt_grp_x, lt_grp_y, lt_grp_w, lt_grp_h);
|
||||
lt_grp->begin();
|
||||
// left GL window
|
||||
lt_cube = new cube_box(lt_cub_x, lt_cub_y, lt_cub_w, lt_cub_h, 0);
|
||||
// menu bar
|
||||
Fl_Sys_Menu_Bar *menubar = new Fl_Sys_Menu_Bar(0, 0, form_w, MENUBAR_H);
|
||||
menubar->add("File/Print window", FL_COMMAND+'p', print_cb);
|
||||
menubar->add("File/Quit", FL_COMMAND+'q', exit_cb);
|
||||
|
||||
lt_cube->begin();
|
||||
Fl_Widget *w = new Fl_Button(10, 10, 120, 30, "FLTK over GL");
|
||||
w->color(FL_FREE_COLOR);
|
||||
w->box(FL_BORDER_BOX );
|
||||
w->callback(show_info_cb);
|
||||
lt_cube->end();
|
||||
// Fl_Grid (layout)
|
||||
Fl_Grid *grid = new Fl_Grid(0, MENUBAR_H, form_w, 350 + 2 * MARGIN);
|
||||
grid->layout(4, 4, MARGIN, GAP);
|
||||
grid->box(FL_FLAT_BOX);
|
||||
|
||||
// center group
|
||||
Fl_Group *ct_grp = new Fl_Group(ct_grp_x, ct_grp_y, ct_grp_w, ct_grp_h);
|
||||
ct_grp->begin();
|
||||
wire = new Fl_Radio_Light_Button(ct_grp_x, ct_grp_y, 100, 25, "Wire");
|
||||
flat = new Fl_Radio_Light_Button(ct_grp_x, wire->y()+wire->h(), 100, 25, "Flat");
|
||||
speed = new Fl_Slider(FL_VERT_SLIDER, ct_grp_x, flat->y()+flat->h()+MARGIN, 40, 200, "Speed");
|
||||
size = new Fl_Slider(FL_VERT_SLIDER, ct_grp_x+40+MARGIN, flat->y()+flat->h()+MARGIN, 40, 200, "Size");
|
||||
exit_button = new Fl_Button(ct_grp_x, form_h-MARGIN-25, 100, 25, "Exit");
|
||||
exit_button->callback(exit_cb);
|
||||
ct_grp->end();
|
||||
ct_grp->resizable(speed); // only sliders resize vertically, not buttons
|
||||
lt_grp->end();
|
||||
lt_grp->resizable(lt_cube);
|
||||
// right group
|
||||
Fl_Group *rt_grp = new Fl_Group(rt_grp_x, rt_grp_y, rt_grp_w, rt_grp_h);
|
||||
rt_grp->begin();
|
||||
// right GL window
|
||||
rt_cube = new cube_box(rt_cub_x, rt_cub_y, rt_cub_w, rt_cub_h, 0);
|
||||
rt_grp->end();
|
||||
rt_grp->resizable(rt_cube);
|
||||
// right resizer
|
||||
Fl_Box *rt_resizer = new Fl_Box(rt_grp_x-5, rt_grp_y, 10, rt_grp_h);
|
||||
rt_resizer->box(FL_NO_BOX);
|
||||
// set column and row weights to control resizing behavior
|
||||
int cwe[] = {50, 0, 0, 50}; // column weights
|
||||
int rwe[] = { 0, 0, 50, 0}; // row weights
|
||||
grid->col_weight(cwe, 4); // set weights for resizing
|
||||
grid->row_weight(rwe, 4); // set weights for resizing
|
||||
|
||||
// set non-default gaps for special layout purposes and labels
|
||||
grid->row_gap(0, 0); // no gap below wire button
|
||||
grid->row_gap(2, 50); // gap below sliders for labels
|
||||
|
||||
// left GL window
|
||||
lt_cube = new cube_box(0, 0, 350, 350);
|
||||
|
||||
// center group
|
||||
wire = new Fl_Radio_Light_Button( 0, 0, 100, 25, "Wire");
|
||||
flat = new Fl_Radio_Light_Button( 0, 0, 100, 25, "Flat");
|
||||
speed = new Fl_Slider(FL_VERT_SLIDER, 0, 0, 40, 90, "Speed");
|
||||
size = new Fl_Slider(FL_VERT_SLIDER, 0, 0, 40, 90, "Size");
|
||||
exit_button = new Fl_Button( 0, 0, 100, 25, "Exit");
|
||||
exit_button->callback(exit_cb);
|
||||
|
||||
// right GL window
|
||||
rt_cube = new cube_box(0, 0, 350, 350);
|
||||
|
||||
// assign widgets to grid positions (R=row, C=col) and sizes
|
||||
// RS=rowspan, CS=colspan: R, C, RS, CS, optional alignment
|
||||
grid->widget(lt_cube, 0, 0, 4, 1);
|
||||
grid->widget(wire, 0, 1, 1, 2);
|
||||
grid->widget(flat, 1, 1, 1, 2);
|
||||
grid->widget(speed, 2, 1, 1, 1, FL_GRID_VERTICAL);
|
||||
grid->widget(size, 2, 2, 1, 1, FL_GRID_VERTICAL);
|
||||
grid->widget(exit_button, 3, 1, 1, 2);
|
||||
grid->widget(rt_cube, 0, 3, 4, 1);
|
||||
|
||||
#if HAVE_GL
|
||||
overlay_button(lt_cube); // overlay a button onto the OpenGL window
|
||||
#endif // HAVE_GL
|
||||
|
||||
form->end();
|
||||
form->resizable(rt_resizer);
|
||||
form->resizable(grid);
|
||||
form->size_range(form->w(), form->h()); // minimum window size
|
||||
}
|
||||
|
||||
@ -257,29 +259,27 @@ int main(int argc, char **argv) {
|
||||
Fl::use_high_res_GL(1);
|
||||
Fl::set_color(FL_FREE_COLOR, 255, 255, 0, 75);
|
||||
makeform(argv[0]);
|
||||
speed->bounds(4,0);
|
||||
#if HAVE_GL
|
||||
speed->bounds(4, 0);
|
||||
speed->value(lt_cube->speed = rt_cube->speed = 1.0);
|
||||
#else
|
||||
speed->value(lt_cube->speed = rt_cube->speed = 0.0);
|
||||
#endif
|
||||
size->bounds(4,0.01);
|
||||
size->value(lt_cube->size = rt_cube->size = 3.0);
|
||||
size->bounds(4, 0.2);
|
||||
size->value(lt_cube->size = rt_cube->size = 2.0);
|
||||
flat->value(1); lt_cube->wire = 0; rt_cube->wire = 1;
|
||||
form->label("cube");
|
||||
form->label("Cube Demo");
|
||||
form->show(argc,argv);
|
||||
lt_cube->show();
|
||||
rt_cube->show();
|
||||
|
||||
#if 0
|
||||
// This demonstrates how to manipulate OpenGL contexts.
|
||||
// In this case the same context is used by multiple windows (I'm not
|
||||
// sure if this is allowed on Win32, can somebody check?).
|
||||
// This fixes a bug on the XFree86 3.0 OpenGL where only one context
|
||||
// per program seems to work, but there are probably better uses for
|
||||
// this!
|
||||
// This fixes a bug on the XFree86 3.0 OpenGL where only one context per
|
||||
// program seems to work, but there are probably better uses for this!
|
||||
lt_cube->make_current(); // causes context to be created
|
||||
rt_cube->context(lt_cube->context()); // share the contexts
|
||||
#endif
|
||||
|
||||
#if HAVE_GL
|
||||
for (;;) {
|
||||
if (form->visible() && speed->value()) {
|
||||
if (!Fl::check()) break; // returns immediately
|
||||
@ -295,4 +295,7 @@ int main(int argc, char **argv) {
|
||||
if (done) break; // exit button was clicked
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return Fl::run();
|
||||
#endif
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Fl_Flex demo program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2020 by Karsten Pedersen
|
||||
// Copyright 2022 by Bill Spitzak and others.
|
||||
// Copyright 2022-2023 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
|
||||
@ -32,7 +32,10 @@ Fl_Button *create_button(const char *caption) {
|
||||
|
||||
void buttons_panel(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_Box *title = new Fl_Box(0, 0, 0, 0, "Welcome to Fl_Flex");
|
||||
title->align(FL_ALIGN_CENTER);
|
||||
title->labelfont(FL_BOLD + FL_ITALIC);
|
||||
title->labelsize(16);
|
||||
|
||||
Fl_Flex *urow = new Fl_Flex(Fl_Flex::ROW);
|
||||
{
|
||||
@ -71,7 +74,7 @@ void buttons_panel(Fl_Flex *parent) {
|
||||
|
||||
Fl_Box *b = new Fl_Box(0, 0, 0, 0, "");
|
||||
|
||||
parent->fixed(w, 60);
|
||||
parent->fixed(title, 60);
|
||||
parent->fixed(urow, 30);
|
||||
parent->fixed(prow, 30);
|
||||
parent->fixed(pad, 1);
|
||||
@ -95,7 +98,7 @@ void middle_panel(Fl_Flex *parent) {
|
||||
|
||||
new Fl_Box(0, 0, 0, 0, "");
|
||||
|
||||
parent->fixed(box, 200);
|
||||
parent->fixed(box, 150);
|
||||
parent->fixed(spacer, 10);
|
||||
parent->fixed(bp, 300);
|
||||
}
|
||||
@ -119,21 +122,21 @@ void mainPanel(Fl_Flex *parent) {
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
Fl_Window *window = new Fl_Double_Window(100, 100, "Simple GUI Example");
|
||||
Fl_Window *win = new Fl_Double_Window(100, 100, "Fl_Flex \"Login\" Layout");
|
||||
|
||||
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();
|
||||
win->resizable(col);
|
||||
win->color(fl_rgb_color(250, 250, 250));
|
||||
win->end();
|
||||
|
||||
window->resize(0, 0, 640, 480);
|
||||
window->size_range(550, 250);
|
||||
window->show(argc, argv);
|
||||
win->resize(0, 0, 600, 300); // same size as grid_login
|
||||
win->size_range(550, 250);
|
||||
win->show(argc, argv);
|
||||
|
||||
int ret = Fl::run();
|
||||
delete window; // not necessary but useful to test for memory leaks
|
||||
delete win; // not necessary but useful to test for memory leaks
|
||||
return ret;
|
||||
}
|
||||
|
203
test/grid_alignment.cxx
Normal file
203
test/grid_alignment.cxx
Normal file
@ -0,0 +1,203 @@
|
||||
//
|
||||
// Fl_Grid demo program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021 by Albrecht Schlosser
|
||||
// Copyright 2022-2023 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
|
||||
//
|
||||
|
||||
//
|
||||
// This program tests several different alignment features of Fl_Grid.
|
||||
//
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Grid.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Input.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
|
||||
// Test function to change the layout (executed by timer callback)
|
||||
|
||||
#define TEST_RELAYOUT (0)
|
||||
#define TEST_REMOVE_NOTIFY (0)
|
||||
|
||||
#if (TEST_RELAYOUT)
|
||||
void relayout_cb(void *v) {
|
||||
Fl_Grid *grid = (Fl_Grid *)v;
|
||||
grid->layout(5, 5, 8, 4);
|
||||
grid->margin(10, 20, 30, 40);
|
||||
grid->layout();
|
||||
grid->redraw();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_REMOVE_NOTIFY
|
||||
|
||||
void remove_cb(void *v) {
|
||||
static int n = 10;
|
||||
n--;
|
||||
Fl_Grid *grid = (Fl_Grid *)v;
|
||||
#if (0) // test 1: remove() the widget -- leaks memory (!)
|
||||
grid->remove(n);
|
||||
#else // test 2: delete the widget -- no leak
|
||||
delete grid->child(0);
|
||||
#endif
|
||||
if (n > 0)
|
||||
Fl::repeat_timeout(0.3, remove_cb, v);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Fl_Grid::Cell *c;
|
||||
Fl_Box *b;
|
||||
Fl_Double_Window *win = new Fl_Double_Window(440, 350, "FLTK 1.4.0 - Fl_Grid Alignment Test");
|
||||
Fl_Grid *grid = new Fl_Grid(10, 10, 420, 330);
|
||||
grid->layout(7, 7, 8, 4); // cols, rows, margin, gap
|
||||
grid->box(FL_FLAT_BOX);
|
||||
grid->color(FL_WHITE);
|
||||
|
||||
// add boxes (top and bottom rows)
|
||||
|
||||
for (int col = 0; col < 7; col++) {
|
||||
grid->col_width(col, 50);
|
||||
b = new Fl_Box(0, 0, 20, 20); // variable size
|
||||
if (col == 5) {
|
||||
b->size(4, 20); // reduce width
|
||||
grid->col_width(col, 4); // new min. width
|
||||
grid->col_weight(col, 0); // no hor. resizing
|
||||
}
|
||||
b->box(FL_FLAT_BOX);
|
||||
b->color(FL_BLUE);
|
||||
grid->widget(b, 0, col);
|
||||
|
||||
if (col == 5)
|
||||
b = new Fl_Box(0, 0, 4, 20); // variable size
|
||||
else
|
||||
b = new Fl_Box(0, 0, 20, 20); // variable size
|
||||
b->box(FL_FLAT_BOX);
|
||||
b->color(FL_RED);
|
||||
grid->widget(b, 6, col);
|
||||
}
|
||||
|
||||
// add boxes (left and right columns)
|
||||
|
||||
grid->row_height(0, 40);
|
||||
grid->row_height(6, 40);
|
||||
|
||||
for (int row = 1; row < 6; row++) {
|
||||
grid->row_height(row, 40);
|
||||
b = new Fl_Box(0, 0, 20, 20); // fixed size, see alignment below
|
||||
b->box(FL_FLAT_BOX);
|
||||
b->color(FL_RED);
|
||||
switch(row) {
|
||||
case 1: grid->widget(b, row, 0, FL_GRID_FILL); break;
|
||||
case 2: grid->widget(b, row, 0, FL_ALIGN_CENTER); break;
|
||||
case 3: grid->widget(b, row, 0, FL_ALIGN_BOTTOM_RIGHT); break;
|
||||
case 4: grid->widget(b, row, 0, FL_ALIGN_BOTTOM_RIGHT); break;
|
||||
case 5: grid->widget(b, row, 0, FL_ALIGN_TOP_RIGHT); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
b = new Fl_Box(0, 0, 20, 20);
|
||||
b->box(FL_FLAT_BOX);
|
||||
b->color(FL_GREEN);
|
||||
c = grid->widget(b, row, 6, FL_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
// two more boxes to demonstrate widget alignment inside the cell
|
||||
|
||||
for (int row = 4; row < 6; row++) {
|
||||
b = new Fl_Box(0, 0, 20, 20); // fixed size, see alignment below
|
||||
b->box(FL_FLAT_BOX);
|
||||
b->color(FL_MAGENTA);
|
||||
c = grid->widget(b, row, 1); // default alignment: FL_GRID_FILL
|
||||
if (row == 4)
|
||||
c->align(FL_ALIGN_BOTTOM_LEFT); // alignment uses widget size
|
||||
if (row == 5)
|
||||
c->align(FL_ALIGN_TOP_LEFT); // alignment uses widget size
|
||||
}
|
||||
|
||||
// one vertical box (line), spanning 5 rows
|
||||
|
||||
b = new Fl_Box(0, 0, 2, 2); // extends vertically
|
||||
b->box(FL_FLAT_BOX);
|
||||
b->color(FL_BLACK);
|
||||
grid->widget(b, 1, 5, 5, 1, FL_GRID_VERTICAL | FL_ALIGN_RIGHT);
|
||||
|
||||
// add a textbox with label or title, spanning 5 cells, centered
|
||||
|
||||
b = new Fl_Box(0, 0, 1, 1); // variable size
|
||||
b->label("Hello, Fl_Grid !");
|
||||
b->labelfont(FL_BOLD + FL_ITALIC);
|
||||
b->labelsize(30);
|
||||
b->labeltype(FL_SHADOW_LABEL);
|
||||
grid->widget(b, 1, 1, 1, 5); // rowspan = 1, colspan = 5
|
||||
|
||||
// add a footer textbox, spanning 3 cells, right aligned
|
||||
|
||||
b = new Fl_Box(0, 0, 1, 10); // variable size
|
||||
b->label("FLTK/test/grid_alignment.cxx");
|
||||
b->labelfont(FL_COURIER);
|
||||
b->labelsize(11);
|
||||
b->align(FL_ALIGN_INSIDE | FL_ALIGN_RIGHT);
|
||||
grid->widget(b, 5, 2, 1, 3, FL_GRID_HORIZONTAL | FL_ALIGN_BOTTOM);
|
||||
|
||||
// input widgets with fixed size and alignment inside the cell
|
||||
|
||||
Fl_Input *i1 = new Fl_Input(0, 0, 100, 30, "Username:");
|
||||
c = grid->widget(i1, 2, 3, 1, 2); // widget, col, row, colspan, rowspan
|
||||
c->align(FL_GRID_HORIZONTAL); // widget alignment in cell
|
||||
|
||||
Fl_Input *i2 = new Fl_Input(0, 0, 100, 30, "Password:");
|
||||
c = grid->widget(i2, 3, 3, 1, 2); // widget, col, row, colspan, rowspan
|
||||
c->align(FL_GRID_HORIZONTAL); // widget alignment in cell
|
||||
|
||||
// the login button spans 2 columns
|
||||
|
||||
Fl_Button *bt = new Fl_Button(0, 0, 10, 30, "Login");
|
||||
grid->widget(bt, 4, 3, 1, 2, FL_GRID_HORIZONTAL); // widget, col, row, colspan, rowspan, alignment
|
||||
|
||||
grid->row_weight(1, 90);
|
||||
grid->row_weight(2, 0);
|
||||
grid->row_weight(3, 0);
|
||||
grid->row_weight(4, 0);
|
||||
|
||||
grid->col_weight(0, 30);
|
||||
grid->col_weight(4, 90);
|
||||
|
||||
grid->row_gap(5, 12);
|
||||
|
||||
grid->end();
|
||||
grid->layout();
|
||||
grid->debug(0);
|
||||
// grid->show_grid(1); // enable to display grid helper lines
|
||||
win->end();
|
||||
win->resizable(grid);
|
||||
win->size_range(440, 350);
|
||||
win->show(argc, argv);
|
||||
|
||||
#if (TEST_RELAYOUT)
|
||||
Fl::add_timeout(5.0, relayout_cb, grid);
|
||||
#endif
|
||||
|
||||
#if (TEST_REMOVE_NOTIFY)
|
||||
Fl::add_timeout(3.0, remove_cb, grid);
|
||||
#endif
|
||||
|
||||
// return Fl::run();
|
||||
int ret = Fl::run();
|
||||
grid->clear_layout();
|
||||
delete win;
|
||||
return ret;
|
||||
}
|
75
test/grid_buttons.cxx
Normal file
75
test/grid_buttons.cxx
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// Fl_Grid demo program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021 by Albrecht Schlosser
|
||||
// Copyright 2022-2023 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
|
||||
//
|
||||
|
||||
// Q: How to achieve a spaced out layout?
|
||||
// https://groups.google.com/g/fltkgeneral/c/haet7hOQR0g
|
||||
|
||||
// A: We use an Fl_Grid with 1 x 7 cells (5 buttons) as requested:
|
||||
// [New] [Options] <gap> [About] [Help] <gap> [Quit]
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Grid.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
Fl_Double_Window *win = new Fl_Double_Window(460, 200, "Fl_Grid Row with 5 Buttons");
|
||||
|
||||
Fl_Grid *grid = new Fl_Grid(0, 0, win->w(), 50);
|
||||
grid->layout(1, 7, 10, 10);
|
||||
|
||||
// create the buttons
|
||||
|
||||
Fl_Button *b0 = new Fl_Button(0, 0, 80, 30, "New");
|
||||
Fl_Button *b1 = new Fl_Button(0, 0, 80, 30, "Options");
|
||||
Fl_Button *b3 = new Fl_Button(0, 0, 80, 30, "About");
|
||||
Fl_Button *b4 = new Fl_Button(0, 0, 80, 30, "Help");
|
||||
Fl_Button *b6 = new Fl_Button(0, 0, 80, 30, "Quit");
|
||||
|
||||
grid->end();
|
||||
|
||||
// assign buttons to grid positions
|
||||
|
||||
grid->widget(b0, 0, 0);
|
||||
grid->widget(b1, 0, 1); grid->col_gap(1, 0);
|
||||
grid->widget(b3, 0, 3);
|
||||
grid->widget(b4, 0, 4); grid->col_gap(4, 0);
|
||||
grid->widget(b6, 0, 6);
|
||||
|
||||
// set column weights for resizing (only empty columns resize)
|
||||
|
||||
int weight[] = { 0, 0, 50, 0, 0, 50, 0 };
|
||||
grid->col_weight(weight, 7);
|
||||
|
||||
grid->end();
|
||||
// grid->show_grid(1); // enable to display grid helper lines
|
||||
|
||||
// add content ...
|
||||
|
||||
Fl_Group *g1 = new Fl_Group(0, 50, win->w(), win->h() - 50);
|
||||
// add more widgets ...
|
||||
|
||||
win->end();
|
||||
win->resizable(g1);
|
||||
win->size_range(win->w(), 100);
|
||||
win->show(argc, argv);
|
||||
|
||||
int ret = Fl::run();
|
||||
delete win; // not necessary but useful to test for memory leaks
|
||||
return ret;
|
||||
}
|
94
test/grid_login.cxx
Normal file
94
test/grid_login.cxx
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// Fl_Grid demo program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021 by Albrecht Schlosser
|
||||
// Copyright 2022-2023 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_Double_Window.H>
|
||||
#include <FL/Fl_Grid.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Input.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
Fl_Double_Window *win = new Fl_Double_Window(480, 200, "Fl_Grid \"Login\" Layout");
|
||||
|
||||
// Fl_Grid of 6 x 6 cells, margin 2 and gap 2
|
||||
|
||||
Fl_Grid *grid = new Fl_Grid(5, 5, 470, 190);
|
||||
grid->layout(6, 6, 2, 2); // 6 rows, 6 columns, margin 2, gap 2
|
||||
|
||||
// image (150x200) in left column
|
||||
|
||||
Fl_Box *ibox = new Fl_Box(0, 0, 150, 200, "Image");
|
||||
ibox->box(FL_BORDER_BOX);
|
||||
ibox->color(fl_rgb_color(0, 200, 0));
|
||||
grid->widget(ibox, 1, 1, 4, 1, FL_GRID_CENTER);
|
||||
|
||||
// the title spans 2 columns (3 - 4)
|
||||
|
||||
Fl_Box *title = new Fl_Box(0, 0, 200, 60);
|
||||
title->label("Welcome to Fl_Grid");
|
||||
title->align(FL_ALIGN_CENTER);
|
||||
title->labelfont(FL_BOLD + FL_ITALIC);
|
||||
title->labelsize(16);
|
||||
grid->widget(title, 1, 3, 1, 2, FL_GRID_HORIZONTAL | FL_GRID_CENTER);
|
||||
|
||||
grid->col_width(2, 90); // placeholder for labels
|
||||
|
||||
// input widgets with fixed height and horizontal stretching
|
||||
|
||||
Fl_Input *i1 = new Fl_Input(0, 0, 150, 30, "Username:");
|
||||
grid->widget(i1, 2, 3, 1, 2, FL_GRID_HORIZONTAL);
|
||||
grid->row_gap(2, 10); // gap below username
|
||||
|
||||
Fl_Input *i2 = new Fl_Input(0, 0, 150, 30, "Password:");
|
||||
grid->widget(i2, 3, 3, 1, 2, FL_GRID_HORIZONTAL);
|
||||
grid->row_gap(3, 10); // gap below password
|
||||
|
||||
// register and login buttons
|
||||
|
||||
Fl_Button *btr = new Fl_Button(0, 0, 80, 30, "Register");
|
||||
grid->widget(btr, 4, 3, 1, 1, FL_GRID_HORIZONTAL);
|
||||
grid->col_gap(3, 20); // gap right of the register button
|
||||
|
||||
Fl_Button *btl = new Fl_Button(0, 0, 80, 30, "Login");
|
||||
grid->widget(btl, 4, 4, 1, 1, FL_GRID_HORIZONTAL);
|
||||
|
||||
// set column and row weights for resizing behavior (optional)
|
||||
|
||||
int cw[] = { 20, 0, 0, 10, 10, 20}; // column weights
|
||||
int rw[] = { 10, 0, 0, 0, 0, 10}; // row weights
|
||||
grid->col_weight(cw, 6);
|
||||
grid->row_weight(rw, 6);
|
||||
|
||||
grid->end();
|
||||
grid->layout();
|
||||
// grid->debug(1);
|
||||
// grid->show_grid(1); // enable to display grid helper lines
|
||||
win->end();
|
||||
grid->color(fl_rgb_color(250, 250, 250));
|
||||
win->color(fl_rgb_color(250, 250, 250));
|
||||
|
||||
win->resizable(grid);
|
||||
win->resize(0, 0, 600, 300); // same size as flex_login
|
||||
win->size_range(550, 250);
|
||||
win->show(argc, argv);
|
||||
|
||||
int ret = Fl::run();
|
||||
delete win; // not necessary but useful to test for memory leaks
|
||||
return ret;
|
||||
}
|
@ -539,6 +539,7 @@ cube.o: ../FL/fl_config.h
|
||||
cube.o: ../FL/Fl_Device.H
|
||||
cube.o: ../FL/Fl_Export.H
|
||||
cube.o: ../FL/Fl_Gl_Window.H
|
||||
cube.o: ../FL/Fl_Grid.H
|
||||
cube.o: ../FL/Fl_Group.H
|
||||
cube.o: ../FL/Fl_Image.H
|
||||
cube.o: ../FL/Fl_Light_Button.H
|
||||
@ -550,6 +551,7 @@ cube.o: ../FL/Fl_Plugin.H
|
||||
cube.o: ../FL/Fl_Preferences.H
|
||||
cube.o: ../FL/Fl_Printer.H
|
||||
cube.o: ../FL/Fl_Radio_Light_Button.H
|
||||
cube.o: ../FL/Fl_Rect.H
|
||||
cube.o: ../FL/Fl_Slider.H
|
||||
cube.o: ../FL/Fl_String.H
|
||||
cube.o: ../FL/Fl_Sys_Menu_Bar.H
|
||||
|
Loading…
Reference in New Issue
Block a user