diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2023-10-16 22:11:33 +0200 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2023-10-16 22:18:24 +0200 |
| commit | 38871c5b3192bccd508f3686413d4e56041ab091 (patch) | |
| tree | 26db3ef4a73e93f23a1d1bcb037652aafc26dbed /test/cube.cxx | |
| parent | e7b790ae31b3c5d5e819f35f5fa8bd3619f7103f (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.cxx | 189 |
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 } |
