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

Reply via email to