On 11/10/11 08:53, Albrecht Schlosser wrote:
> I tried with another class derived from Fl_Box instead of
> Fl_Table(_Row) as in your test, and it didn't show the effect.

        Albrecht: did the Fl_Box derived widget test involve
        overloading handle() to post the menu?

        If so, that'd probably work fine with Fl_Table as well,
        and would be different than OP's technique which uses
        the table's event_callback() to post the menu (a technique
        specific to Fl_Table that's meant to allow mouse events
        to make changes to the table)

        I think what's happening (not sure) is:
        Fl_Table calls its event_callback() *during* it's handle()
        method, and it's probably not expecting the event_callback()
        code to start its own event loop.

        I'm not sure it's technically possible for the event_callback()
        to be used for doing its own event loop (which popping up a
        blocking menu implies), so I think the below technique is
        probably needed, and the docs for Fl_Table::event_callback()
        should warn about this.

> I tested using an event display in handle(), and the box widget
> didn't get the push event. However, I can see a difference with
> your test program, but I don't know (yet?) what it is.
> 
> More tests needed. Greg, if you have an idea...

        Can I suggest the OP try this technique instead, which uses
        handle() to post the menu instead of the event_callback()

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Table_Row.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/fl_draw.H>

#define MAX_ROWS 30
#define MAX_COLS 4

// Derive a class from Fl_Table
class MyTable : public Fl_Table_Row {
  void DrawData(int X, int Y, int W, int H) {
    fl_push_clip(X,Y,W,H);
    // Draw cell bg
    fl_rectf(X,Y,W,H);
    // Draw box border
    fl_color(color()); fl_rect(X,Y,W,H);
    fl_pop_clip();
  }

  void draw_cell(TableContext context, int ROW=0, int COL=0, int X=0, int Y=0, 
int W=0, int H=0) {
    switch ( context ) {
      case CONTEXT_CELL:                        // Draw data in cells
        if (row_selected(ROW)) {
          printf("draw_cell Row=%d Col=%d Context=%d X=%d Y=%d W=%d H=%d\n", 
ROW, COL, context, X, Y, W, H);
          fl_color(FL_YELLOW);
        } else {
          fl_color(FL_WHITE);
        }
        DrawData(X,Y,W,H);
        return;
      default:
        return;
    }
  }
  //// NEW CODE HERE:START ////
  int handle(int e) {
    switch ( e ) {
      case FL_PUSH:
        // HANDLE THE MENU POSTING HERE INSTEAD, IN AN OVERLOAD OF 
MyTable::handle()
        if (Fl::event_button () == FL_RIGHT_MOUSE) {
          popmenu->position (Fl::event_x (), Fl::event_y ());
          popmenu->show();
          popmenu->popup();
          return(1);            // we handled the event
        } else {
          popmenu->hide ();
        }
        break;
    }
    return(Fl_Table_Row::handle(e));
    //// NEW CODE HERE:END ////
  }
  static void event_callback(Fl_Widget*, void*);
  void event_callback2();

public:
  Fl_Menu_Button *popmenu;
  MyTable(int X, int Y, int W, int H, const char *L=0) : 
Fl_Table_Row(X,Y,W,H,L) {
    // Rows
    rows(MAX_ROWS);             // how many rows
    // Cols
    cols(MAX_COLS);             // how many columns
    col_width_all(180);         // default width of columns
    end();                      // end the Fl_Table group
    callback (&event_callback, (void*)this);
  }
  ~MyTable() { }
};

void MyTable::event_callback(Fl_Widget*, void *data) {
  MyTable *o = (MyTable*)data;
  o->event_callback2();
}

/// Callback for table events
void MyTable::event_callback2()
{
  int R = callback_row(),
      C = callback_col();

  TableContext context = callback_context();
  printf("event_callback2 Row=%d Col=%d Context=%d Event=%d InteractiveResize? 
%d\n",
          R, C, (int)context, (int)Fl::event(), (int)is_interactive_resize());
  //// DONT DO POPUP MENU POSTING HERE: SEE ABOVE
}

Fl_Menu_Item menu_popmenu[] = {
  {"Insert Before...", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
  {"Insert After...", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
  {"Delete", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
  {"Edit...", 0,  0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
  {0,0,0,0,0,0,0,0,0}
};

int main(int argc, char **argv) {
  Fl_Double_Window win(900, 400, "Simple Table");
  MyTable table(0,0,880,380);
  table.type (MyTable::SELECT_SINGLE);

  Fl_Menu_Button popmenu(30,30,100,100);
  popmenu.menu(menu_popmenu);
  popmenu.type(Fl_Menu_Button::POPUP3);
  table.popmenu = &popmenu;

  win.end();
  win.resizable(table);
  win.show(argc,argv);
  return(Fl::run());
}
_______________________________________________
fltk mailing list
fltk@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to