diff --git a/examples/.gitignore b/examples/.gitignore index d4a21b441..2aaf8b559 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -39,6 +39,7 @@ table-spreadsheet table-spreadsheet-with-keyboard-nav table-with-keynav table-with-right-column-stretch-fit +table-with-right-click-menu tabs-simple textdisplay-with-colors texteditor-simple diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ea0b8487a..8912cffdf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -58,6 +58,7 @@ set (SIMPLE_SOURCES table-spreadsheet-with-keyboard-nav table-with-keynav table-with-right-column-stretch-fit + table-with-right-click-menu tabs-simple textdisplay-with-colors texteditor-simple diff --git a/examples/Makefile b/examples/Makefile index 43f1d3119..86eca0734 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -55,6 +55,7 @@ ALL = animgifimage$(EXEEXT) \ table-spreadsheet-with-keyboard-nav$(EXEEXT) \ table-with-keynav$(EXEEXT) \ table-with-right-column-stretch-fit$(EXEEXT) \ + table-with-right-click-menu$(EXEEXT) \ tabs-simple$(EXEEXT) \ textdisplay-with-colors$(EXEEXT) \ texteditor-simple$(EXEEXT) \ diff --git a/examples/table-with-right-click-menu.cxx b/examples/table-with-right-click-menu.cxx new file mode 100644 index 000000000..7f59ab575 --- /dev/null +++ b/examples/table-with-right-click-menu.cxx @@ -0,0 +1,131 @@ +// +// Simple example of using Fl_Table with popup menus - Greg Ercolano 12/16/2023 +// Ref: https://www.seriss.com/people/erco/fltk/#GLDynamicPopup +// +// Copyright 2023 Greg Ercolano. +// Copyright 1998-2010 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 +#include +#include +#include +#include + +#define MAX_ROWS 30 +#define MAX_COLS 26 // A-Z + +// Derive a class from Fl_Table +class MyTable : public Fl_Table { + // Post context menu at current event x,y + void PostContextMenu() { + int context = callback_context(); + switch (context) { + case CONTEXT_COL_HEADER: + case CONTEXT_CELL: { + char s[80]; + // Create context sensitive menu label + if ( context == CONTEXT_CELL ) { + sprintf(s, "Cell %c%d", 'A'+callback_col(), callback_row()); + } else { + sprintf(s, "Column %c", 'A'+callback_col()); + } + // Post dynamically created context menu, get user's choice + Fl_Menu_Button menu(Fl::event_x(), Fl::event_y(), 80, 1); + menu.add(s, 0, 0, 0, FL_MENU_DIVIDER|FL_MENU_INACTIVE); + menu.add("Item 1"); + menu.add("Item 2"); + const Fl_Menu_Item *item = menu.popup(); + if ( item ) printf("You chose '%s'\n", item->label()); + break; + } + default: break; + } + } + + // MyTable callback + static void my_callback(Fl_Widget*, void*data) { + MyTable *o = (MyTable*)data; + if ( Fl::event_button() == FL_RIGHT_MOUSE ) o->PostContextMenu(); + } + + // Draw the row/col headings + // Make this a dark thin upbox with the text inside. + // + void DrawHeader(const char *s, int X, int Y, int W, int H) { + fl_push_clip(X,Y,W,H); + fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, row_header_color()); + fl_color(FL_BLACK); + fl_draw(s, X,Y,W,H, FL_ALIGN_CENTER); + fl_pop_clip(); + } + // Draw the cells + void DrawCell(const char *s, int X, int Y, int W, int H) { + fl_push_clip(X,Y,W,H); + fl_color(FL_WHITE); fl_rectf(X,Y,W,H); // Draw cell bg + fl_color(FL_GRAY0); fl_draw(s, X,Y,W,H, FL_ALIGN_CENTER); // Draw cell text + fl_color(color()); fl_rect(X,Y,W,H); // Draw box border + fl_pop_clip(); + } + // Handle drawing table's cells + // Fl_Table calls this function to draw each visible cell in the table. + // It's up to us to use FLTK's drawing functions to draw the cells the way we want. + // + void draw_cell(TableContext context, int ROW=0, int COL=0, int X=0, int Y=0, int W=0, int H=0) FL_OVERRIDE { + static char s[40]; + switch ( context ) { + case CONTEXT_STARTPAGE: // before page is drawn.. + fl_font(FL_HELVETICA, 16); // set the font for our drawing operations + return; + case CONTEXT_COL_HEADER: // Draw column headers + sprintf(s,"%c",'A'+COL); // "A", "B", "C", etc. + DrawHeader(s,X,Y,W,H); + return; + case CONTEXT_ROW_HEADER: // Draw row headers + sprintf(s,"%03d:",ROW); // "001:", "002:", etc + DrawHeader(s,X,Y,W,H); + return; + case CONTEXT_CELL: // Draw cells + sprintf(s,"%c%d",'A'+COL,ROW); + DrawCell(s,X,Y,W,H); + return; + default: + return; + } + } +public: + // Constructor + MyTable(int X, int Y, int W, int H, const char *L=0) : Fl_Table(X,Y,W,H,L) { + // Rows + rows(MAX_ROWS); // how many rows + row_header(1); // enable row headers (along left) + row_height_all(20); // default height of rows + row_resize(0); // disable row resizing + // Cols + cols(MAX_COLS); // how many columns + col_header(1); // enable column headers (along top) + col_width_all(80); // default width of columns + col_resize(1); // enable column resizing + end(); // end the Fl_Table group + callback(my_callback, (void*)this); // set a callback for the table + } + ~MyTable() { } +}; + +int main(int argc, char **argv) { + Fl_Double_Window win(900, 400, "Table Simple"); + MyTable table(10,10,880,380); + win.end(); + win.resizable(table); + win.show(argc,argv); + return(Fl::run()); +}