OK, you have a good approach, but you need to use a different Window type that
is specifically made for this.
Derive your own class from Fl_Menu_Window. In the constructor, call set_modal()
and set_menu_window(). Your window should now receive DRAG and RELEASE events
even without first getting the corresponding PUSH event.
To pop up the window, call Fl_Group::current(0) to avoid being added as a
child, create your menu window, call Fl::grab(myMenu), and show the window
(might have to swap these two!). Then stay in aloop as long as the menu window
is visible: while (myMenu->visible()) Fl::wait(); . Once this returns, call
Fl::grab(0L);
It's 4 am and I can't test right now if it works, but this is basically what
popup() does. I am not sure if a regular button as a child of the popup window
will receive DRAG and RELEASE events if it did not get a PUSH event. You may
have to write your own button code here.
Oh, and this is what I wrote a long time ago. I am not sure if it still works
with 1.3.0, or does what your need:
class Flmm_Popup_Window : public Fl_Window
{
public:
Flmm_Popup_Window( int W, int H, char *L = 0L );
char popup(int x=999999, int y=999999);
void focus(int x, int y);
void focus(Fl_Widget const* const w);
protected:
int handle( int );
void show();
char done;
int focus_x, focus_y;
};
Flmm_Popup_Window::Flmm_Popup_Window( int W, int H, char *L)
: Fl_Window(0, 0, W, H, L)
{
done = 0;
focus_x = focus_y = 0;
clear_border();
box(FL_UP_BOX);
set_non_modal();
}
char Flmm_Popup_Window::popup(int x, int y)
{
if (x==999999)
x = Fl::event_x_root();
if (y==999999)
y = Fl::event_y_root();
position(x-focus_x, y-focus_y);
Fl_Window::show();
Fl::grab(this);
while (visible()) {
Fl::wait();
}
Fl::release();
return 1;
}
void Flmm_Popup_Window::show() {
popup();
}
void Flmm_Popup_Window::focus(int x, int y)
{
focus_x = x;
focus_y = y;
}
void Flmm_Popup_Window::focus(Fl_Widget const* const w)
{
if (w)
focus(w->x()+w->w()/2, w->y()+w->h()/2);
}
int Flmm_Popup_Window::handle(int ev)
{
if (ev == FL_KEYBOARD && Fl::focus()) {
if (Fl::focus()->handle(ev)==1)
return 1;
if (Fl::focus()->handle(FL_SHORTCUT)==1)
return 1;
if (Fl::event_key()==FL_Escape) {
if (callback())
do_callback();
return 1;
}
} else if (ev == FL_PUSH) {
int ex = Fl::event_x(), ey = Fl::event_y();
if ( ex<0 || ey<0 || ex>w() || ey>h() ) {
hide();
if (callback())
do_callback();
return 1;
}
Fl_Window *pg = Fl::grab_;
Fl::grab_ = 0;
Fl_Window::handle(ev);
Fl::grab_ = pg;
return 1;
}
return Fl_Window::handle(ev);
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk