summaryrefslogtreecommitdiff
path: root/src/fl_ask.cxx
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2021-12-04 13:35:47 +0100
committerAlbrecht Schlosser <albrechts.fltk@online.de>2021-12-04 14:49:27 +0100
commitb6de09cff2465db3c0a6e6a013b825462bc9a0e7 (patch)
tree23725f27cc08e314f3c5d15d1c47c3f3b24b7588 /src/fl_ask.cxx
parent240465626604ed9a7f7b2cb997ab4dffd419eabc (diff)
Re-enable nested (aka recursive) common dialogs (STR 3242, #282)
Apply Fl_Dialog_r10831.patch as given in STR 3242: https://www.fltk.org/strfiles/3242/Fl_Dialog_r10831.patch Reformat, add missing pieces, rename private members, cleanup... Improve documentation, add fl_choice_n() (issue #282) New methods fl_input_str() and fl_password_str() return Fl_String
Diffstat (limited to 'src/fl_ask.cxx')
-rw-r--r--src/fl_ask.cxx888
1 files changed, 390 insertions, 498 deletions
diff --git a/src/fl_ask.cxx b/src/fl_ask.cxx
index c9255f14e..a4e44ffc3 100644
--- a/src/fl_ask.cxx
+++ b/src/fl_ask.cxx
@@ -15,361 +15,128 @@
//
/**
- \file fl_ask.cxx
- \brief Utility functions for common dialogs.
- */
-
-// Implementation of fl_message, fl_ask, fl_choice, fl_input
-// The three-message fl_show_x functions are for forms compatibility
-// mostly. In most cases it is easier to get a multi-line message
-// by putting newlines in the message.
-
-#include <FL/Fl.H>
-#include <FL/fl_string.h>
-#include <FL/fl_ask.H>
-#include "flstring.h"
-
-#include <FL/Fl_Box.H>
-#include <FL/Fl_Button.H>
-#include <FL/Fl_Return_Button.H>
-#include <FL/Fl_Window.H>
-#include <FL/Fl_Input.H>
-#include <FL/Fl_Secret_Input.H>
-#include <FL/platform.H>
-#include "Fl_Screen_Driver.H"
-#include <FL/fl_draw.H>
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
-static Fl_Window *message_form;
-static Fl_Box *message;
-static Fl_Box *icon;
-static Fl_Button *button[3];
-static Fl_Input *input;
-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 int form_x = 0;
-static int form_y = 0;
-static int form_position = 0; // 0 = not set, 1 = absolute, 2 = centered
-
-static char avoidRecursion = 0;
-
-// Sets the global return value (ret_val) and closes the window.
-// Note: this is used for the button callbacks and the window
-// callback (closing the window with the close button or menu).
-// The first argument (Fl_Widget *) can either be an Fl_Button*
-// pointer to one of the buttons or an Fl_Window* pointer to the
-// message window (message_form).
-static void button_cb(Fl_Widget *, long val) {
- ret_val = (int) val;
- 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(button_cb);
- // w->clear_border();
- // w->box(FL_UP_BOX);
- (message = new Fl_Box(60, 25, 340, 20))
- ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
- (input = new Fl_Input(60, 37, 340, 23))->hide();
- {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=310; b<3; b++, x -= 100) {
- if (b==1)
- button[b] = new Fl_Return_Button(x, 70, 90, 23);
- else
- button[b] = new Fl_Button(x, 70, 90, 23);
- button[b]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
- button[b]->callback(button_cb, b);
- }
- }
- button[0]->shortcut(FL_Escape);
- // add the buttons (left to right)
- {
- for (int b=2; 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[3], button_h[3];
- 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 < 3; 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];
- }
-
- if (input->visible()) text_height = message_h + 25;
- else text_height = message_h;
-
- max_w = message_w + 10 + icon_size;
- w = button_w[0] + button_w[1] + button_w[2] - 10;
+ \addtogroup group_comdlg
+ @{
+*/
- if (w > max_w)
- max_w = w;
+/**
+ \file fl_ask.cxx
- message_w = max_w - 10 - icon_size;
+ \brief Utility functions for common dialogs.
- w = max_w + 20;
- h = max_h + 30 + text_height;
+ This file defines the functions
- message_form->size(w, h);
- message_form->size_range(w, h, w, h);
+ - fl_alert()
+ - fl_beep()
+ - fl_message()
+ - fl_ask()
+ - fl_choice()
+ - fl_input()
+ - fl_input_str()
+ - fl_password()
+ - fl_password_str()
- message->resize(20 + icon_size, 10, message_w, message_h);
- icon->resize(10, 10, icon_size, icon_size);
- icon->labelsize(icon_size - 10);
- input->resize(20 + icon_size, 10 + message_h, message_w, 25);
+ and some more functions to change their behavior (positioning,
+ window title, and more).
- for (x = w, i = 0; i < 3; i ++)
- if (button_w[i])
- {
- x -= button_w[i];
- button[i]->resize(x, h - 10 - max_h, button_w[i] - 10, max_h);
+ Since FLTK 1.4.0 a big part of these functions is
+ implemented in class Fl_Message.
+*/
-// printf("button %d (%s) is %dx%d+%d,%d\n", i, button[i]->label(),
-// button[i]->w(), button[i]->h(),
-// button[i]->x(), button[i]->y());
- }
- message_form->init_sizes();
-}
+#include <FL/Fl.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input_.H>
+#include "flstring.h"
+#include "Fl_Screen_Driver.H"
+#include <FL/fl_ask.H>
+#include "Fl_Message.h" // intentionally "hidden" in src/...
-static int innards(const char* fmt, va_list ap,
- const char *b0,
- const char *b1,
- const char *b2)
-{
- Fl::pushed(0); // stop dragging (STR #2159)
-
- avoidRecursion = 1;
-
- makeform();
- message_form->size(410,103);
- char buffer[1024];
- if (!strcmp(fmt,"%s")) {
- message->label(va_arg(ap, const char*));
- } else {
- ::vsnprintf(buffer, 1024, fmt, ap);
- message->label(buffer);
- }
+#include <stdio.h>
+#include <stdarg.h>
- message->labelfont(fl_message_font_);
- if (fl_message_size_ == -1)
- message->labelsize(FL_NORMAL_SIZE);
- else
- message->labelsize(fl_message_size_);
- if (b0) {button[0]->show(); button[0]->label(b0); button[1]->position(210,70);}
- else {button[0]->hide(); button[1]->position(310,70);}
- if (b1) {button[1]->show(); button[1]->label(b1);}
- else button[1]->hide();
- if (b2) {button[2]->show(); button[2]->label(b2);}
- else button[2]->hide();
- const char* prev_icon_label = icon->label();
- if (!prev_icon_label) icon->label(iconlabel);
-
- resizeform();
-
- if (button[1]->visible() && !input->visible())
- button[1]->take_focus();
-
- if (form_position) {
- if (form_position == 2) { // centered
- form_x -= message_form->w()/2;
- form_y -= message_form->h()/2;
- }
- message_form->position(form_x, form_y);
- form_x = form_y = form_position = 0;
- } else if (enableHotspot)
- message_form->hotspot(button[0]);
- else
- message_form->free_position();
-
- if (b0 && Fl_Widget::label_shortcut(b0))
- 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;
-}
+// static, configurable variables
- /** \addtogroup group_comdlg
- @{ */
+Fl_Font fl_message_font_ = FL_HELVETICA;
+Fl_Fontsize fl_message_size_ = -1;
// pointers you can use to change FLTK to another language:
-const char* fl_no = "No"; ///< string pointer used in common dialogs, you can change it to another language
-const char* fl_yes= "Yes"; ///< string pointer used in common dialogs, you can change it to another language
-const char* fl_ok = "OK"; ///< string pointer used in common dialogs, you can change it to another language
-const char* fl_cancel= "Cancel"; ///< string pointer used in common dialogs, you can change it to another language
-const char* fl_close= "Close"; ///< string pointer used in common dialogs, you can change it to another language
+const char *fl_no = "No"; ///< string pointer used in common dialogs, you can change it to another language
+const char *fl_yes = "Yes"; ///< string pointer used in common dialogs, you can change it to another language
+const char *fl_ok = "OK"; ///< string pointer used in common dialogs, you can change it to another language
+const char *fl_cancel = "Cancel"; ///< string pointer used in common dialogs, you can change it to another language
+const char *fl_close = "Close"; ///< string pointer used in common dialogs, you can change it to another language
// fltk functions:
/**
- Emits a system beep message.
- \param[in] type The beep type from the \ref Fl_Beep enumeration.
- \note \#include <FL/fl_ask.H>
- */
-void fl_beep(int type)
-{
+ Emits a system beep message.
+
+ \param[in] type The beep type from the \ref Fl_Beep enumeration.
+
+ \code #include <FL/fl_ask.H> \endcode
+*/
+void fl_beep(int type) {
Fl::screen_driver()->beep(type);
}
-
/** Shows an information message dialog box.
- \note Common dialog boxes are application modal. No more than one common dialog box
- can be open at any time. Requests for additional dialog boxes are ignored.
- \note \#include <FL/fl_ask.H>
-
+ \code #include <FL/fl_ask.H> \endcode
- \param[in] fmt can be used as an sprintf-like format and variables for the message text
- */
+ \param[in] fmt can be used as an sprintf-like format and variables for the message text
+*/
void fl_message(const char *fmt, ...) {
- if (avoidRecursion) return;
-
+ Fl_Message msg("i");
va_list ap;
// fl_beep(FL_BEEP_MESSAGE);
va_start(ap, fmt);
- iconlabel = "i";
- innards(fmt, ap, 0, fl_close, 0);
+ msg.innards(fmt, ap, 0, fl_close, 0);
va_end(ap);
- iconlabel = "?";
}
-/** Shows an alert message dialog box
+/** Shows an alert message dialog box.
- \note Common dialog boxes are application modal. No more than one common dialog box
- can be open at any time. Requests for additional dialog boxes are ignored.
- \note \#include <FL/fl_ask.H>
+ \code #include <FL/fl_ask.H> \endcode
\param[in] fmt can be used as an sprintf-like format and variables for the message text
- */
+*/
void fl_alert(const char *fmt, ...) {
- if (avoidRecursion) return;
-
+ Fl_Message msg("!");
va_list ap;
// fl_beep(FL_BEEP_ERROR);
va_start(ap, fmt);
- iconlabel = "!";
- innards(fmt, ap, 0, fl_close, 0);
+ msg.innards(fmt, ap, 0, fl_close, 0);
va_end(ap);
- iconlabel = "?";
}
+
/** Shows a dialog displaying the \p fmt message,
- this dialog features 2 yes/no buttons
+ this dialog features 2 yes/no buttons.
- \note Common dialog boxes are application modal. No more than one common dialog box
- can be open at any time. Requests for additional dialog boxes are ignored.
- \note \#include <FL/fl_ask.H>
+ \code #include <FL/fl_ask.H> \endcode
\param[in] fmt can be used as an sprintf-like format and variables for the message text
- \retval 0 if the no button is selected or another dialog box is still open
+ \retval 0 if the no button is selected
\retval 1 if yes is selected
\deprecated fl_ask() is deprecated since it uses "Yes" and "No" for the buttons which
does not conform to the current FLTK Human Interface Guidelines.
Use fl_choice() with the appropriate verbs instead.
- */
+*/
int fl_ask(const char *fmt, ...) {
- if (avoidRecursion) return 0;
-
+ Fl_Message msg("?");
va_list ap;
// fl_beep(FL_BEEP_QUESTION);
va_start(ap, fmt);
- int r = innards(fmt, ap, fl_no, fl_yes, 0);
+ int r = msg.innards(fmt, ap, fl_no, fl_yes, 0);
va_end(ap);
return r;
@@ -377,295 +144,420 @@ int fl_ask(const char *fmt, ...) {
/** Shows a dialog displaying the printf style \p fmt message.
- This dialog features up to 3 customizable choice buttons
- which are specified in order of *right-to-left* in the dialog, e.g.
- \image html fl_choice_left_middle_right.png
- \image latex fl_choice_left_middle_right.png "fl_choice() button ordering" width=4cm
-
- \note Common dialog boxes are application modal. No more than one common dialog box
- can be open at any time. Requests for additional dialog boxes are ignored.
- \note \#include <FL/fl_ask.H>
-
- Three choices with printf() style formatting:
- \image html fl_choice_three_fmt.png
- \image latex fl_choice_three_fmt.png "fl_choice() three choices with printf formatting" width=4cm
- \code
- int num_msgs = GetNumberOfMessages();
- switch ( fl_choice("What to do with %d messages?", "Send", "Save", "Delete", num_msgs) ) {
- case 0: .. // Send
- case 1: .. // Save (default)
- case 2: .. // Delete
- ..
- }
- \endcode
-
- Three choice example:
- \image html fl_choice_three.png
- \image latex fl_choice_three.png "fl_choice() three choices" width=4cm
- \code
- switch ( fl_choice("How many bedrooms?", "Zero", "One", "Two") ) {
- case 0: .. // "Zero"
- case 1: .. // "One" (default)
- case 2: .. // "Two"
- }
- \endcode
-
- Two choice example:
- \image html fl_choice_two.png
- \image latex fl_choice_two.png "fl_choice() two choices" width=4cm
- \code
- switch ( fl_choice("Empty trash?", "Yes", "No", 0) ) {
- case 0: .. // Yes
- case 1: .. // No (default)
- }
- \endcode
-
- One choice example:
- \image html fl_choice_one.png
- \image latex fl_choice_one.png "fl_choice() one choice" width=4cm
- \code
- fl_choice("All hope is lost.", "OK", 0, 0); // "OK" default
- \endcode
+ This dialog features up to 3 customizable choice buttons
+ which are specified in order of *right-to-left* in the dialog, e.g.
+ \image html fl_choice_left_middle_right.png
+ \image latex fl_choice_left_middle_right.png "fl_choice() button ordering" width=4cm
+
+ \code #include <FL/fl_ask.H> \endcode
+
+ Three choices with printf() style formatting:
+ \image html fl_choice_three_fmt.png
+ \image latex fl_choice_three_fmt.png "fl_choice() three choices with printf formatting" width=4cm
+ \code
+ int num_msgs = GetNumberOfMessages();
+ switch ( fl_choice("What to do with %d messages?", "Send", "Save", "Delete", num_msgs) ) {
+ case 0: .. // Send
+ case 1: .. // Save (default)
+ case 2: .. // Delete
+ ..
+ }
+ \endcode
+
+ Three choice example:
+ \image html fl_choice_three.png
+ \image latex fl_choice_three.png "fl_choice() three choices" width=4cm
+ \code
+ switch ( fl_choice("How many bedrooms?", "Zero", "One", "Two") ) {
+ case 0: .. // "Zero"
+ case 1: .. // "One" (default)
+ case 2: .. // "Two"
+ }
+ \endcode
+
+ Two choice example:
+ \image html fl_choice_two.png
+ \image latex fl_choice_two.png "fl_choice() two choices" width=4cm
+ \code
+ switch ( fl_choice("Empty trash?", "Yes", "No", 0) ) {
+ case 0: .. // Yes
+ case 1: .. // No (default)
+ }
+ \endcode
+
+ One choice example:
+ \image html fl_choice_one.png
+ \image latex fl_choice_one.png "fl_choice() one choice" width=4cm
+ \code
+ fl_choice("All hope is lost.", "OK", 0, 0); // "OK" default
+ \endcode
+
+ \param[in] fmt can be used as an sprintf-like format and variables for the message text
+ \param[in] b0 text label for right button 0
+ \param[in] b1 text label for middle button 1 (can be 0)
+ \param[in] b2 text label for left button 2 (can be 0)
+ \retval 0 if the button with \p b0 text is pushed
+ \retval 1 if the button with \p b1 text is pushed
+ \retval 2 if the button with \p b2 text is pushed
+*/
+int fl_choice(const char *fmt, const char *b0, const char *b1, const char *b2, ...) {
- \param[in] fmt can be used as an sprintf-like format and variables for the message text
- \param[in] b0 text label for right button 0
- \param[in] b1 text label for middle button 1 (can be 0)
- \param[in] b2 text label for left button 2 (can be 0)
- \retval 0 if the button with \p b0 text is pushed or another dialog box is still open
- \retval 1 if the button with \p b1 text is pushed
- \retval 2 if the button with \p b2 text is pushed
- */
-int fl_choice(const char*fmt,const char *b0,const char *b1,const char *b2,...){
+ Fl_Message msg("?");
+ va_list ap;
+
+ // fl_beep(FL_BEEP_QUESTION);
+
+ va_start(ap, b2);
+ int r = msg.innards(fmt, ap, b0, b1, b2);
+ va_end(ap);
+ return r;
+}
+
+/** Shows a dialog displaying the printf style \p fmt message.
+
+ This function is like fl_choice() but returns \c -1 if the dialog window
+ was closed by pressing the \c Escape key or the window close button
+ rather than pushing one of the dialog buttons.
+
+ \see fl_choice()
+
+ \param[in] fmt can be used as an sprintf-like format and variables for the message text
+ \param[in] b0 text label for right button 0
+ \param[in] b1 text label for middle button 1 (can be 0)
+ \param[in] b2 text label for left button 2 (can be 0)
- if (avoidRecursion) return 0;
+ \retval -3 reserved, FLTK 1.3 only: another dialog is still open (not possible in 1.4)
+ \retval -2 if the dialog was closed by pushing the window close button
+ \retval -1 if the dialog was closed by hitting Escape
+ \retval 0 if the button with \p b0 text is pushed
+ \retval 1 if the button with \p b1 text is pushed
+ \retval 2 if the button with \p b2 text is pushed
+*/
+int fl_choice_n(const char *fmt, const char *b0, const char *b1, const char *b2, ...) {
+ Fl_Message msg("?");
va_list ap;
// fl_beep(FL_BEEP_QUESTION);
va_start(ap, b2);
- int r = innards(fmt, ap, b0, b1, b2);
+ int r = msg.innards(fmt, ap, b0, b1, b2);
va_end(ap);
+ if (msg.window_closed() != 0)
+ return msg.window_closed();
return r;
}
-/** Gets the Fl_Box icon container of the current default dialog used in
- many common dialogs like fl_message(), fl_alert(),
- fl_ask(), fl_choice(), fl_input(), fl_password()
- \note \#include <FL/fl_ask.H>
+
+/**
+ Gets the Fl_Box icon container of the current default dialog used in
+ many common dialogs like fl_message(), fl_alert(),
+ fl_ask(), fl_choice(), fl_input(), fl_password().
+
+ The return value cannot be Null. The object pointed to is an Fl_Box widget.
+ The returned pointer (Fl_Widget *) can be safely cast to an Fl_Box* pointer.
+
+ \code #include <FL/fl_ask.H> \endcode
*/
-Fl_Widget *fl_message_icon() {makeform(); return icon;}
-
-static const char* input_innards(const char* fmt, va_list ap,
- const char* defstr, uchar type) {
- makeform();
- message_form->size(410,103);
- message->position(60,10);
- input->type(type);
- input->show();
- input->value(defstr);
- input->take_focus();
-
- int r = innards(fmt, ap, fl_cancel, fl_ok, 0);
- input->hide();
- message->position(60,25);
- return r ? input->value() : 0;
+Fl_Widget *fl_message_icon() {
+ return Fl_Message::message_icon();
}
-/** Shows an input dialog displaying the \p fmt message
+/** Shows an input dialog displaying the \p fmt message with variable arguments.
- \note Common dialog boxes are application modal. No more than one common dialog box
- can be open at any time. Requests for additional dialog boxes are ignored.
- \note \#include <FL/fl_ask.H>
+ This version of fl_input() is deprecated. The return value points
+ to an internal allocated string that may be changed later. You must
+ copy the string immediately after return from this method - at least
+ before the next call of the event loop.
- \param[in] fmt can be used as an sprintf-like format and variables for the message text
- \param[in] defstr defines the default returned string if no text is entered
- \return the user string input if OK was pushed, NULL if Cancel was pushed or another dialog box was still open
- */
-const char* fl_input(const char *fmt, const char *defstr, ...) {
+ \deprecated Please use
+ fl_input_str(int maxchar, const char *fmt, const char *defstr, ...) instead.
+
+ \code #include <FL/fl_ask.H> \endcode
- if (avoidRecursion) return 0;
+ \param[in] fmt can be used as an sprintf-like format and variables for the message text
+ \param[in] defstr defines the default returned string if no text is entered
+
+ \return the user string input if OK was pushed
+ \retval NULL if Cancel was pushed or the window was closed by the user
+*/
+const char *fl_input(const char *fmt, const char *defstr, ...) {
// fl_beep(FL_BEEP_QUESTION);
+ Fl_Message msg("?");
va_list ap;
va_start(ap, defstr);
- const char* r = input_innards(fmt, ap, defstr, FL_NORMAL_INPUT);
+ const char *r = msg.input_innards(fmt, ap, defstr, FL_NORMAL_INPUT, -1);
va_end(ap);
return r;
}
-/** Shows an input dialog displaying the \p fmt message.
+/** Shows an input dialog displaying the \p fmt message with variable arguments.
- Like fl_input() except the input text is not shown,
- '*' characters are displayed instead.
+ Like fl_input(), but this method has an additional (first) argument \p maxchar
+ that limits the number of \b characters that can be input. Since the
+ string is encoded in UTF-8 it is possible that the number of bytes
+ in the string is larger than \p maxchar.
- \note Common dialog boxes are application modal. No more than one common dialog box
- can be open at any time. Requests for additional dialog boxes are ignored.
- \note \#include <FL/fl_ask.H>
+ Other than the deprecated fl_input() method w/o the \p maxchar argument, this one
+ returns the string in an Fl_String object that must be released after use. This
+ can be a local/automatic variable.
- \param[in] fmt can be used as an sprintf-like format and variables for the message text
- \param[in] defstr defines the default returned string if no text is entered
- \return the user string input if OK was pushed, NULL if Cancel was pushed or aother dialog box was still open
- */
-const char *fl_password(const char *fmt, const char *defstr, ...) {
+ \code #include <FL/fl_ask.H> \endcode
+
+ Example:
+ \code
+ { Fl_String str = fl_input_str(0, "Enter text:", "");
+ printf("Text is: '%s'\n", str.value() ? str.value() : "<cancelled>");
+ } // (str goes out of scope)
+ \endcode
+
+ If the user hits \c Escape or closes the window \c str.value() returns NULL.
+
+ \param[in] maxchar input size limit in characters (not bytes), use 0 for no limit
+ \param[in] fmt can be used as an sprintf-like format and variables for the message text
+ \param[in] defstr defines the default returned string if no text is entered
+
+ \return the user string input if OK was pushed or NULL in Fl_String::value()
+ \retval Fl_String::value() == NULL if Cancel was pushed or the window was closed by the user
+
+ \since 1.4.0
+*/
+Fl_String fl_input_str(int maxchar, const char *fmt, const char *defstr, ...) {
+
+ // fl_beep(FL_BEEP_QUESTION);
+
+ Fl_Message msg("?");
+ if (maxchar < 0)
+ maxchar = 0;
+ va_list ap;
+ va_start(ap, defstr);
+ const char *r = msg.input_innards(fmt, ap, defstr, FL_NORMAL_INPUT, maxchar);
+ va_end(ap);
+ return r; // Fl_String(r)
+}
+
+/** Shows an input dialog displaying the \p fmt message with variable arguments.
+
+ Like fl_input() except the input text is not shown,
+ '*' or similar replacement characters are displayed instead.
- if (avoidRecursion) return 0;
+ \deprecated Please use
+ fl_password_str(int maxchar, const char *fmt, const char *defstr, ...) instead.
+
+ \code #include <FL/fl_ask.H> \endcode
+
+ \param[in] fmt can be used as an sprintf-like format and variables for the message text
+ \param[in] defstr defines the default returned string if no text is entered
+
+ \return the user string input if OK was pushed
+ \retval NULL if Cancel was pushed or the window was closed by the user
+*/
+const char *fl_password(const char *fmt, const char *defstr, ...) {
// fl_beep(FL_BEEP_PASSWORD);
+ Fl_Message msg("?");
va_list ap;
va_start(ap, defstr);
- const char* r = input_innards(fmt, ap, defstr, FL_SECRET_INPUT);
+ const char *r = msg.input_innards(fmt, ap, defstr, FL_SECRET_INPUT);
va_end(ap);
return r;
}
-/** Sets the preferred position for the common message box used in
- many common dialogs like fl_message(), fl_alert(),
- fl_ask(), fl_choice(), fl_input(), fl_password().
+/** Shows an input dialog displaying the \p fmt message with variable arguments.
+
+ Like fl_input_str() except the input text is not shown,
+ '*' or similar replacement characters are displayed instead.
+
+ Other than the deprecated fl_password() method w/o the \p maxchar argument, this
+ one returns the string in an Fl_String object that must be released after use.
+ This can be a local/automatic variable.
+
+ For an example see fl_input_str()
+
+ \code #include <FL/fl_ask.H> \endcode
+
+ \param[in] maxchar input size limit in characters (not bytes); use 0 for no limit
+ \param[in] fmt can be used as an sprintf-like format and variables for the message text
+ \param[in] defstr defines the default returned string if no text is entered
+
+ \return the user string input if OK was pushed or NULL in Fl_String::value()
+ \retval Fl_String::value() == NULL if Cancel was pushed or the window was closed by the user
+
+ \since 1.4.0
+*/
+Fl_String fl_password_str(int maxchar, const char *fmt, const char *defstr, ...) {
+
+ // fl_beep(FL_BEEP_PASSWORD);
+
+ Fl_Message msg("?");
+ if (maxchar < 0)
+ maxchar = 0;
+ va_list ap;
+ va_start(ap, defstr);
+ const char *r = msg.input_innards(fmt, ap, defstr, FL_SECRET_INPUT, maxchar);
+ va_end(ap);
+ return r; // Fl_String(r)
+}
+
+/** Sets the preferred position for the message box used in
+ many common dialogs like fl_message(), fl_alert(),
+ fl_ask(), fl_choice(), fl_input(), fl_password().
- Resets after every call to any of the common dialogs.
+ The position set with this method overrides the hotspot setting,
+ i.e. setting a position has higher priority than the hotspot mode
+ set by fl_message_hotspot(int).
- The position set with this method overrides the hotspot setting,
- i.e. setting a position has higher priority than the hotspot mode
- set by fl_message_hotspot(int).
+ The preferred position set by any of the fl_message_position() variants
+ affects only the next call of one of the common dialogs. The preferred
+ position is reset to 0 (unset) as soon as the dialog is shown.
- If the optional argument \p center is non-zero (true) the message box
- will be centered at the given coordinates rather than using the X/Y
- position as the window position (top left corner).
+ If the optional argument \p center is non-zero (true) the message box
+ will be centered at the given coordinates rather than using the X/Y
+ position as the window position (top left corner).
- \note \#include <FL/fl_ask.H>
+ \code #include <FL/fl_ask.H> \endcode
- \param[in] x Preferred X position
- \param[in] y Preferred Y position
- \param[in] center 1 = centered, 0 = absolute
+ \param[in] x Preferred X position
+ \param[in] y Preferred Y position
+ \param[in] center 1 = centered, 0 = absolute
- \see int fl_message_position(int *x, int *y)
+ \see int fl_message_position(int *x, int *y)
*/
void fl_message_position(const int x, const int y, const int center) {
- form_x = x;
- form_y = y;
- form_position = center ? 2 : 1;
+ Fl_Message::message_position(x, y, center);
}
-/** Sets the preferred position for the common message box used in
- many common dialogs like fl_message(), fl_alert(),
- fl_ask(), fl_choice(), fl_input(), fl_password().
+/** Sets the preferred position for the message box used in
+ many common dialogs like fl_message(), fl_alert(),
+ fl_ask(), fl_choice(), fl_input(), fl_password().
- The common message box will be centered over the given widget
- or window extensions.
+ The message box will be centered over the given widget
+ or window extensions.
- Everything else is like fl_message_position(int, int, int) with
- argument 'center' set to 1.
+ Everything else is like fl_message_position(int, int, int) with
+ argument 'center' set to 1.
- \note \#include <FL/fl_ask.H>
+ \code #include <FL/fl_ask.H> \endcode
- \param[in] widget Widget or window to position the message box over.
+ \param[in] widget Widget or window to position the message box over.
- \see int fl_message_position(int x, int y, int center)
+ \see int fl_message_position(int x, int y, int center)
*/
void fl_message_position(Fl_Widget *widget) {
- form_x = widget->x() + widget->w()/2;
- form_y = widget->y() + widget->h()/2;
- form_position = 2;
+ Fl_Message::message_position(widget);
}
-/** Gets the preferred position for the common message box used in
- many common dialogs like fl_message(), fl_alert(),
- fl_ask(), fl_choice(), fl_input(), fl_password().
+/** Gets the preferred position for the message box used in
+ many common dialogs like fl_message(), fl_alert(),
+ fl_ask(), fl_choice(), fl_input(), fl_password().
+
+ \code #include <FL/fl_ask.H> \endcode
- \note \#include <FL/fl_ask.H>
+ The position set with this method overrides the hotspot setting,
+ i.e. setting a position has higher priority than the hotspot mode
+ set by fl_message_hotspot(int).
- \param[out] x Preferred X position, returns -1 if not set
- \param[out] y Preferred Y position, returns -1 if not set
+ The preferred position set by any of the fl_message_position() variants
+ affects only the next call of one of the common dialogs. The preferred
+ position is reset to 0 (unset) as soon as the dialog is shown.
- \returns whether position is currently set or not
- \retval 0 position is not set (may be hotspot or not)
- \retval 1 position is set (window position)
- \retval 2 position is set (message box centered)
+ \param[out] x Preferred X position, returns -1 if not set
+ \param[out] y Preferred Y position, returns -1 if not set
- \see fl_message_position(int, int)
- \see fl_message_hotspot(int)
- \see int fl_message_hotspot()
+ \returns whether position is currently set or not
+ \retval 0 position is not set (hotspot may be enabled or not)
+ \retval 1 position is set (window position)
+ \retval 2 position is set (message box centered)
+
+ \see fl_message_hotspot()
+ \see fl_message_hotspot(int)
+ \see fl_message_position(int, int)
+ \see fl_message_position(const int x, const int y, const int center)
+ \see fl_message_position(Fl_Widget *)
*/
int fl_message_position(int *x, int *y) {
- if (x)
- *x = form_position ? form_x : -1;
- if (y)
- *y = form_position ? form_y : -1;
- return form_position;
+ return Fl_Message::message_position(x, y);
}
-/** Sets whether or not to move the common message box used in
- many common dialogs like fl_message(), fl_alert(),
- fl_ask(), fl_choice(), fl_input(), fl_password() to follow
- the mouse pointer.
-
- The default is \e enabled, so that the default button is the
- hotspot and appears at the mouse position.
- \note \#include <FL/fl_ask.H>
- \param[in] enable non-zero enables hotspot behavior,
- 0 disables hotspot
- */
+/** Sets whether or not to move the message box used in
+ many common dialogs like fl_message(), fl_alert(),
+ fl_ask(), fl_choice(), fl_input(), fl_password() to follow
+ the mouse pointer.
+
+ The default is \e enabled, so that the default button is the
+ hotspot and appears at the mouse position.
+
+ \code #include <FL/fl_ask.H> \endcode
+
+ \param[in] enable non-zero enables hotspot behavior,
+ 0 disables hotspot
+*/
void fl_message_hotspot(int enable) {
- enableHotspot = enable ? 1 : 0;
+ Fl_Message::message_hotspot(enable);
}
-/** Gets whether or not to move the common message box used in
- many common dialogs like fl_message(), fl_alert(),
- fl_ask(), fl_choice(), fl_input(), fl_password() to follow
- the mouse pointer.
- \note \#include <FL/fl_ask.H>
- \return 0 if disable, non-zero otherwise
- \see fl_message_hotspot(int)
- */
-int fl_message_hotspot(void) {
- return enableHotspot;
+/** Gets whether or not to move the message box used in
+ many common dialogs like fl_message(), fl_alert(),
+ fl_ask(), fl_choice(), fl_input(), fl_password() to follow
+ the mouse pointer.
+
+ This is a permanent setting. It remains active and affects the window
+ position unless overridden by an explicit positioning request by means
+ of one of the fl_message_position() variants.
+
+ \code #include <FL/fl_ask.H> \endcode
+
+ \return 0 if disabled, non-zero otherwise
+
+ \see void fl_message_hotspot(int)
+ \see int fl_message_position(int *x, int *y)
+ \see void fl_message_position(Fl_Widget *)
+ \see fl_message_position()
+*/
+int fl_message_hotspot() {
+ return Fl_Message::message_hotspot();
}
/** Sets the title of the dialog window used in many common dialogs.
- This window \p title will be used in the next call of one of the
- common dialogs like fl_message(), fl_alert(), fl_ask(), fl_choice(),
- fl_input(), fl_password().
+ This window \p title will be used in the next call of one of the
+ common dialogs like fl_message(), fl_alert(), fl_ask(), fl_choice(),
+ fl_input(), fl_password().
- The \p title string is copied internally, so that you can use a
- local variable or free the string immediately after this call. It
- applies only to the \b next call of one of the common dialogs and
- will be reset to an empty title (the default for all dialogs) after
- that call.
+ The \p title string is copied internally, so that you can use a
+ local variable or free the string immediately after this call. It
+ applies only to the \b next call of one of the common dialogs and
+ will be reset to an empty title (the default for all dialogs) after
+ that call.
- \note \#include <FL/fl_ask.H>
- \param[in] title window label, string copied internally
+ \code #include <FL/fl_ask.H> \endcode
+ \param[in] title window label, string copied internally
*/
void fl_message_title(const char *title) {
- makeform();
- message_form->copy_label(title);
+ Fl_Message::message_title(title);
}
/** Sets the default title of the dialog window used in many common dialogs.
- This window \p title will be used in all subsequent calls of one of the
- common dialogs like fl_message(), fl_alert(), fl_ask(), fl_choice(),
- fl_input(), fl_password(), unless a specific title has been set
- with fl_message_title(const char *title).
+ This window \p title will be used in all subsequent calls of one of the
+ common dialogs like fl_message(), fl_alert(), fl_ask(), fl_choice(),
+ fl_input(), fl_password(), unless a specific title has been set
+ with fl_message_title(const char *title).
- The default is no title. You can override the default title for a
- single dialog with fl_message_title(const char *title).
+ The default is no title. You can override the default title for a
+ single dialog with fl_message_title(const char *title).
- The \p title string is copied internally, so that you can use a
- local variable or free the string immediately after this call.
+ The \p title string is copied internally, so that you can use a
+ local variable or free the string immediately after this call.
- \note \#include <FL/fl_ask.H>
- \param[in] title default window label, string copied internally
+ \code #include <FL/fl_ask.H> \endcode
+
+ \param[in] title default window label, string copied internally
*/
void fl_message_title_default(const char *title) {
- if (message_title_default) {
- free ((void *)message_title_default);
- message_title_default = 0;
- }
- if (title)
- message_title_default = fl_strdup(title);
+ Fl_Message::message_title_default(title);
}
/** @} */