diff options
| -rw-r--r-- | examples/Makefile | 1 | ||||
| -rw-r--r-- | examples/table-with-keynav.cxx | 197 |
2 files changed, 198 insertions, 0 deletions
diff --git a/examples/Makefile b/examples/Makefile index 2e8d35767..f2e32a758 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -17,6 +17,7 @@ ALL = howto-add_fd-and-popen$(EXEEXT) \ table-sort$(EXEEXT) \ table-spreadsheet$(EXEEXT) \ table-spreadsheet-with-keyboard-nav$(EXEEXT) \ + table-with-keynav$(EXEEXT) \ tabs-simple$(EXEEXT) \ textdisplay-with-colors$(EXEEXT) \ texteditor-simple$(EXEEXT) \ diff --git a/examples/table-with-keynav.cxx b/examples/table-with-keynav.cxx new file mode 100644 index 000000000..995e85e41 --- /dev/null +++ b/examples/table-with-keynav.cxx @@ -0,0 +1,197 @@ +// +// "$Id$" +// +// Example of Fl_Table with keyboard selection navigation - Greg Ercolano 04/14/2012 +// +// Display a 10x10 multiplication table, and allow the user to +// make cell or row selections (with mouse or keyboard navigation) +// to select areas of the table, and show the sum of the cell's values. +// +// Started with the "testkeyboardnav.cxx" example from the original +// Fl_Table project, using Jean-Marc Lienher's additions for keyboard nav. +// +// Copyright 2003, 2012 Greg Ercolano. +// Copyright 2004 Jean-Marc Lienher +// 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: +// +// http://www.fltk.org/COPYING.php +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +#include <FL/Fl.H> +#include <FL/fl_draw.H> +#include <FL/Fl_Double_Window.H> +#include <FL/Fl_Toggle_Button.H> +#include <FL/Fl_Output.H> +#include <FL/Fl_Table_Row.H> +#include <stdio.h> +#include <stdlib.h> + +// GLOBALS +class MyTable; +Fl_Toggle_Button *G_rowselect = 0; // toggle to enable row selection +MyTable *G_table = 0; // table widget +Fl_Output *G_sum = 0; // displays sum of user's selection + +class MyTable : public Fl_Table_Row { + int row_beg, col_beg, row_end, col_end; // kb nav + mouse selection +protected: + // See if row R and column C is inside selection area + int IsSelected(int R, int C) { + if ( G_rowselect->value() == 0 ) + return( (R >= row_beg && R <= col_end && + C >= col_beg && C <= row_end) ? 1 : 0); + else + return( (R >= row_beg && R <= col_end) ? 1 : 0); + } + // Handle drawing all cells in table + void draw_cell(TableContext context, int R=0,int C=0, int X=0,int Y=0,int W=0,int H=0) { + static char s[30]; + switch ( context ) { + case CONTEXT_STARTPAGE: + // Whenever we redraw the table, update row/col selection vals first + get_selection(row_beg, col_beg, col_end, row_end); + break; + case CONTEXT_COL_HEADER: + case CONTEXT_ROW_HEADER: + fl_font(FL_HELVETICA | FL_BOLD, 14); + fl_push_clip(X, Y, W, H); + { + Fl_Color c = (context==CONTEXT_COL_HEADER) ? col_header_color() : row_header_color(); + fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, c); + fl_color(FL_BLACK); + // Draw text for headers + sprintf(s, "%d", (context == CONTEXT_COL_HEADER) ? C : R); + fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); + } + fl_pop_clip(); + return; + case CONTEXT_CELL: { + // Keyboard nav and mouse selection highlighting + int is_select = IsSelected(R,C); + fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, is_select ? FL_YELLOW : FL_WHITE); + // Draw text for the cell + fl_push_clip(X+3, Y+3, W-6, H-6); + { + fl_font(FL_HELVETICA, 14); + fl_color(FL_BLACK); + sprintf(s, "%d", R*C); // factor row + col for data cells + fl_draw(s, X+3, Y+3, W-6, H-6, FL_ALIGN_RIGHT); + } + fl_pop_clip(); + return; + } + default: + return; + } + } +public: + // CTOR + MyTable(int x, int y, int w, int h, const char *l=0) : Fl_Table_Row(x,y,w,h,l) { + // Row init + row_header(1); + row_header_width(70); + row_resize(1); + rows(11); + row_height_all(20); + // Col init + col_header(1); + col_header_height(20); + col_resize(1); + cols(11); + col_width_all(70); + end(); // Fl_Table derives from Fl_Group, so end() it + } + ~MyTable() { } + // Update the displayed sum value + int GetSelectionSum() { + int sum = -1; + for ( int R=0; R<11; R++ ) { + for ( int C=0; C<11; C++ ) { + if ( IsSelected(R,C) ) { + if ( sum == -1 ) sum = 0; + sum += R*C; + } + } + } + return(sum); + } + // Update the "Selection sum:" display + void UpdateSum() { + static char s[80]; + int sum = GetSelectionSum(); + if ( sum == -1 ) { sprintf(s, "(nothing selected)"); G_sum->color(48); } + else { sprintf(s, "%d", sum); G_sum->color(FL_WHITE); } + G_sum->value(s); + G_sum->redraw(); + } + // Keyboard and mouse events + int handle(int e) { + // See if selection changed + static int lastselect = 0; + int thisselect = row_beg + (row_end*11) + (col_beg*11*2) + (col_end*11*3); + int ret = Fl_Table::handle(e); + if ( e == FL_KEYBOARD && Fl::event_key() == FL_Escape ) exit(0); + switch (e) { + case FL_PUSH: + case FL_RELEASE: + case FL_KEYUP: + case FL_KEYDOWN: + case FL_DRAG: { + if ( lastselect != thisselect ) { // Selection changed? + UpdateSum(); // update the sum + redraw(); // XXX: needed for row selection to redraw properly + lastselect = thisselect; + } + ret = 1; + break; + } + case FL_FOCUS: // tells FLTK we're interested in keyboard events + case FL_UNFOCUS: + ret = 1; + break; + } + return(ret); + } +}; + +// User changed the 'row select' toggle button +void RowSelect_CB(Fl_Widget *w, void*) { + w->window()->redraw(); // redraw with changes applied + G_table->UpdateSum(); +} +int main() { + Fl_Double_Window win(862, 312, "table-with-keynav"); + win.begin(); + // Create table + G_table = new MyTable(10, 30, win.w()-20, win.h()-70, "Times Table"); + G_table->tooltip("Use mouse or arrow keys to make selections.\n" + "Sum of selected values is shown."); + // Row select toggle button + G_rowselect = new Fl_Toggle_Button(140,10,12,12,"Row selection"); + G_rowselect->align(FL_ALIGN_LEFT); + G_rowselect->value(0); + G_rowselect->selection_color(FL_YELLOW); + G_rowselect->callback(RowSelect_CB); + G_rowselect->tooltip("Click to toggle row vs. row/col selection"); + // Selection sum display + win.end(); + win.begin(); + G_sum = new Fl_Output(140,G_table->y()+G_table->h()+10,160,25,"Selection Sum:"); + G_sum->value("(nothing selected)"); + G_sum->color(48); + win.end(); + win.resizable(G_table); + win.show(); + return Fl::run(); +} + +// +// End of "$Id$". +// |
