|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: fl_ask.cxx 8136 2010-12-29 11:51:29Z manolo $" 00003 // 00004 // Standard dialog functions for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 // Implementation of fl_message, fl_ask, fl_choice, fl_input 00029 // The three-message fl_show_x functions are for forms compatibility 00030 // mostly. In most cases it is easier to get a multi-line message 00031 // by putting newlines in the message. 00032 00033 #include <stdio.h> 00034 #include <stdarg.h> 00035 #include "flstring.h" 00036 00037 #include <FL/Fl.H> 00038 00039 #include <FL/fl_ask.H> 00040 00041 #include <FL/Fl_Box.H> 00042 #include <FL/Fl_Button.H> 00043 #include <FL/Fl_Return_Button.H> 00044 #include <FL/Fl_Window.H> 00045 #include <FL/Fl_Input.H> 00046 #include <FL/Fl_Secret_Input.H> 00047 #include <FL/x.H> 00048 #include <FL/fl_draw.H> 00049 00050 static Fl_Window *message_form; 00051 static Fl_Box *message; 00052 static Fl_Box *icon; 00053 static Fl_Button *button[3]; 00054 static Fl_Input *input; 00055 static int ret_val; 00056 static const char *iconlabel = "?"; 00057 Fl_Font fl_message_font_ = FL_HELVETICA; 00058 Fl_Fontsize fl_message_size_ = 14; 00059 #ifdef __APPLE__ 00060 extern "C" void NSBeep(void); 00061 #endif 00062 00063 static char avoidRecursion = 0; 00064 00065 // Sets the global return value (ret_val) and closes the window. 00066 // Note: this is used for the button callbacks and the window 00067 // callback (closing the window with the close button or menu). 00068 // The first argument (Fl_Widget *) can either be an Fl_Button* 00069 // pointer to one of the buttons or an Fl_Window* pointer to the 00070 // message window (message_form). 00071 static void button_cb(Fl_Widget *, void *val) { 00072 ret_val = (fl_intptr_t)val; 00073 message_form->hide(); 00074 } 00075 00076 static Fl_Window *makeform() { 00077 if (message_form) { 00078 message_form->size(410,103); 00079 return message_form; 00080 } 00081 // make sure that the dialog does not become the child of some 00082 // current group 00083 Fl_Group *previously_current_group = Fl_Group::current(); 00084 Fl_Group::current(0); 00085 // create a new top level window 00086 Fl_Window *w = message_form = new Fl_Window(410,103,""); 00087 message_form->callback(button_cb,(void *)0); 00088 // w->clear_border(); 00089 // w->box(FL_UP_BOX); 00090 (message = new Fl_Box(60, 25, 340, 20)) 00091 ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP); 00092 (input = new Fl_Input(60, 37, 340, 23))->hide(); 00093 {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50); 00094 o->box(FL_THIN_UP_BOX); 00095 o->labelfont(FL_TIMES_BOLD); 00096 o->labelsize(34); 00097 o->color(FL_WHITE); 00098 o->labelcolor(FL_BLUE); 00099 } 00100 // create the buttons (right to left) 00101 for (int b=0, x=310; b<3; b++, x -= 100) { 00102 if (b==1) 00103 button[b] = new Fl_Return_Button(x, 70, 90, 23); 00104 else 00105 button[b] = new Fl_Button(x, 70, 90, 23); 00106 button[b]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); 00107 button[b]->callback(button_cb,(void *)b); 00108 } 00109 button[0]->shortcut(FL_Escape); 00110 w->resizable(new Fl_Box(60,10,110-60,27)); 00111 w->end(); 00112 w->set_modal(); 00113 Fl_Group::current(previously_current_group); 00114 return w; 00115 } 00116 00117 /* 00118 * 'resizeform()' - Resize the form and widgets so that they hold everything 00119 * that is asked of them... 00120 */ 00121 00122 void resizeform() { 00123 int i; 00124 int message_w, message_h; 00125 int text_height; 00126 int button_w[3], button_h[3]; 00127 int x, w, h, max_w, max_h; 00128 const int icon_size = 50; 00129 00130 fl_font(fl_message_font_, fl_message_size_); 00131 message_w = message_h = 0; 00132 fl_measure(message->label(), message_w, message_h); 00133 00134 message_w += 10; 00135 message_h += 10; 00136 if (message_w < 340) 00137 message_w = 340; 00138 if (message_h < 30) 00139 message_h = 30; 00140 00141 fl_font(button[0]->labelfont(), button[0]->labelsize()); 00142 00143 memset(button_w, 0, sizeof(button_w)); 00144 memset(button_h, 0, sizeof(button_h)); 00145 00146 for (max_h = 25, i = 0; i < 3; i ++) 00147 if (button[i]->visible()) 00148 { 00149 fl_measure(button[i]->label(), button_w[i], button_h[i]); 00150 00151 if (i == 1) 00152 button_w[1] += 20; 00153 00154 button_w[i] += 30; 00155 button_h[i] += 10; 00156 00157 if (button_h[i] > max_h) 00158 max_h = button_h[i]; 00159 } 00160 00161 if (input->visible()) text_height = message_h + 25; 00162 else text_height = message_h; 00163 00164 max_w = message_w + 10 + icon_size; 00165 w = button_w[0] + button_w[1] + button_w[2] - 10; 00166 00167 if (w > max_w) 00168 max_w = w; 00169 00170 message_w = max_w - 10 - icon_size; 00171 00172 w = max_w + 20; 00173 h = max_h + 30 + text_height; 00174 00175 message_form->size(w, h); 00176 message_form->size_range(w, h, w, h); 00177 00178 message->resize(20 + icon_size, 10, message_w, message_h); 00179 icon->resize(10, 10, icon_size, icon_size); 00180 icon->labelsize(icon_size - 10); 00181 input->resize(20 + icon_size, 10 + message_h, message_w, 25); 00182 00183 for (x = w, i = 0; i < 3; i ++) 00184 if (button_w[i]) 00185 { 00186 x -= button_w[i]; 00187 button[i]->resize(x, h - 10 - max_h, button_w[i] - 10, max_h); 00188 00189 // printf("button %d (%s) is %dx%d+%d,%d\n", i, button[i]->label(), 00190 // button[i]->w(), button[i]->h(), 00191 // button[i]->x(), button[i]->y()); 00192 } 00193 } 00194 00195 static int innards(const char* fmt, va_list ap, 00196 const char *b0, 00197 const char *b1, 00198 const char *b2) 00199 { 00200 Fl::pushed(0); // stop dragging (STR #2159) 00201 00202 avoidRecursion = 1; 00203 00204 makeform(); 00205 char buffer[1024]; 00206 if (!strcmp(fmt,"%s")) { 00207 message->label(va_arg(ap, const char*)); 00208 } else { 00209 ::vsnprintf(buffer, 1024, fmt, ap); 00210 message->label(buffer); 00211 } 00212 00213 message->labelfont(fl_message_font_); 00214 message->labelsize(fl_message_size_); 00215 if (b0) {button[0]->show(); button[0]->label(b0); button[1]->position(210,70);} 00216 else {button[0]->hide(); button[1]->position(310,70);} 00217 if (b1) {button[1]->show(); button[1]->label(b1);} 00218 else button[1]->hide(); 00219 if (b2) {button[2]->show(); button[2]->label(b2);} 00220 else button[2]->hide(); 00221 const char* prev_icon_label = icon->label(); 00222 if (!prev_icon_label) icon->label(iconlabel); 00223 00224 resizeform(); 00225 00226 if (button[1]->visible() && !input->visible()) 00227 button[1]->take_focus(); 00228 message_form->hotspot(button[0]); 00229 if (b0 && Fl_Widget::label_shortcut(b0)) 00230 button[0]->shortcut(0); 00231 else 00232 button[0]->shortcut(FL_Escape); 00233 00234 // deactivate Fl::grab(), because it is incompatible with modal windows 00235 Fl_Window* g = Fl::grab(); 00236 if (g) Fl::grab(0); 00237 message_form->show(); 00238 while (message_form->shown()) Fl::wait(); 00239 if (g) // regrab the previous popup menu, if there was one 00240 Fl::grab(g); 00241 icon->label(prev_icon_label); 00242 00243 avoidRecursion = 0; 00244 return ret_val; 00245 } 00246 00250 // pointers you can use to change FLTK to a foreign language: 00251 const char* fl_no = "No"; 00252 const char* fl_yes= "Yes"; 00253 const char* fl_ok = "OK"; 00254 const char* fl_cancel= "Cancel"; 00255 const char* fl_close= "Close"; 00256 00257 // fltk functions: 00262 void fl_beep(int type) { 00263 #ifdef WIN32 00264 switch (type) { 00265 case FL_BEEP_QUESTION : 00266 case FL_BEEP_PASSWORD : 00267 MessageBeep(MB_ICONQUESTION); 00268 break; 00269 case FL_BEEP_MESSAGE : 00270 MessageBeep(MB_ICONASTERISK); 00271 break; 00272 case FL_BEEP_NOTIFICATION : 00273 MessageBeep(MB_ICONASTERISK); 00274 break; 00275 case FL_BEEP_ERROR : 00276 MessageBeep(MB_ICONERROR); 00277 break; 00278 default : 00279 MessageBeep(0xFFFFFFFF); 00280 break; 00281 } 00282 #elif defined(__APPLE__) 00283 switch (type) { 00284 case FL_BEEP_DEFAULT : 00285 case FL_BEEP_ERROR : 00286 NSBeep(); 00287 break; 00288 default : 00289 break; 00290 } 00291 #else 00292 switch (type) { 00293 case FL_BEEP_DEFAULT : 00294 case FL_BEEP_ERROR : 00295 if (!fl_display) fl_open_display(); 00296 00297 XBell(fl_display, 100); 00298 break; 00299 default : 00300 if (!fl_display) fl_open_display(); 00301 00302 XBell(fl_display, 50); 00303 break; 00304 } 00305 #endif // WIN32 00306 } 00307 00317 void fl_message(const char *fmt, ...) { 00318 00319 if (avoidRecursion) return; 00320 00321 va_list ap; 00322 00323 fl_beep(FL_BEEP_MESSAGE); 00324 00325 va_start(ap, fmt); 00326 iconlabel = "i"; 00327 innards(fmt, ap, 0, fl_close, 0); 00328 va_end(ap); 00329 iconlabel = "?"; 00330 } 00331 00340 void fl_alert(const char *fmt, ...) { 00341 00342 if (avoidRecursion) return; 00343 00344 va_list ap; 00345 00346 fl_beep(FL_BEEP_ERROR); 00347 00348 va_start(ap, fmt); 00349 iconlabel = "!"; 00350 innards(fmt, ap, 0, fl_close, 0); 00351 va_end(ap); 00352 iconlabel = "?"; 00353 } 00365 int fl_ask(const char *fmt, ...) { 00366 00367 if (avoidRecursion) return 0; 00368 00369 va_list ap; 00370 00371 fl_beep(FL_BEEP_QUESTION); 00372 00373 va_start(ap, fmt); 00374 int r = innards(fmt, ap, fl_no, fl_yes, 0); 00375 va_end(ap); 00376 00377 return r; 00378 } 00379 00395 int fl_choice(const char*fmt,const char *b0,const char *b1,const char *b2,...){ 00396 00397 if (avoidRecursion) return 0; 00398 00399 va_list ap; 00400 00401 fl_beep(FL_BEEP_QUESTION); 00402 00403 va_start(ap, b2); 00404 int r = innards(fmt, ap, b0, b1, b2); 00405 va_end(ap); 00406 return r; 00407 } 00413 Fl_Widget *fl_message_icon() {makeform(); return icon;} 00414 00415 static const char* input_innards(const char* fmt, va_list ap, 00416 const char* defstr, uchar type) { 00417 makeform(); 00418 message->position(60,10); 00419 input->type(type); 00420 input->show(); 00421 input->value(defstr); 00422 input->take_focus(); 00423 00424 int r = innards(fmt, ap, fl_cancel, fl_ok, 0); 00425 input->hide(); 00426 message->position(60,25); 00427 return r ? input->value() : 0; 00428 } 00429 00440 const char* fl_input(const char *fmt, const char *defstr, ...) { 00441 00442 if (avoidRecursion) return 0; 00443 00444 fl_beep(FL_BEEP_QUESTION); 00445 00446 va_list ap; 00447 va_start(ap, defstr); 00448 const char* r = input_innards(fmt, ap, defstr, FL_NORMAL_INPUT); 00449 va_end(ap); 00450 return r; 00451 } 00452 00466 const char *fl_password(const char *fmt, const char *defstr, ...) { 00467 00468 if (avoidRecursion) return 0; 00469 00470 fl_beep(FL_BEEP_PASSWORD); 00471 00472 va_list ap; 00473 va_start(ap, defstr); 00474 const char* r = input_innards(fmt, ap, defstr, FL_SECRET_INPUT); 00475 va_end(ap); 00476 return r; 00477 } 00478 00481 // 00482 // End of "$Id: fl_ask.cxx 8136 2010-12-29 11:51:29Z manolo $". 00483 //