diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/Fl_File_Chooser2.cxx | 7 | ||||
| -rw-r--r-- | src/Fl_Message.cxx | 532 | ||||
| -rw-r--r-- | src/Fl_Message.h | 160 | ||||
| -rw-r--r-- | src/Makefile | 1 | ||||
| -rw-r--r-- | src/fl_ask.cxx | 888 | ||||
| -rw-r--r-- | src/makedepend | 60 |
7 files changed, 1138 insertions, 511 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa74b6c7d..19168612e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,6 +56,7 @@ set (CPPFILES Fl_Menu_Window.cxx Fl_Menu_add.cxx Fl_Menu_global.cxx + Fl_Message.cxx Fl_Multi_Label.cxx Fl_Native_File_Chooser.cxx Fl_Overlay_Window.cxx diff --git a/src/Fl_File_Chooser2.cxx b/src/Fl_File_Chooser2.cxx index 736a2f95c..363adf721 100644 --- a/src/Fl_File_Chooser2.cxx +++ b/src/Fl_File_Chooser2.cxx @@ -21,8 +21,11 @@ // *** BEGIN OUT OF SOURCE DOCUMENTATION *** -/** \defgroup group_comdlg Common Dialogs classes and functions - @{ +/** \defgroup group_comdlg Common Dialog Classes and Functions + + \brief Common dialog functions for file selection, message output, and more. + + @{ */ /** \class Fl_File_Chooser The Fl_File_Chooser widget displays a standard file selection diff --git a/src/Fl_Message.cxx b/src/Fl_Message.cxx new file mode 100644 index 000000000..1b93ecad3 --- /dev/null +++ b/src/Fl_Message.cxx @@ -0,0 +1,532 @@ +// +// Common dialog implementation for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2021 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +/** + \cond DriverDev + \addtogroup DriverDeveloper + \{ +*/ + +/** + \file Fl_Message.cxx - Base class for common dialogs. + + This is the base class for all common FLTK dialog windows used in + fl_message(), fl_ask(), fl_choice(), fl_input(), and fl_password(). + + \note <b>Internal use only. This class may be changed as required + without notice.</b>\n + This class is reserved for FLTK's internal usage in common dialogs + in FLTK 1.4.x and later. The header file is "hidden" in the src/ + folder and not installed with the public header files. + + \since 1.4.0 + + All common dialogs can be altered by changing the contents of some + static class variables. This is done by accessor methods like + fl_message_title() and others defined in FL/fl_ask.H. This is for + backwards compatibility with FLTK 1.3.x and earlier. + + \note The documentation is only visible if the CMake option + \c 'OPTION_INCLUDE_DRIVER_DOCUMENTATION' is enabled. +*/ + +#include <FL/Fl.H> +#include "flstring.h" +#include <FL/fl_ask.H> +#include "Fl_Message.h" // intentionally "hidden" in src/... + +#include <FL/Fl_Window.H> +#include <FL/Fl_Box.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Return_Button.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Secret_Input.H> +#include <FL/fl_draw.H> + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> + +// Fl_Message static variables + +const char *Fl_Message::message_title_default_; +const char *Fl_Message::message_title_; + +Fl_Box *Fl_Message::message_icon_; + +char *Fl_Message::input_buffer_; +int Fl_Message::input_size_; + +int Fl_Message::enable_hotspot_ = 1; +int Fl_Message::form_x_ = 0; +int Fl_Message::form_y_ = 0; +int Fl_Message::form_position_ = 0; // 0 = not set, 1 = absolute, 2 = centered + +/** + Fl_Message's internal button callback. + + This callback function is used when the user pushes a button, presses the + \c Return key, or uses a valid shortcut for one of the buttons. + + The internal return value \p retval_ is set according to the button that + was invoked (0, 1, 2) and \p window_closed_ is set to 0 (dialog closed + by dialog button). Then the dialog window is closed (hidden). +*/ + +void Fl_Message::button_cb_(Fl_Widget *w, void *d) { + Fl_Window *window = w->window(); + Fl_Message *dialog = (Fl_Message *)window->user_data(); + dialog->window_closed_ = 0; + dialog->retval_ = fl_int(d); // button + window->hide(); +} // button_cb_() + +/** + Fl_Message's internal window callback. + + This callback function is used internally when the dialog window is closed + by the user with the window close button or by pressing \c Escape. + + The internal return value \p retval_ is set to 0 (i.e. button 0) and + \p window_closed_ is set to -1 (Escape) or -2 (window close button). + Then the dialog window is closed (hidden). +*/ + +void Fl_Message::window_cb_(Fl_Widget *w, void *d) { + Fl_Window *window = (Fl_Window *)w; + Fl_Message *dialog = (Fl_Message *)window->user_data(); + if ((Fl::event() == FL_KEYBOARD || Fl::event() == FL_SHORTCUT) && + (Fl::event_key() == FL_Escape)) + dialog->window_closed_ = -1; + else + dialog->window_closed_ = -2; + dialog->retval_ = 0; // either window or button 0 + window->hide(); +} // window_cb_() + +/** + Fl_Message constructor. + + The constructor creates a default message window and sets the icon type + to the given \p iconlabel which can be any character (or string). + + Message text box (Fl_Box), icon (Fl_Box), and an input (Fl_Input) widgets + are created and initialized. Three buttons are created and arranged right to + left in the message window. The second (middle) button is an Fl_Return_Button. + + The message window is set to modal() +*/ +Fl_Message::Fl_Message(const char *iconlabel) + : window_(0) + , retval_(0) + , window_closed_(0) { + + // Make sure that the dialog does not become the child of some current group. + + Fl_Group *previous_group = Fl_Group::current(); + if (previous_group) + Fl_Group::current(0); + + // create widgets + + window_ = new Fl_Window(400, 150, NULL); + message_ = new Fl_Box(60, 25, 340, 20); + message_->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_WRAP); + + input_ = new Fl_Input(60, 37, 340, 23); + input_->hide(); + + Fl_Box *icon_template = message_icon(); // use template for icon box + + icon_ = new Fl_Box(10, 10, 50, 50); + icon_->box(icon_template->box()); + icon_->labelfont(icon_template->labelfont()); + icon_->labelsize(icon_template->labelsize()); + icon_->color(icon_template->color()); + icon_->labelcolor(icon_template->labelcolor()); + icon_->label(iconlabel); + + window_->end(); // don't add the buttons automatically + + // create the buttons (positions: right to left) + // button 1 is a return button + + 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_, fl_voidptr(b)); + } + + // add the buttons left to right for tab navigation + + for (int b = 2; b >= 0; b--) { + window_->add(button_[b]); + } + + window_->begin(); + window_->resizable(new Fl_Box(60, 10, 110 - 60, 27)); + window_->end(); + window_->callback(window_cb_, this); + window_->set_modal(); + + // restore previous group + Fl_Group::current(previous_group); +} + +/** + Resizes the form and widgets so that they hold everything + that is asked of them. +*/ +void Fl_Message::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; + + 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; // account for return button arrow + + 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; + + if (w > max_w) + max_w = w; + + message_w = max_w - 10 - icon_size; + + w = max_w + 20; + h = max_h + 30 + text_height; + + window_->size(w, h); + window_->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); + input_->resize(20 + icon_size, 10 + message_h, message_w, 25); + + 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); + } + } +} + +/** + Does all Fl_Message window internals for messages with and w/o an input field. + + This method finalizes the layout of the message window, arranges (shows or hides) + the buttons and the optional text input widget, sets the message window title, + pops up the window, and waits for user input. + + The message window is positioned according to the positioning options set before + calling the message function. + + The private variables \p retval_ and \p window_closed_ are set depending + on the user action (pushing a button or closing the window). + + \note The above mentioned variables must be evaluated before the event + loop is called because they might be overwritten by another dialog. + It is safe to evaluate the variables before the message function returns. + + \param[in] fmt printf style format used in the user function call + \param[in] ap argument list provided by the user function call + \param[in] b0 text of button 0 (right: usually the "cancel" button) + \param[in] b1 text of button 1 (middle) + \param[in] b2 text of button 2 (left) + + \returns return code + \retval 0 for Escape, window close, or button 0 + \retval 1 button 1 was pushed + \retval 2 button 2 was pushed +*/ + +int Fl_Message::innards(const char *fmt, va_list ap, const char *b0, const char *b1, const char *b2) { + Fl::pushed(0); // stop dragging (STR #2159) + + char buffer[1024]; + if (!strcmp(fmt, "%s")) { + message_->label(va_arg(ap, const char *)); + } else { + ::vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap); + message_->label(buffer); + } + + 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(); + + resizeform(); + + if (button_[1]->visible() && !input_->visible()) + button_[1]->take_focus(); + + if (form_position_) { + if (form_position_ == 2) { // centered + form_x_ -= window_->w() / 2; + form_y_ -= window_->h() / 2; + } + window_->position(form_x_, form_y_); + form_x_ = form_y_ = form_position_ = 0; + } else if (enable_hotspot_) + window_->hotspot(button_[0]); + else + window_->free_position(); + + if (b0 && Fl_Widget::label_shortcut(b0)) + button_[0]->shortcut(0); + + // set the one-time window title, if defined and a specific title is not set + if (!window_->label() && message_title_) { + window_->copy_label(message_title_); + message_title(0); // reset global message title (compat.) + } + + // set default window title, if defined and a specific title is not set + if (!window_->label() && message_title_default_) + window_->copy_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 + window_->show(); + Fl_Group::current(current_group); + while (window_->shown()) + Fl::wait(); + if (g) // regrab the previous popup menu, if there was one + Fl::grab(g); + + return retval_; +} + +/** + Gets the default icon container (Fl_Box) used in common dialogs. + + Many common dialogs like fl_message(), fl_alert(), fl_ask(), + fl_choice(), fl_input(), and fl_password() display an icon. + + You can use this method to get the icon box (Fl_Box) and modify + the icon's box type, font, fontsize etc. + + \since FLTK 1.4.0 + + \note This method replaces the deprecated method fl_message_icon(). + Note that this new method correctly returns an Fl_Box * pointer, + whereas fl_message_icon() returns Fl_Widget *. + + The current icon default values are: + + - width and height: 50 (currently not changeable) + - box(FL_THIN_UP_BOX) + - labelfont(FL_TIMES_BOLD) + - labelsize(34) + - color(FL_WHITE) + - labelcolor(FL_BLUE) + + These values may be changed in a future FLTK version (although this + is not very likely to happen). + + If you change this then the changed values are used for subsequently + started common dialogs. This is intended to change the icon layout + for your application at startup time. It is not recommended to change + the default values for each message. +*/ +Fl_Box *Fl_Message::message_icon() { + + if (!Fl_Message::message_icon_) { // not yet initialized + + Fl_Group *current_group = Fl_Group::current(); + Fl_Group::current(0); + + Fl_Box *o = Fl_Message::message_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); + Fl_Group::current(current_group); + } + return Fl_Message::message_icon_; +} + +/** + Does all Fl_Message window internals for messages with a text input field. + + \see innards() +*/ +const char *Fl_Message::input_innards(const char *fmt, va_list ap, const char *defstr, uchar type, int maxchar) { + message_->position(60, 10); + input_->type(type); + input_->show(); + input_->value(defstr); + input_->take_focus(); + if (maxchar > 0) + input_->maximum_size(maxchar); + + int r = innards(fmt, ap, fl_cancel, fl_ok, 0); + + if (!r) + return 0; + + if (input_->value()) { + + int size = input_->size() + 1; + + if (maxchar < 0) { // need to store the value in pre-allocated buffer + + // The allocated input buffer starts with size 0 and is allocated + // in multiples of 128 bytes >= size. If both the size and the pointer + // are 0 (NULL) then realloc() allocates a /new/ buffer. + + if (size > input_size_) { + size += 127; + size &= ~127; + input_buffer_ = (char *)realloc(input_buffer_, size); + input_size_ = size; + } + + // Store the input. Note that value() can contain null bytes, + // so we use memcpy and add a terminating null byte as well. + + memcpy(input_buffer_, input_->value(), input_->size()); + input_buffer_[input_->size()] = '\0'; + return (input_buffer_); + + } else { // new version: allocate string buffer + + char *buf = (char *)malloc(size); + memcpy(buf, input_->value(), input_->size()); + buf[input_->size()] = '\0'; + return (buf); + } + + } else + return 0; +} + +/** 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(). + + 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. + + \param[in] title window label, string copied internally +*/ +void Fl_Message::message_title(const char *title) { + if (message_title_) { + free((void *)message_title_); + message_title_ = 0; + } + if (title) + message_title_ = strdup(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). + + 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. + + \param[in] title default window label, string copied internally +*/ +void Fl_Message::message_title_default(const char *title) { + if (message_title_default_) { + free((void *)message_title_default_); + message_title_default_ = 0; + } + if (title) + message_title_default_ = strdup(title); +} + +/** + \} + \endcond +*/ diff --git a/src/Fl_Message.h b/src/Fl_Message.h new file mode 100644 index 000000000..83dfad1df --- /dev/null +++ b/src/Fl_Message.h @@ -0,0 +1,160 @@ +// +// Common dialog header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2021 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +#ifndef _src_Fl_Message_h_ +#define _src_Fl_Message_h_ + +#include <FL/Fl_Window.H> +#include <FL/fl_ask.H> + +class Fl_Box; +class Fl_Button; +class Fl_Input; + +/** + \cond DriverDev + + \addtogroup DriverDeveloper + + \{ +*/ + +/** + This is the base class for all common FLTK dialog windows used in + fl_message(), fl_ask(), fl_choice(), fl_input(), and fl_password(). + + \note <b>Internal use only. This class may be changed as required + without notice.</b>\n + + This class is reserved for FLTK's internal usage in common dialogs + in FLTK 1.4.x and later. The header file is "hidden" in the src/ + folder and not installed with the public header files. + + This class uses some static variables used to let the user code change + the behavior and look of the \b next call of some of the message related + functions. This is necessary to support the existing fl_message() and + similar functions and is safe as long as the variables are reset before + the function pops up (shows) the message window and enters the internal + (i.e. nested) event loop. + + \since 1.4.0 +*/ + +/* Note: Do not FL_EXPORT this class, it's for internal use only */ + +class Fl_Message { + + // static variables and methods + +private: + static Fl_Box *message_icon_; // returned by Fl_Message::message_icon() + + static const char *message_title_; + static const char *message_title_default_; + + // Note: since Fl_Message objects are destroyed before fl_input() + // and fl_password() return their input text, we *need* to store + // the text in an internal (static) buffer. :-( + + // The newer functions fl_input_str() and fl_password_str() return the + // text in an Fl_String object that must be allocated and free()'d by + // the caller. + + static char *input_buffer_; // points to the allocated text buffer + static int input_size_; // size of allocated text buffer + + // the callback for all buttons: + static void button_cb_(Fl_Widget *w, void *d); + + // the window callback: + static void window_cb_(Fl_Widget *w, void *d); + + // resize to make text and buttons fit + void resizeform(); + +public: + static Fl_Box *message_icon(); + static void message_title(const char *title); + static void message_title_default(const char *title); + + /** Implements fl_message_position(const int, const int y, const int center). */ + static void message_position(const int x, const int y, const int center) { + form_x_ = x; + form_y_ = y; + form_position_ = center ? 2 : 1; + } + + /** Implements fl_message_position(Fl_Widget *widget). */ + static void message_position(Fl_Widget *widget) { + form_x_ = widget->x() + widget->w() / 2; + form_y_ = widget->y() + widget->h() / 2; + form_position_ = 2; + } + + /** Implements fl_message_position(int *x, int *y). */ + static int 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_; + } + + /** Implements void fl_message_hotspot(int). */ + static void message_hotspot(int enable) { enable_hotspot_ = enable ? 1 : 0; } + + /** Implements int fl_message_hotspot(). */ + static int message_hotspot() { return enable_hotspot_; } + + int window_closed() const { + return window_closed_; + } + + // member variables and methods + +private: + Fl_Window *window_; ///< message window + Fl_Box *message_; ///< message text + Fl_Box *icon_; ///< contains the icon + Fl_Button *button_[3]; ///< buttons used internally + Fl_Input *input_; ///< normal text or secret input + int retval_; ///< internally used to store the return value + int window_closed_; ///< window close flag (-1 = Escape, -2 = close button) + + // static (private) variables + + static int enable_hotspot_; ///< follow the mouse pointer (hotspot) + static int form_x_; ///< x position for next dialog + static int form_y_; ///< y position for next dialog + static int form_position_; ///< 0 = not set (may be hotspot), 1 = absolute, 2 = centered + +public: + // Constructor + Fl_Message(const char *iconlabel); + /** Destructor. */ + ~Fl_Message() { delete window_; } + + int innards(const char *fmt, va_list ap, const char *b0, const char *b1, const char *b2); + + const char *input_innards(const char *fmt, va_list ap, const char *defstr, uchar type, int maxchar = -1); +}; + +/** + \} + \endcond +*/ + +#endif // _src_Fl_Message_h_ diff --git a/src/Makefile b/src/Makefile index a31788929..2fe252ba8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -58,6 +58,7 @@ CPPFILES = \ Fl_Menu_Window.cxx \ Fl_Menu_add.cxx \ Fl_Menu_global.cxx \ + Fl_Message.cxx \ Fl_Multi_Label.cxx \ Fl_Native_File_Chooser.cxx \ Fl_Overlay_Window.cxx \ 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); } /** @} */ diff --git a/src/makedepend b/src/makedepend index 78310c64e..d719a269f 100644 --- a/src/makedepend +++ b/src/makedepend @@ -207,7 +207,7 @@ drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/Fl_Repeat_Button.H drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/Fl_Return_Button.H drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/Fl_Round_Button.H drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/Fl_Spinner.H -drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/fl_string.h +drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/Fl_String.H drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/fl_types.h drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/fl_utf8.h drivers/Posix/Fl_Posix_Printer_Driver.o: ../FL/Fl_Widget.H @@ -273,7 +273,7 @@ drivers/PostScript/Fl_PostScript.o: ../FL/Fl_Plugin.H drivers/PostScript/Fl_PostScript.o: ../FL/Fl_PostScript.H drivers/PostScript/Fl_PostScript.o: ../FL/Fl_Preferences.H drivers/PostScript/Fl_PostScript.o: ../FL/Fl_Return_Button.H -drivers/PostScript/Fl_PostScript.o: ../FL/fl_string.h +drivers/PostScript/Fl_PostScript.o: ../FL/Fl_String.H drivers/PostScript/Fl_PostScript.o: ../FL/Fl_Tile.H drivers/PostScript/Fl_PostScript.o: ../FL/fl_types.h drivers/PostScript/Fl_PostScript.o: ../FL/fl_utf8.h @@ -397,6 +397,7 @@ drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_RGB_Image.H drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_Scrollbar.H drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_Shared_Image.H drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_Slider.H +drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_String.H drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_Text_Buffer.H drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_Text_Display.H drivers/X11/Fl_X11_Screen_Driver.o: ../FL/Fl_Text_Editor.H @@ -463,6 +464,7 @@ drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_RGB_Image.H drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_Scrollbar.H drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_Single_Window.H drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_Slider.H +drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_String.H drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_Text_Buffer.H drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_Text_Display.H drivers/X11/Fl_X11_Window_Driver.o: ../FL/Fl_Text_Editor.H @@ -915,7 +917,6 @@ fl_ask.o: ../FL/fl_ask.H fl_ask.o: ../FL/fl_attr.h fl_ask.o: ../FL/Fl_Bitmap.H fl_ask.o: ../FL/Fl_Box.H -fl_ask.o: ../FL/Fl_Button.H fl_ask.o: ../FL/fl_casts.H fl_ask.o: ../FL/Fl_Device.H fl_ask.o: ../FL/fl_draw.H @@ -923,18 +924,15 @@ fl_ask.o: ../FL/Fl_Export.H fl_ask.o: ../FL/Fl_Graphics_Driver.H fl_ask.o: ../FL/Fl_Group.H fl_ask.o: ../FL/Fl_Image.H -fl_ask.o: ../FL/Fl_Input.H fl_ask.o: ../FL/Fl_Input_.H fl_ask.o: ../FL/Fl_Pixmap.H fl_ask.o: ../FL/Fl_Plugin.H fl_ask.o: ../FL/Fl_Preferences.H fl_ask.o: ../FL/Fl_Rect.H -fl_ask.o: ../FL/Fl_Return_Button.H fl_ask.o: ../FL/Fl_RGB_Image.H fl_ask.o: ../FL/Fl_Scrollbar.H -fl_ask.o: ../FL/Fl_Secret_Input.H fl_ask.o: ../FL/Fl_Slider.H -fl_ask.o: ../FL/fl_string.h +fl_ask.o: ../FL/Fl_String.H fl_ask.o: ../FL/Fl_Text_Buffer.H fl_ask.o: ../FL/Fl_Text_Display.H fl_ask.o: ../FL/Fl_Text_Editor.H @@ -943,9 +941,9 @@ fl_ask.o: ../FL/fl_utf8.h fl_ask.o: ../FL/Fl_Valuator.H fl_ask.o: ../FL/Fl_Widget.H fl_ask.o: ../FL/Fl_Window.H -fl_ask.o: ../FL/platform.H fl_ask.o: ../FL/platform_types.h fl_ask.o: flstring.h +fl_ask.o: Fl_Message.h fl_ask.o: Fl_Screen_Driver.H Fl_Bitmap.o: ../FL/abi-version.h Fl_Bitmap.o: ../FL/Enumerations.H @@ -1499,6 +1497,7 @@ Fl_File_Chooser.o: ../FL/Fl_Menu_Button.H Fl_File_Chooser.o: ../FL/Fl_Menu_Item.H Fl_File_Chooser.o: ../FL/Fl_Preferences.H Fl_File_Chooser.o: ../FL/Fl_Return_Button.H +Fl_File_Chooser.o: ../FL/Fl_String.H Fl_File_Chooser.o: ../FL/Fl_Tile.H Fl_File_Chooser.o: ../FL/fl_types.h Fl_File_Chooser.o: ../FL/fl_utf8.h @@ -1536,7 +1535,7 @@ Fl_File_Chooser2.o: ../FL/Fl_Menu_Item.H Fl_File_Chooser2.o: ../FL/Fl_Preferences.H Fl_File_Chooser2.o: ../FL/Fl_Return_Button.H Fl_File_Chooser2.o: ../FL/Fl_Shared_Image.H -Fl_File_Chooser2.o: ../FL/fl_string.h +Fl_File_Chooser2.o: ../FL/Fl_String.H Fl_File_Chooser2.o: ../FL/Fl_Tile.H Fl_File_Chooser2.o: ../FL/fl_types.h Fl_File_Chooser2.o: ../FL/fl_utf8.h @@ -1575,6 +1574,7 @@ fl_file_dir.o: ../FL/Fl_Menu_Button.H fl_file_dir.o: ../FL/Fl_Menu_Item.H fl_file_dir.o: ../FL/Fl_Preferences.H fl_file_dir.o: ../FL/Fl_Return_Button.H +fl_file_dir.o: ../FL/Fl_String.H fl_file_dir.o: ../FL/Fl_Tile.H fl_file_dir.o: ../FL/fl_types.h fl_file_dir.o: ../FL/fl_utf8.h @@ -1895,6 +1895,7 @@ Fl_Help_Dialog.o: ../FL/Fl_RGB_Image.H Fl_Help_Dialog.o: ../FL/Fl_Scrollbar.H Fl_Help_Dialog.o: ../FL/Fl_Shared_Image.H Fl_Help_Dialog.o: ../FL/Fl_Slider.H +Fl_Help_Dialog.o: ../FL/Fl_String.H Fl_Help_Dialog.o: ../FL/fl_types.h Fl_Help_Dialog.o: ../FL/fl_utf8.h Fl_Help_Dialog.o: ../FL/Fl_Valuator.H @@ -2020,6 +2021,7 @@ Fl_Input.o: ../FL/Fl_RGB_Image.H Fl_Input.o: ../FL/Fl_Scrollbar.H Fl_Input.o: ../FL/Fl_Secret_Input.H Fl_Input.o: ../FL/Fl_Slider.H +Fl_Input.o: ../FL/Fl_String.H Fl_Input.o: ../FL/Fl_Text_Buffer.H Fl_Input.o: ../FL/Fl_Text_Display.H Fl_Input.o: ../FL/Fl_Text_Editor.H @@ -2055,6 +2057,7 @@ Fl_Input_.o: ../FL/Fl_Rect.H Fl_Input_.o: ../FL/Fl_RGB_Image.H Fl_Input_.o: ../FL/Fl_Scrollbar.H Fl_Input_.o: ../FL/Fl_Slider.H +Fl_Input_.o: ../FL/Fl_String.H Fl_Input_.o: ../FL/Fl_Text_Buffer.H Fl_Input_.o: ../FL/Fl_Text_Display.H Fl_Input_.o: ../FL/Fl_Text_Editor.H @@ -2241,6 +2244,32 @@ Fl_Menu_Window.o: ../FL/Fl_Widget.H Fl_Menu_Window.o: ../FL/Fl_Window.H Fl_Menu_Window.o: ../FL/platform_types.h Fl_Menu_Window.o: Fl_Window_Driver.H +Fl_Message.o: ../config.h +Fl_Message.o: ../FL/abi-version.h +Fl_Message.o: ../FL/Enumerations.H +Fl_Message.o: ../FL/Fl.H +Fl_Message.o: ../FL/fl_ask.H +Fl_Message.o: ../FL/fl_attr.h +Fl_Message.o: ../FL/Fl_Bitmap.H +Fl_Message.o: ../FL/Fl_Box.H +Fl_Message.o: ../FL/Fl_Button.H +Fl_Message.o: ../FL/fl_casts.H +Fl_Message.o: ../FL/fl_draw.H +Fl_Message.o: ../FL/Fl_Export.H +Fl_Message.o: ../FL/Fl_Group.H +Fl_Message.o: ../FL/Fl_Image.H +Fl_Message.o: ../FL/Fl_Input.H +Fl_Message.o: ../FL/Fl_Input_.H +Fl_Message.o: ../FL/Fl_Return_Button.H +Fl_Message.o: ../FL/Fl_Secret_Input.H +Fl_Message.o: ../FL/Fl_String.H +Fl_Message.o: ../FL/fl_types.h +Fl_Message.o: ../FL/fl_utf8.h +Fl_Message.o: ../FL/Fl_Widget.H +Fl_Message.o: ../FL/Fl_Window.H +Fl_Message.o: ../FL/platform_types.h +Fl_Message.o: flstring.h +Fl_Message.o: Fl_Message.h Fl_Multi_Label.o: ../FL/abi-version.h Fl_Multi_Label.o: ../FL/Enumerations.H Fl_Multi_Label.o: ../FL/Fl.H @@ -2282,6 +2311,7 @@ Fl_Native_File_Chooser.o: ../FL/Fl_Menu_Item.H Fl_Native_File_Chooser.o: ../FL/Fl_Native_File_Chooser.H Fl_Native_File_Chooser.o: ../FL/Fl_Preferences.H Fl_Native_File_Chooser.o: ../FL/Fl_Return_Button.H +Fl_Native_File_Chooser.o: ../FL/Fl_String.H Fl_Native_File_Chooser.o: ../FL/Fl_Tile.H Fl_Native_File_Chooser.o: ../FL/fl_types.h Fl_Native_File_Chooser.o: ../FL/fl_utf8.h @@ -2317,6 +2347,7 @@ Fl_Native_File_Chooser_FLTK.o: ../FL/Fl_Menu_Item.H Fl_Native_File_Chooser_FLTK.o: ../FL/Fl_Native_File_Chooser.H Fl_Native_File_Chooser_FLTK.o: ../FL/Fl_Preferences.H Fl_Native_File_Chooser_FLTK.o: ../FL/Fl_Return_Button.H +Fl_Native_File_Chooser_FLTK.o: ../FL/Fl_String.H Fl_Native_File_Chooser_FLTK.o: ../FL/Fl_Tile.H Fl_Native_File_Chooser_FLTK.o: ../FL/fl_types.h Fl_Native_File_Chooser_FLTK.o: ../FL/fl_utf8.h @@ -2360,7 +2391,7 @@ Fl_Native_File_Chooser_GTK.o: ../FL/Fl_Plugin.H Fl_Native_File_Chooser_GTK.o: ../FL/Fl_Preferences.H Fl_Native_File_Chooser_GTK.o: ../FL/Fl_Return_Button.H Fl_Native_File_Chooser_GTK.o: ../FL/Fl_Shared_Image.H -Fl_Native_File_Chooser_GTK.o: ../FL/fl_string.h +Fl_Native_File_Chooser_GTK.o: ../FL/Fl_String.H Fl_Native_File_Chooser_GTK.o: ../FL/Fl_Tile.H Fl_Native_File_Chooser_GTK.o: ../FL/fl_types.h Fl_Native_File_Chooser_GTK.o: ../FL/fl_utf8.h @@ -2932,7 +2963,7 @@ fl_string.o: ../FL/Fl.H fl_string.o: ../FL/fl_casts.H fl_string.o: ../FL/Fl_Export.H fl_string.o: ../FL/Fl_Preferences.H -fl_string.o: ../FL/fl_string.h +Fl_String.o: ../FL/Fl_String.H fl_string.o: ../FL/fl_types.h fl_string.o: ../FL/fl_utf8.h fl_string.o: ../FL/platform_types.h @@ -3128,6 +3159,7 @@ Fl_Text_Editor.o: ../FL/Fl_Rect.H Fl_Text_Editor.o: ../FL/Fl_RGB_Image.H Fl_Text_Editor.o: ../FL/Fl_Scrollbar.H Fl_Text_Editor.o: ../FL/Fl_Slider.H +Fl_Text_Editor.o: ../FL/Fl_String.H Fl_Text_Editor.o: ../FL/Fl_Text_Buffer.H Fl_Text_Editor.o: ../FL/Fl_Text_Display.H Fl_Text_Editor.o: ../FL/Fl_Text_Editor.H @@ -3565,6 +3597,7 @@ Fl_x.o: ../FL/Fl_RGB_Image.H Fl_x.o: ../FL/Fl_Scrollbar.H Fl_x.o: ../FL/Fl_Shared_Image.H Fl_x.o: ../FL/Fl_Slider.H +Fl_x.o: ../FL/Fl_String.H Fl_x.o: ../FL/Fl_Text_Buffer.H Fl_x.o: ../FL/Fl_Text_Display.H Fl_x.o: ../FL/Fl_Text_Editor.H @@ -3661,6 +3694,7 @@ forms_bitmap.o: ../FL/Fl_RGB_Image.H forms_bitmap.o: ../FL/Fl_Round_Button.H forms_bitmap.o: ../FL/fl_show_colormap.H forms_bitmap.o: ../FL/Fl_Slider.H +forms_bitmap.o: ../FL/Fl_String.H forms_bitmap.o: ../FL/Fl_Tile.H forms_bitmap.o: ../FL/Fl_Timer.H forms_bitmap.o: ../FL/fl_types.h @@ -3719,6 +3753,7 @@ forms_compatibility.o: ../FL/Fl_RGB_Image.H forms_compatibility.o: ../FL/Fl_Round_Button.H forms_compatibility.o: ../FL/fl_show_colormap.H forms_compatibility.o: ../FL/Fl_Slider.H +forms_compatibility.o: ../FL/Fl_String.H forms_compatibility.o: ../FL/Fl_Tile.H forms_compatibility.o: ../FL/Fl_Timer.H forms_compatibility.o: ../FL/fl_types.h @@ -3787,6 +3822,7 @@ forms_fselect.o: ../FL/Fl_RGB_Image.H forms_fselect.o: ../FL/Fl_Round_Button.H forms_fselect.o: ../FL/fl_show_colormap.H forms_fselect.o: ../FL/Fl_Slider.H +forms_fselect.o: ../FL/Fl_String.H forms_fselect.o: ../FL/Fl_Tile.H forms_fselect.o: ../FL/Fl_Timer.H forms_fselect.o: ../FL/fl_types.h @@ -3845,6 +3881,7 @@ forms_pixmap.o: ../FL/Fl_RGB_Image.H forms_pixmap.o: ../FL/Fl_Round_Button.H forms_pixmap.o: ../FL/fl_show_colormap.H forms_pixmap.o: ../FL/Fl_Slider.H +forms_pixmap.o: ../FL/Fl_String.H forms_pixmap.o: ../FL/Fl_Tile.H forms_pixmap.o: ../FL/Fl_Timer.H forms_pixmap.o: ../FL/fl_types.h @@ -3902,6 +3939,7 @@ forms_timer.o: ../FL/Fl_RGB_Image.H forms_timer.o: ../FL/Fl_Round_Button.H forms_timer.o: ../FL/fl_show_colormap.H forms_timer.o: ../FL/Fl_Slider.H +forms_timer.o: ../FL/Fl_String.H forms_timer.o: ../FL/Fl_Tile.H forms_timer.o: ../FL/Fl_Timer.H forms_timer.o: ../FL/fl_types.h |
