summaryrefslogtreecommitdiff
path: root/test/cube.cxx
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2023-10-16 22:11:33 +0200
committerAlbrecht Schlosser <albrechts.fltk@online.de>2023-10-16 22:18:24 +0200
commit38871c5b3192bccd508f3686413d4e56041ab091 (patch)
tree26db3ef4a73e93f23a1d1bcb037652aafc26dbed /test/cube.cxx
parente7b790ae31b3c5d5e819f35f5fa8bd3619f7103f (diff)
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
Diffstat (limited to 'test/cube.cxx')
-rw-r--r--test/cube.cxx189
1 files changed, 96 insertions, 93 deletions
diff --git a/test/cube.cxx b/test/cube.cxx
index 2dacb5976..bd69bc42c 100644
--- a/test/cube.cxx
+++ b/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
+// 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 *, void *) {
+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)
-{
+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 );
+ 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 .
+// . lt_cube center : rt_cube .
// . 350 100 : 350 .
// . |<------------------->| |<-------->| |<------------------->| .
// ....................................................................
-// : ....................... ............ ....................... :
+// : ....................... ............ ....................... : __
// : : : : : : : :
-// : : A : : B : : C : :
+// : : A : : B : : C : : h = 350
// : : : : : : : :
// : :.....................: :..........: :.....................: : __
// :..................................................................: __ MARGIN
//
-// | |
-// MARGIN
-//
+// | | | | | |
+// MARGIN GAP GAP
-#define MENUBAR_H 25 // menubar height
-#define MARGIN 20 // fixed margin around widgets
-#define MARGIN2 (MARGIN*2)
-#define MARGIN3 (MARGIN*3)
-
-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.");
-}
+#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);
+
+ // 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);
+
+ // 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
- 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();
+ // left GL window
+ lt_cube = new cube_box(0, 0, 350, 350);
- // 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);
+ // 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
}