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
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk