Using Fl_Window (Fl_Double_Window) + set_non_modal() is definitely easier, and 
does not hog input. Thanks for mentioning that, Ian.

New problem, though. Test code is below.

Regardless of what group/win type I use, mouse input will pass through the 
popup to the window/widgets below. This acts like an insertion-order thing. So, 
widget is drawn z-top, but it is z-below for input. I can "fix" the input order 
by making sure the other widget additions occur before the suggestion box.

In my project, though, I can't control/guarantee the insertion order of the 
widget into the parent group ... so I'm a bit stumped.

Ideas? I'll keep reading docs/threads ...

Denton

---

/** \file main.cpp

  creating a "suggestions" drop-down box

  CHANGES
    - dentonlt, jan 2013: original version

*/

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Select_Browser.H>
#include <FL/names.h>

class SuggestionBox : public Fl_Window {

  Fl_Widget *anchor_;
  Fl_Select_Browser *browser_;

  static void static_browser_cb_(Fl_Widget *src, void *dat) {
    if(!src || !dat) printf("SuggestionBox::browser_cb_ rec'd NULL arg.\n");
    else ((SuggestionBox *)dat)->browser_cb_(src, dat);
  }

  void browser_cb_(Fl_Widget *src, void *dat) {
    // hack!
    printf("SuggestionBox::browser_cb_ runs\n"); fflush(stdout);
    set_changed();
    hide();
  }

  int handle(int event) {
    //printf("SuggestionBox::handle() ran with event %s\n", 
fl_eventnames[event]);
    int ret = Fl_Window::handle(event);
    if(changed()) {
      clear_changed();
      if(callback()) do_callback();
    }
    return ret;
  }

public:
  SuggestionBox(int X, int Y, int W, int H, const char *n = NULL) :
    Fl_Window(X, Y, W, H, n) {

    anchor_ = NULL;

    browser_ = new Fl_Select_Browser(0, 0, W, H);
      browser_->callback(static_browser_cb_, this);

    // mock 'selection' data
      browser_->add("red");
      browser_->add("read");
      browser_->add("reed");
      browser_->add("regurgitate");

    Fl_Window::end();
    //clear_border();
    //set_non_modal(); // stay on top, do not capture events

    }

  Fl_Select_Browser *browser() { return browser_; }

  void anchor(Fl_Widget *a) { anchor_ = a; }

};

class SuggestionInput : public Fl_Input {

  SuggestionBox *browser_;

  static void static_browser_cb_(Fl_Widget *src, void *dat) {
    if(!src || !dat) printf("SuggestionInput::browser_cb_ rec'd NULL arg.\n");
    else ((SuggestionInput *)dat)->browser_cb_(src, dat);
  }

  void browser_cb_(Fl_Widget *src, void *dat) {
    // hack!
    printf("SuggestionInput::browser_cb_ runs\n"); fflush(stdout);
    value(browser_->browser()->text(browser_->browser()->value()));
    browser_->hide();
  }

  void post_suggestions_() {
    printf("SuggestionInput::post_suggestions_() runs\n"); fflush(stdout);
    if(browser_->parent()) browser_->position(x(), y() + h());
    //else browser_->position(Fl::first_window()->x() + x(), 
Fl::first_window()->y() + y() + h());
    browser_->show();
    browser_->redraw();
  }

  int handle(int event) {
    int ret = Fl_Input::handle(event);
    if(changed()) {
      clear_changed();
      if(value()) post_suggestions_();
      if(callback()) do_callback();
    }
    return ret;
  }

public:
  SuggestionInput(int X, int Y, int W, int H, const char *n = NULL) :
    Fl_Input(X, Y, W, H, n) {
    browser_ = new SuggestionBox(0, 0, W, 80);
      browser_->callback(static_browser_cb_, this);
      browser_->hide();
      browser_->anchor(this);

    // try both with & without ...
    //if(browser_->parent()) browser_->parent(NULL);
  }

  ~SuggestionInput() {
    printf("SuggestionInput::dtor runs\n"); fflush(stdout);
    delete browser_;
  }

};


void button_cb_(Fl_Widget *, void *) {
  printf("button_cb_ ran.\n"); fflush(stdout);
}

int main (int argc, char ** argv)
{
  Fl_Window *window;
  Fl_Input *input;
  Fl_Button *button;

  window = new Fl_Window (600, 300);

    // if I create 'button' here, then it is 'under' the popup.

    input = new SuggestionInput(10, 10, 200, 35);

    // creating button here hides input from previously inserted widgets
    button = new Fl_Button(10, 45, 200, 35, "nothing"); // this masks input 
into the popup ...
      button->callback(button_cb_, NULL);

  window->resizable(NULL);
  window->end ();
  window->show (argc, argv);

  return(Fl::run());
}

_______________________________________________
fltk mailing list
fltk@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to