summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/Makefile1
-rw-r--r--examples/table-with-keynav.cxx197
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$".
+//