#include #include #include #include #include #include #include class Tpt_Return_Button : public Fl_Return_Button { public: int handle(int event) { if (event == FL_KEYBOARD && (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) { simulate_key_action(); do_callback(); return 1; } else return Fl_Button::handle(event); } Tpt_Return_Button(int x, int y, int w, int h) : Fl_Return_Button(x, y, w, h) {} }; static Fl_Window *message_form; static Fl_Box *message; static Fl_Box *icon; static const int N_BUTTONS = 3; static Fl_Button *button[N_BUTTONS]; static int ret_val; static const char *iconlabel = "?"; static const char *message_title_default; Fl_Font fl_message_font_ = FL_HELVETICA; Fl_Fontsize fl_message_size_ = -1; static int enableHotspot = 1; static char avoidRecursion = 0; // Sets the global return value (ret_val) and closes the window. static void button_cb(Fl_Widget *, long val) { ret_val = (int) val; if (Fl::event_key() == FL_Escape) ret_val = -1; message_form->hide(); } // If the window is simply closed, that's the same as hitting escape static void form_cb(Fl_Widget *, long val) { ret_val = -1; message_form->hide(); } static Fl_Window *makeform() { if (message_form) { return message_form; } // make sure that the dialog does not become the child of some // current group Fl_Group *previously_current_group = Fl_Group::current(); Fl_Group::current(0); // create a new top level window Fl_Window *w = message_form = new Fl_Window(410,103); message_form->callback(form_cb); (message = new Fl_Box(60, 25, 340, 20)) ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP); {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50); o->box(FL_THIN_UP_BOX); o->labelfont(FL_TIMES_BOLD); o->labelsize(34); o->color(FL_WHITE); o->labelcolor(FL_BLUE); } w->end(); // don't add the buttons automatically // create the buttons (right to left) for (int b=0, x=100*N_BUTTONS+10; balign(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); button[b]->callback(button_cb, b); } button[0]->shortcut(FL_Escape); // add the buttons (left to right so arrow keys work) for (int b = N_BUTTONS-1; b >= 0; --b) w->add(button[b]); w->begin(); w->resizable(new Fl_Box(60,10,110-60,27)); w->end(); w->set_modal(); Fl_Group::current(previously_current_group); return w; } /* * 'resizeform()' - Resize the form and widgets so that they hold everything * that is asked of them... */ static void resizeform() { int i; int message_w, message_h; int text_height; int button_w[N_BUTTONS], button_h[N_BUTTONS]; int x, w, h, max_w, max_h; const int icon_size = 50; message_form->size(410,103); fl_font(message->labelfont(), message->labelsize()); message_w = message_h = 0; fl_measure(message->label(), message_w, message_h); message_w += 10; message_h += 10; if (message_w < 340) message_w = 340; if (message_h < 30) message_h = 30; fl_font(button[0]->labelfont(), button[0]->labelsize()); memset(button_w, 0, sizeof(button_w)); memset(button_h, 0, sizeof(button_h)); for (max_h = 25, i = 0; i < N_BUTTONS; i ++) if (button[i]->visible()) { fl_measure(button[i]->label(), button_w[i], button_h[i]); if (i == 1) button_w[1] += 20; button_w[i] += 30; button_h[i] += 10; if (button_h[i] > max_h) max_h = button_h[i]; } text_height = message_h; max_w = message_w + 10 + icon_size; w = -10; for (int i = 0; i < N_BUTTONS; ++i) w += button_w[i]; if (w > max_w) max_w = w; message_w = max_w - 10 - icon_size; w = max_w + 20; h = max_h + 30 + text_height; message_form->size(w, h); message_form->size_range(w, h, w, h); message->resize(20 + icon_size, 10, message_w, message_h); icon->resize(10, 10, icon_size, icon_size); icon->labelsize(icon_size - 10); for (x = w, i = 0; i < N_BUTTONS; i ++) if (button_w[i]) { x -= button_w[i]; button[i]->resize(x, h - 10 - max_h, button_w[i] - 10, max_h); } message_form->init_sizes(); } int tpt_choose(const char* prompt, const char* op0, const char *op1, const char* op2, int curx) { if (avoidRecursion) return 0; Fl::pushed(0); // stop dragging avoidRecursion = 1; makeform(); message_form->size(410,103); message->label(prompt); message->labelfont(fl_message_font_); if (fl_message_size_ == -1) message->labelsize(FL_NORMAL_SIZE); else message->labelsize(fl_message_size_); if (op0) { button[0]->show(); button[0]->label(op0); button[1]->position(210,70); } else { button[0]->hide(); button[1]->position(310,70); } if (op1) { button[1]->show(); button[1]->label(op1);} else button[1]->hide(); if (op2) { button[2]->show(); button[2]->label(op2); } else button[2]->hide(); button[curx]->take_focus(); const char* prev_icon_label = icon->label(); if (!prev_icon_label) icon->label(iconlabel); resizeform(); if (enableHotspot) message_form->hotspot(button[0]); if (op0 && Fl_Widget::label_shortcut(op0)) button[0]->shortcut(0); else button[0]->shortcut(FL_Escape); // set default window title, if defined and a specific title is not set if (!message_form->label() && message_title_default) message_form->label(message_title_default); // deactivate Fl::grab(), because it is incompatible with modal windows Fl_Window* g = Fl::grab(); if (g) Fl::grab(0); Fl_Group *current_group = Fl_Group::current(); // make sure the dialog does not interfere with any active group message_form->show(); Fl_Group::current(current_group); while (message_form->shown()) Fl::wait(); if (g) // regrab the previous popup menu, if there was one Fl::grab(g); icon->label(prev_icon_label); message_form->label(0); // reset window title avoidRecursion = 0; return ret_val; }