ask.C

#include <stdio.h>
#include <string.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Return_Button.H>

int get_string(char*buffer, const char *from) {
  Fl_Window window(320,75);
  window.set_modal();
  Fl_Input input(60, 40, 250, 25,"Input:");
  input.value(buffer);
  Fl_Button cancel(60, 10,80, 25,"cancel");
  Fl_Return_Button ok(150, 10,80, 25,"OK");
  window.end();
  window.show();
  for (;;) {
    Fl::wait();
    Fl_Widget *o;
    while (o = Fl::readqueue()) {
      if (o == &ok) {
	strcpy(buffer, input.value());
	return 1;
      } else if (o == &cancel || o == &window) {
	return 0;
      }
    }
  }
}

int main(int argc, char **argv) {
  char buffer[128];
  if (get_string(buffer, argv[1])) {
    puts(buffer);
    return 0;
  } else {
    return 1; // exit with error
  }
}

Widgets don't need to have callback() set. The default callback puts a pointer to the widget on a "queue" from which it can later be read with Fl::readqueue(). This was done for Forms compatibility but it is useful for modal windows. In this example the "get_string" function puts up a modal window and loops until one of the buttons is pushed. Fl::wait() does exactly one cycle of what Fl::run() does repeatedly: it updates the screen and then waits for and responds to an event (or several events if they are all ready at the same time). It then returns, allowing the user program to check any state information it wants to after each group of events. One thing the user program can check is Fl::readqueue() which returns each object without a callback that was triggered. It returns null when the queue is empty. It is possible for more than one object to be on the queue (or the same object several times) so if your program wants to read the queue it should always read it until empty and ignore unrecognized widgets (don't look at them as they may have been deleted).

modal() on a window prevents any interaction with other program windows below it, and prevents the user from raising a program window above it (well, it tries, but X is broken). It won't make any difference in this program because there is only one window, but this allows the "get_string" function to be used as subroutine by a larger program and have the expected behavior.

This program also demonstrates that fltk widgets may be constructed as C++ automatic objects (local variables). You have to be careful about destruction, however. Always make sure all automatic children are destructed before the container (by declaring the children after the container), since the destructor for a container will attempt to delete all remaining children, and you don't want to delete automatic objects.

[Next example]
[back to contents]