Author: greg.ercolano
Date: 2010-12-10 10:24:47 -0800 (Fri, 10 Dec 2010)
New Revision: 8001
Log:
Code cleanup for two table spreadsheet examples.


Modified:
   branches/branch-1.3/examples/table-spreadsheet.cxx
   branches/branch-1.3/examples/table-with-keyboard-nav.cxx

Modified: branches/branch-1.3/examples/table-spreadsheet.cxx
===================================================================
--- branches/branch-1.3/examples/table-spreadsheet.cxx  2010-12-10 17:52:14 UTC 
(rev 8000)
+++ branches/branch-1.3/examples/table-spreadsheet.cxx  2010-12-10 18:24:47 UTC 
(rev 8001)
@@ -29,8 +29,8 @@
 #include <stdlib.h>
 #include <FL/Fl.H>
 #include <FL/Fl_Double_Window.H>
-#include <FL/Fl_Int_Input.H>
 #include <FL/Fl_Table.H>
+#include <FL/Fl_Int_Input.H>
 #include <FL/fl_draw.H>
 
 const int MAX_COLS = 10;
@@ -42,22 +42,21 @@
   int row_edit, col_edit;                              // row/col being 
modified
 
 protected:
-  void draw_cell(TableContext context, int=0, int=0, int=0, int=0, int=0, 
int=0);
+  void draw_cell(TableContext context,int=0,int=0,int=0,int=0,int=0,int=0);
   void event_callback2();                              // table's event 
callback (instance)
-  static void event_callback(Fl_Widget*, void *v) {    // table's event 
callback (static)
+  static void event_callback(Fl_Widget*,void *v) {     // table's event 
callback (static)
     ((Spreadsheet*)v)->event_callback2();
   }
-  // Handle input widget's callback
-  static void input_cb(Fl_Widget*, void* v) {
+  static void input_cb(Fl_Widget*,void* v) {           // input widget's 
callback
     ((Spreadsheet*)v)->set_value_hide();
   }
 
 public:
-  Spreadsheet(int x, int y, int w, int h, const char* l=0) : 
Fl_Table(x,y,w,h,l) {
+  Spreadsheet(int X,int Y,int W,int H,const char* L=0) : Fl_Table(X,Y,W,H,L) {
     callback(&event_callback, (void*)this);
     when(FL_WHEN_NOT_CHANGED|when());
     // Create input widget that we'll use whenever user clicks on a cell
-    input = new Fl_Int_Input(w/2,h/2,0,0);
+    input = new Fl_Int_Input(W/2,H/2,0,0);
     input->hide();
     input->callback(input_cb, (void*)this);
     input->when(FL_WHEN_ENTER_KEY_ALWAYS);             // callback triggered 
when user hits Enter
@@ -100,29 +99,29 @@
   // Return the sum of all rows in this column
   int sum_rows(int C) {
     int sum = 0;
-    for (int r=0; r<MAX_ROWS; ++r)
+    for (int r=0; r<rows()-1; ++r)                     // -1: don't include 
cell data in 'totals' column
       sum += values[r][C];
     return(sum);
   }
   // Return the sum of all cols in this row
   int sum_cols(int R) {
     int sum = 0;
-    for (int c=0; c<MAX_COLS; ++c)
+    for (int c=0; c<cols()-1; ++c)                     // -1: don't include 
cell data in 'totals' column
       sum += values[R][c];
     return(sum);
   }
   // Return the sum of all cells in table
   int sum_all() {
     int sum = 0;
-    for (int c=0; c<MAX_COLS; ++c)
-      for (int r=0; r<MAX_ROWS; ++r)
+    for (int c=0; c<cols()-1; ++c)                     // -1: don't include 
cell data in 'totals' column
+      for (int r=0; r<rows()-1; ++r)                   // -1: ""
        sum += values[r][c];
     return(sum);
   }
 };
 
 // Handle drawing all cells in table
-void Spreadsheet::draw_cell(TableContext context, int R, int C, int X, int Y, 
int W, int H) {
+void Spreadsheet::draw_cell(TableContext context, int R,int C, int X,int Y,int 
W,int H) {
   static char s[30]; 
   switch ( context ) {
     case CONTEXT_STARTPAGE:                    // table about to redraw
@@ -168,7 +167,7 @@
       if ( C < cols()-1 && R < rows()-1 ) {
        fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, FL_WHITE);
       } else {
-       fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, 0xbbddbb00);
+       fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, 0xbbddbb00);       // money green
       }
       // Text
       fl_push_clip(X+3, Y+3, W-6, H-6);
@@ -214,16 +213,15 @@
            start_editing(R,C);                         // start new edit
          return;
 
-       case FL_KEYBOARD: {
+       case FL_KEYBOARD:                               // key press in table?
          if ( Fl::event_key() == FL_Escape ) exit(0);  // ESC closes app
-         if (C == cols()-1 || R == rows()-1) return;   // can't edit totals 
column
+         if (C == cols()-1 || R == rows()-1) return;   // no editing of totals 
column
          done_editing();                               // finish any previous 
editing
          start_editing(R,C);                           // start new edit
          if (Fl::event() == FL_KEYBOARD && Fl::e_text[0] != '\r') {
            input->handle(Fl::event());                 // pass keypress to 
input widget
          }
          return;
-        }
       }
       return;
     }

Modified: branches/branch-1.3/examples/table-with-keyboard-nav.cxx
===================================================================
--- branches/branch-1.3/examples/table-with-keyboard-nav.cxx    2010-12-10 
17:52:14 UTC (rev 8000)
+++ branches/branch-1.3/examples/table-with-keyboard-nav.cxx    2010-12-10 
18:24:47 UTC (rev 8001)
@@ -1,8 +1,9 @@
 //
 // "$Id$"
 //
-//     Test Jean-Marc's mods for keyboard nav and mouse selection
-//     using a modified version of the Fl_Table 'singleinput' program.
+//     Simple example of an interactive spreadsheet using Fl_Table.
+//     Uses Mr. Satan's technique of instancing an Fl_Input around.
+//     Modified to test Jean-Marc's mods for keyboard nav and mouse selection.
 //
 //      Fl_Table[1.00/LGPL] 04/18/03 Mister Satan      -- Initial 
implementation, submitted to erco for Fl_Table
 //      Fl_Table[1.10/LGPL] 05/17/03 Greg Ercolano     -- Small mods to follow 
changes to Fl_Table
@@ -31,61 +32,65 @@
 //
 //     http://www.fltk.org/str.php
 //
+#include <stdio.h>
+#include <stdlib.h>
 #include <FL/Fl.H>
 #include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Table.H>
 #include <FL/Fl_Int_Input.H>
 #include <FL/Fl_Value_Slider.H>
 #include <FL/fl_draw.H>
-#include <FL/Fl_Table.H>
-#include <stdio.h>
-#include <stdlib.h>
 
 const int MAX_COLS = 26;
 const int MAX_ROWS = 500;
 
-class SingleInput : public Fl_Table {
-  Fl_Int_Input* input;
-  int values[MAX_ROWS][MAX_COLS];
-  int row_edit, col_edit;
-  int s_left, s_top, s_right, s_bottom;        // kb nav + mouse selection
+class Spreadsheet : public Fl_Table {
+  Fl_Int_Input *input;                                 // single instance of 
Fl_Int_Input widget
+  int values[MAX_ROWS][MAX_COLS];                      // array of data for 
cells
+  int row_edit, col_edit;                              // row/col being 
modified
+  int s_left, s_top, s_right, s_bottom;                        // kb nav + 
mouse selection
 
 protected:
-  void draw_cell(TableContext context, int=0, int=0, int=0, int=0, int=0, 
int=0);
-  static void event_callback(Fl_Widget*, void*);
-  void event_callback2();
-  static void input_cb(Fl_Widget*, void* v);
+  void draw_cell(TableContext context,int=0,int=0,int=0,int=0,int=0,int=0);
+  void event_callback2();                              // table's event 
callback (instance)
+  static void event_callback(Fl_Widget*, void *v) {    // table's event 
callback (static)
+    ((Spreadsheet*)v)->event_callback2();
+  }
+  static void input_cb(Fl_Widget*, void* v) {          // input widget's 
callback
+    ((Spreadsheet*)v)->set_value_hide();
+  }
 
 public:
-  SingleInput(int x, int y, int w, int h, const char* l=0) : 
Fl_Table(x,y,w,h,l) {
-    int i, j;
+  Spreadsheet(int X,int Y,int W,int H,const char* L=0) : Fl_Table(X,Y,W,H,L) {
     callback(&event_callback, (void*)this);
     when(FL_WHEN_NOT_CHANGED|when());
-    input = new Fl_Int_Input(w/2,h/2,0,0);
+    // Create input widget that we'll use whenever user clicks on a cell
+    input = new Fl_Int_Input(W/2,H/2,0,0);
     input->hide();
     input->callback(input_cb, (void*)this);
-    input->when(FL_WHEN_ENTER_KEY_ALWAYS);
+    input->when(FL_WHEN_ENTER_KEY_ALWAYS);             // callback triggered 
when user hits Enter
     input->maximum_size(5);
-    for (i = 0; i < MAX_ROWS; i++) {
-      for (j = 0; j < MAX_COLS; j++) {
-       values[i][j] = (i + 2) * (j + 3);
-      }
-    }
+    for (int c = 0; c < MAX_COLS; c++)
+      for (int r = 0; r < MAX_ROWS; r++)
+       values[r][c] = (r + 2) * (c + 3);               // initialize cells
     end();
   }
-  ~SingleInput() { }
+  ~Spreadsheet() { }
 
+  // Apply value from input widget to values[row][col] array and hide (done 
editing)
+  void set_value_hide() {
+    values[row_edit][col_edit] = atoi(input->value());
+    input->hide();
+    window()->cursor(FL_CURSOR_DEFAULT);               // XXX: if we don't do 
this, cursor can disappear!
+  }
   // Change number of rows
   void rows(int val) {
-    if (input->visible()) {
-      input->do_callback(); 
-    }
+    set_value_hide();
     Fl_Table::rows(val);
   }
   // Change number of columns
   void cols(int val) {
-    if (input->visible()) {
-      input->do_callback();
-    }
+    set_value_hide();
     Fl_Table::cols(val);
   }
   // Get number of rows
@@ -96,20 +101,54 @@
   inline int cols() {
     return Fl_Table::cols();
   }
-  // Apply value from input widget to values[row][col] array
-  void set_value() {
-    values[row_edit][col_edit] = atoi(input->value());
-    input->hide();
+  // Start editing a new cell: move the Fl_Int_Input widget to specified 
row/column
+  //    Preload the widget with the cell's current value,
+  //    and make the widget 'appear' at the cell's location.
+  //
+  void start_editing(int R, int C) {
+    row_edit = R;                                      // Now editing this 
row/col
+    col_edit = C;
+    int X,Y,W,H;
+    find_cell(CONTEXT_CELL, R,C, X,Y,W,H);             // Find X/Y/W/H of cell
+    input->resize(X,Y,W,H);                            // Move Fl_Input widget 
there
+    char s[30]; sprintf(s, "%d", values[R][C]);                // Load input 
widget with cell's current value
+    input->value(s);
+    input->position(0,strlen(s));                      // Select entire input 
field
+    input->show();                                     // Show the input 
widget, now that we've positioned it
+    input->take_focus();
   }
+  // Tell the input widget it's done editing, and to 'hide'
+  void done_editing() {
+    if (input->visible()) {                            // input widget 
visible, ie. edit in progress?
+      set_value_hide();                                        // Transfer its 
current contents to cell and hide
+    }
+  }
+  // Return the sum of all rows in this column
+  int sum_rows(int C) {
+    int sum = 0;
+    for (int r=0; r<rows()-1; ++r)                     // -1: don't include 
cell data in 'totals' column
+      sum += values[r][C];
+    return(sum);
+  }
+  // Return the sum of all cols in this row
+  int sum_cols(int R) {
+    int sum = 0;
+    for (int c=0; c<cols()-1; ++c)                     // -1: don't include 
cell data in 'totals' column
+      sum += values[R][c];
+    return(sum);
+  }
+  // Return the sum of all cells in table
+  int sum_all() {
+    int sum = 0;
+    for (int c=0; c<cols()-1; ++c)                     // -1: don't include 
cell data in 'totals' column
+      for (int r=0; r<rows()-1; ++r)                   // -1: ""
+       sum += values[r][c];
+    return(sum);
+  }
 };
 
-void SingleInput::input_cb(Fl_Widget*, void* v) {
-  ((SingleInput*)v)->set_value();
-}
-
 // Handle drawing all cells in table
-void SingleInput::draw_cell(TableContext context, 
-                           int R, int C, int X, int Y, int W, int H) {
+void Spreadsheet::draw_cell(TableContext context, int R,int C, int X,int Y,int 
W,int H) {
   static char s[30]; 
   switch ( context ) {
     case CONTEXT_STARTPAGE:                    // table about to redraw
@@ -118,37 +157,32 @@
       break;
 
     case CONTEXT_COL_HEADER:                   // table wants us to draw a 
column heading (C is column)
-      fl_font(FL_HELVETICA | FL_BOLD, 14);
-      fl_push_clip(X, Y, W, H);
+      fl_font(FL_HELVETICA | FL_BOLD, 14);     // set font for heading to bold
+      fl_push_clip(X,Y,W,H);                   // clip region for text
       {
-       fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
+       fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, col_header_color());
        fl_color(FL_BLACK);
-       if (C != cols()-1) {
-         // Not last column? Show column letter
-         s[0] = 'A' + C;
-         s[1] = '\0';
-         fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER);
-       } else {
-         // Last column? show 'TOTAL'
-         fl_draw("TOTAL", X, Y, W, H, FL_ALIGN_CENTER);
+       if (C == cols()-1) {                    // Last column? show 'TOTAL'
+         fl_draw("TOTAL", X,Y,W,H, FL_ALIGN_CENTER);
+       } else {                                // Not last column? show column 
letter
+         sprintf(s, "%c", 'A' + C);
+         fl_draw(s, X,Y,W,H, FL_ALIGN_CENTER);
        }
       }
       fl_pop_clip();
       return;
 
     case CONTEXT_ROW_HEADER:                   // table wants us to draw a row 
heading (R is row)
-      fl_font(FL_HELVETICA | FL_BOLD, 14);
-      fl_push_clip(X, Y, W, H);
+      fl_font(FL_HELVETICA | FL_BOLD, 14);     // set font for row heading to 
bold
+      fl_push_clip(X,Y,W,H);
       {
-       fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, row_header_color());
+       fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, row_header_color());
        fl_color(FL_BLACK);
-       if (R != rows()-1) {
-         // Not last row? Show row number
+       if (R == rows()-1) {                    // Last row? Show 'Total'
+         fl_draw("TOTAL", X,Y,W,H, FL_ALIGN_CENTER);
+       } else {                                // Not last row? show row#
          sprintf(s, "%d", R+1);
-         fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER);
-       } else {
-         // Last row? show 'TOTAL'
-         fl_draw("TOTAL", X, Y, W, H, FL_ALIGN_CENTER);
+         fl_draw(s, X,Y,W,H, FL_ALIGN_CENTER);
        }
       }
       fl_pop_clip();
@@ -156,47 +190,35 @@
 
     case CONTEXT_CELL: {                       // table wants us to draw a cell
       if (R == row_edit && C == col_edit && input->visible()) {
-       return;
+       return;                                 // dont draw for cell with 
input widget over it
       }
-
-      // BACKGROUND
+      // Background
       // Keyboard nav and mouse selection highlighting
       if (R >= s_top && R <= s_bottom && C >= s_left && C <= s_right) {
-       fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, FL_YELLOW);
+       fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, FL_YELLOW);
+      } else if ( C < cols()-1 && R < rows()-1 ) {
+       fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, FL_WHITE);
       } else {
-       fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, FL_WHITE);
+       fl_draw_box(FL_THIN_UP_BOX, X,Y,W,H, 0xbbddbb00);       // money green
       }
-
-      // TEXT
+      // Text
       fl_push_clip(X+3, Y+3, W-6, H-6);
       {
        fl_color(FL_BLACK); 
-       if (C != cols()-1 && R != rows()-1) {
-         fl_font(FL_HELVETICA, 14);
-         sprintf(s, "%d", values[R][C]);
-         fl_draw(s, X+3, Y+3, W-6, H-6, FL_ALIGN_RIGHT);
-       } else {
-         int T = 0;
-         fl_font(FL_HELVETICA | FL_BOLD, 14);
-
-         if (C == cols()-1 && R == rows()-1) { // All cells total
-           for (int c=0; c<cols()-1; ++c) {
-             for (int r=0; r<rows()-1; ++r) {
-               T += values[r][c];
-             }
-           }
+       if (C == cols()-1 || R == rows()-1) {   // Last row or col? Show total
+         fl_font(FL_HELVETICA | FL_BOLD, 14);  // ..in bold font
+         if (C == cols()-1 && R == rows()-1) { // Last row+col? Total all cells
+           sprintf(s, "%d", sum_all());
          } else if (C == cols()-1) {           // Row subtotal
-           for (int c=0; c<cols()-1; ++c) {
-             T += values[R][c];
-           }
+           sprintf(s, "%d", sum_cols(R));
          } else if (R == rows()-1) {           // Col subtotal
-           for (int r=0; r<rows()-1; ++r) {
-             T += values[r][C];
-           }
+           sprintf(s, "%d", sum_rows(C));
          }
-
-         sprintf(s, "%d", T);
-         fl_draw(s, X+3, Y+3, W-6, H-6, FL_ALIGN_RIGHT);
+         fl_draw(s, X+3,Y+3,W-6,H-6, FL_ALIGN_RIGHT);
+       } else {                                // Not last row or col? Show 
cell contents
+         fl_font(FL_HELVETICA, 14);            // ..in regular font
+         sprintf(s, "%d", values[R][C]);
+         fl_draw(s, X+3,Y+3,W-6,H-6, FL_ALIGN_RIGHT);
        }
       }
       fl_pop_clip();
@@ -219,70 +241,39 @@
 }
 
 // Callback whenever someone clicks on different parts of the table
-void SingleInput::event_callback(Fl_Widget*, void* data) {
-  SingleInput* o = (SingleInput*)data;
-  o->event_callback2();
-}
-
-void SingleInput::event_callback2() {
+void Spreadsheet::event_callback2() {
   int R = callback_row();
   int C = callback_col();
   TableContext context = callback_context(); 
 
   switch ( context ) {
-    case CONTEXT_CELL: {                       // A table event occurred on a 
cell
-      fprintf(stderr, "CALLBACK: CONTEXT_CELL: for R/C: %d / %d\n", R, C); 
-      switch (Fl::event()) { 
-       case FL_PUSH:
-         if (!Fl::event_clicks()) {
-           if (input->visible()) input->do_callback();
-           input->hide();
-           return;
-         }
-         Fl::event_clicks(0);
-         //FALLTHROUGH
+    case CONTEXT_CELL: {                               // A table event 
occurred on a cell
+      switch (Fl::event()) {                           // see what FLTK event 
caused it
+       case FL_PUSH:                                   // mouse click?
+         done_editing();                               // finish editing 
previous
+         if (R != rows()-1 && C != cols()-1 )          // only edit cells not 
in total's columns
+           start_editing(R,C);                         // start new edit
+         return;
 
-       case FL_KEYBOARD:
-         if ( Fl::event_key() == FL_Escape )
-           exit(0);                            // ESC closes app
-         if (Fl::event() == FL_KEYBOARD && 
-            ( Fl::e_length == 0 || Fl::event_key() == FL_Tab) ) {
-           return;                             // ignore eg. keyboard nav keys
-         }
-         if (C == cols()-1 || R == rows()-1) return;
-         if (input->visible()) input->do_callback();
-         row_edit = R;
-         col_edit = C;
-         set_selection(R, C, R, C);
-         int XX,YY,WW,HH;
-         find_cell(CONTEXT_CELL, R, C, XX, YY, WW, HH);
-         input->resize(XX,YY,WW,HH);
-         char s[30];
-         sprintf(s, "%d", values[R][C]);
-         input->value(s);
-         input->position(0,strlen(s));         // pre-highlight (so typing 
replaces contents)
-         input->show();
-         input->take_focus();
+       case FL_KEYBOARD:                               // key press in table?
+         if ( Fl::event_key() == FL_Escape ) exit(0);  // ESC closes app
+         if (C == cols()-1 || R == rows()-1) return;   // no editing of totals 
column
+         done_editing();                               // finish any previous 
editing
+         set_selection(R, C, R, C);                    // select the current 
cell
+         start_editing(R,C);                           // start new edit
          if (Fl::event() == FL_KEYBOARD && Fl::e_text[0] != '\r') {
-           input->handle(Fl::event());
+           input->handle(Fl::event());                 // pass keypress to 
input widget
          }
          return;
       }
       return;
     }
 
-    case CONTEXT_ROW_HEADER:                   // A table event occurred on 
row/column header
+    case CONTEXT_TABLE:                                        // A table 
event occurred on dead zone in table
+    case CONTEXT_ROW_HEADER:                           // A table event 
occurred on row/column header
     case CONTEXT_COL_HEADER:
-      if (input->visible()) input->do_callback();
-      input->hide();
+      done_editing();                                  // done editing, hide
       return;
-
-    case CONTEXT_TABLE:                                // A table event 
occurred on dead zone in table
-      if (R < 0 && C < 0) {
-       if (input->visible()) input->do_callback();
-       input->hide();
-      }
-      return;
     
     default:
       return;
@@ -291,23 +282,25 @@
 
 // Change number of columns
 void setcols_cb(Fl_Widget* w, void* v) {
-  SingleInput* table = (SingleInput*)v;
+  Spreadsheet* table = (Spreadsheet*)v;
   Fl_Valuator* in = (Fl_Valuator*)w;
   int cols = int(in->value()) + 1;
   table->cols(cols);
+  table->redraw();
 }
 
 // Change number of rows
 void setrows_cb(Fl_Widget* w, void* v) {
-  SingleInput* table = (SingleInput*)v;
+  Spreadsheet* table = (Spreadsheet*)v;
   Fl_Valuator* in = (Fl_Valuator*)w;
   int rows = int(in->value()) + 1;
   table->rows(rows);
+  table->redraw();
 }
 
 int main() {
-  Fl_Double_Window *win = new Fl_Double_Window(600, 400, "table with keyboard 
nav");
-  SingleInput* table = new SingleInput(20, 20, win->w()-80, win->h()-80);
+  Fl_Double_Window *win = new Fl_Double_Window(922, 382, "Fl_Table Spreadsheet 
with Keyboard Navigation");
+  Spreadsheet* table = new Spreadsheet(20, 20, win->w()-80, win->h()-80);
   // Table rows
   table->row_header(1);
   table->row_header_width(70);

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to