Hello,

OK, success at last. Or at least partial success.

I have modified my test code to include your suggestions, thanks a lot!

But as usual when one problem is solved n others popup (no pun intended).

Here is what I've got so far:

Popup works with
1) click+release until clicked outside or on button in popup
2) while clicked until released on button in popup (but not outside)

There are some odd things I have noticed, though:

1) FL_ENTER is transmitted to the children but curiously not FL_LEAVE.
The only way to make sure that they are highlighted appropriately while
hovering is to use a loop: for all children: child(i)->handle(FL_LEAVE)
in the popup window handle before sending the actual event to the
children. While this is a work-around it does not seem to be a
particularly pretty one.
2) Tooltips are only shown from the menu-button not from the
Fl_Active_Button inside the popup. Oddly enough, the tooltips are not
shown with 1.3.x but the text of the menu-button tooltip is shown for
the Fl_Active_Buttons in 1.1.9 (maybe because of grab?).
3) FL_PUSH does not get routed to buttons.

4) Even though the popup window is modal I seem to be able to move the
main window while the popup window is shown! That looks rather odd and
is not a desired behavior, I'm sure.
5) When you click on the window decorations of the main window the popup
should disappear - but does not (e.g. system menu) or X, or they should
not be accessible at all.

My current test platform is Ubuntu running KDE3, FLTK 1.3-r8514.

Could anybody confirm my observations?

Even better, would anybody know of a solution to some of the problems
mentioned above?

Thanks a lot,

Herman


Below the adapted code:

It should run for 1.3.x and 1.1.x (you have to comment one line in the
MyMenuWindow constructor).

// M E N U T E S T . C X /////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Menu_Window.H>

class Fl_Active_Button:public Fl_Button
{
  public:
  Fl_Active_Button(int X, int Y, int W, int H, const char*
L=""):Fl_Button(X,Y,W,H,L)
  { color(FL_BLUE);
  }
  int handle(int e)
  { fprintf(stderr,"receive event in active button: %d\n",e);
    switch(e)
    { case FL_ENTER:
      case FL_MOVE: color(FL_RED); redraw(); return(1);
      case FL_LEAVE: color(FL_BLUE); redraw(); return(1);
//      case FL_PUSH: do_callback(); return(1);  // never received!
      case FL_RELEASE: if (Fl::event_inside(this))
do_callback(this,user_data()); return(1);
      default:  color(FL_BLUE); return(Fl_Button::handle(e));
    }
  }
};

class Fl_Redirect_Button:public Fl_Button
{ Fl_Window* _win;
  public:
  Fl_Redirect_Button(int X, int Y, int W, int H, const char*
L=""):Fl_Button(X,Y,W,H,L)
  { redirect(NULL);
  }

  void redirect(Fl_Window* w) {_win=w;}
  Fl_Window* redirect() {return(_win);}

  int handle(int e)
  { switch(e)
    { case FL_PUSH:
      { if (redirect())
        { redirect()->position(window()->x()+x(),window()->y()+y()+h());
          redirect()->show();
          redirect()->set_modal();

          Fl::grab(redirect());
          Fl::focus( redirect() );
          while( redirect()->visible()) Fl::wait();
          fprintf(stderr,"grab out\n");
          Fl::grab(0);

          redirect()->hide();
          Fl::focus(this);
          return(1);
        }
      } break;
    }
    return(Fl_Button::handle(e));
  }
};

class MyMenuWindow:public Fl_Menu_Window
{
  public:
  MyMenuWindow(int W, int H, const char* L=""):Fl_Menu_Window(W,H,L)
  { set_modal();
    set_menu_window(); //comment this line when compiling for FLTK 1.1.x
  }

  int handle(int e)
  { fprintf(stderr,"event in menuwindow: %d\n",e);
    for(int i=0;i<children();++i) child(i)->handle(FL_LEAVE);
    if (e==FL_DRAG) e=FL_MOVE;
    if (e==FL_PUSH && !Fl::event_inside(this)) this->hide();
// this does not seem to work as intended (seems always true,
// probably due to grab)
//    if (e==FL_RELEASE && !Fl::event_inside(this)) this->hide();

   return(Fl_Menu_Window::handle(e));
  }
};

void bcallback(Fl_Active_Button* o,void*v)
{ fprintf(stderr,"********* in button-callback: %d\n",(int)v);
  o->window()->hide();
}

int main(int argc, char** argv)
{
  MyMenuWindow* hidden=new MyMenuWindow(120,150);
      hidden->border(0);
      hidden->set_modal();

      Fl_Active_Button* ba=new Fl_Active_Button(10,10,100,50,"Hello");
      ba->tooltip("hello test");
      ba->callback((Fl_Callback*)bcallback);
      ba->user_data((void*)0);

      Fl_Active_Button* ba2=new Fl_Active_Button(10,60,100,50,"Hello2");

      ba2->tooltip("hello2 test");
      ba2->callback((Fl_Callback*)bcallback);
      ba2->user_data((void*)1);
  hidden->end();

  Fl_Window * win=new Fl_Window(120,100,"test menu");
      Fl_Redirect_Button* b=new Fl_Redirect_Button(10,10,100,25,"clickme");
      b->redirect(hidden);
      b->tooltip("click the button to open the widget menu");
  win->end();

  win->show(argc,argv);
  return(Fl::run());
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to