1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
//
// "$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 <FL/names.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 {
protected:
// 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_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 selected = G_rowselect->value() ? row_selected(R) : is_selected(R,C);
fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, selected ? 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<rows(); R++ ) {
for ( int C=0; C<cols(); C++ ) {
if ( G_rowselect->value() ? row_selected(R) : is_selected(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); }
// Update only if different (lets one copy/paste from sum)
if ( strcmp(s,G_sum->value()))
{ G_sum->value(s); G_sum->redraw(); }
}
// Keyboard and mouse events
int handle(int e) {
int ret = Fl_Table_Row::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: {
//ret = 1; // *don't* indicate we 'handled' these, just update ('handling' prevents e.g. tab nav)
UpdateSum();
redraw();
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::option(Fl::OPTION_ARROW_FOCUS, 0); // disable arrow focus nav (we want arrows to control cells)
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 Shift + 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);
G_sum->tooltip("This field shows the sum of the selected cells in the table");
win.end();
win.resizable(G_table);
win.show();
return Fl::run();
}
//
// End of "$Id$".
//
|