summaryrefslogtreecommitdiff
path: root/examples/table-with-right-click-menu.cxx
blob: 7f59ab575a6e0173c10f737fd748cd43ffd3d320 (plain)
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
//
//    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 <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Table.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Menu_Button.H>

#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());
}