|
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_Menu_Type.cxx 7903 2010-11-28 21:06:39Z matt $" 00003 // 00004 // Menu item code for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Menu items are kludged by making a phony Fl_Box widget so the normal 00007 // widget panel can be used to control them. 00008 // 00009 // This file also contains code to make Fl_Menu_Button, Fl_Menu_Bar, 00010 // etc widgets. 00011 // 00012 // Copyright 1998-2010 by Bill Spitzak and others. 00013 // 00014 // This library is free software; you can redistribute it and/or 00015 // modify it under the terms of the GNU Library General Public 00016 // License as published by the Free Software Foundation; either 00017 // version 2 of the License, or (at your option) any later version. 00018 // 00019 // This library is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00022 // Library General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU Library General Public 00025 // License along with this library; if not, write to the Free Software 00026 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00027 // USA. 00028 // 00029 // Please report all bugs and problems on the following page: 00030 // 00031 // http://www.fltk.org/str.php 00032 // 00033 00034 #include <FL/Fl.H> 00035 #include "Fl_Widget_Type.h" 00036 #include "alignment_panel.h" 00037 #include <FL/fl_message.H> 00038 #include <FL/Fl_Menu_.H> 00039 #include <FL/Fl_Button.H> 00040 #include <FL/Fl_Value_Input.H> 00041 #include <FL/Fl_Text_Display.H> 00042 #include "../src/flstring.h" 00043 #include <stdio.h> 00044 #include <stdlib.h> 00045 00046 Fl_Menu_Item menu_item_type_menu[] = { 00047 {"Normal",0,0,(void*)0}, 00048 {"Toggle",0,0,(void*)FL_MENU_BOX}, 00049 {"Radio",0,0,(void*)FL_MENU_RADIO}, 00050 {0}}; 00051 00052 extern int reading_file; 00053 extern int force_parent; 00054 extern int i18n_type; 00055 extern const char* i18n_include; 00056 extern const char* i18n_function; 00057 extern const char* i18n_file; 00058 extern const char* i18n_set; 00059 00060 static char submenuflag; 00061 00062 void Fl_Input_Choice_Type::build_menu() { 00063 Fl_Input_Choice* w = (Fl_Input_Choice*)o; 00064 // count how many Fl_Menu_Item structures needed: 00065 int n = 0; 00066 Fl_Type* q; 00067 for (q = next; q && q->level > level; q = q->next) { 00068 if (q->is_parent()) n++; // space for null at end of submenu 00069 n++; 00070 } 00071 if (!n) { 00072 if (menusize) delete[] (Fl_Menu_Item*)(w->menu()); 00073 w->menu(0); 00074 menusize = 0; 00075 } else { 00076 n++; // space for null at end of menu 00077 if (menusize<n) { 00078 if (menusize) delete[] (Fl_Menu_Item*)(w->menu()); 00079 menusize = n+10; 00080 w->menu(new Fl_Menu_Item[menusize]); 00081 } 00082 // fill them all in: 00083 Fl_Menu_Item* m = (Fl_Menu_Item*)(w->menu()); 00084 int lvl = level+1; 00085 for (q = next; q && q->level > level; q = q->next) { 00086 Fl_Menu_Item_Type* i = (Fl_Menu_Item_Type*)q; 00087 if (i->o->image()) i->o->image()->label(m); 00088 else { 00089 m->label(i->o->label() ? i->o->label() : "(nolabel)"); 00090 m->labeltype(i->o->labeltype()); 00091 } 00092 m->shortcut(((Fl_Button*)(i->o))->shortcut()); 00093 m->callback(0,(void*)i); 00094 m->flags = i->flags(); 00095 m->labelfont(i->o->labelfont()); 00096 m->labelsize(i->o->labelsize()); 00097 m->labelcolor(i->o->labelcolor()); 00098 if (q->is_parent()) {lvl++; m->flags |= FL_SUBMENU;} 00099 m++; 00100 int l1 = 00101 (q->next && q->next->is_menu_item()) ? q->next->level : level; 00102 while (lvl > l1) {m->label(0); m++; lvl--;} 00103 lvl = l1; 00104 } 00105 } 00106 o->redraw(); 00107 } 00108 00109 00110 Fl_Type *Fl_Menu_Item_Type::make() { 00111 // Find the current menu item: 00112 Fl_Type* q = Fl_Type::current; 00113 Fl_Type* p = q; 00114 if (p) { 00115 if ( (force_parent && q->is_menu_item()) || !q->is_parent()) p = p->parent; 00116 } 00117 force_parent = 0; 00118 if (!p || !(p->is_menu_button() || (p->is_menu_item() && p->is_parent()))) { 00119 fl_message("Please select a menu to add to"); 00120 return 0; 00121 } 00122 if (!o) { 00123 o = new Fl_Button(0,0,100,20); // create template widget 00124 o->labelsize(Fl_Widget_Type::default_size); 00125 } 00126 00127 Fl_Menu_Item_Type* t = submenuflag ? new Fl_Submenu_Type() : new Fl_Menu_Item_Type(); 00128 t->o = new Fl_Button(0,0,100,20); 00129 t->factory = this; 00130 t->add(p); 00131 if (!reading_file) t->label(submenuflag ? "submenu" : "item"); 00132 return t; 00133 } 00134 00135 Fl_Type *Fl_Submenu_Type::make() { 00136 submenuflag = 1; 00137 Fl_Type* t = Fl_Menu_Item_Type::make(); 00138 submenuflag = 0; 00139 return t; 00140 } 00141 00142 Fl_Menu_Item_Type Fl_Menu_Item_type; 00143 Fl_Submenu_Type Fl_Submenu_type; 00144 00146 // Writing the C code: 00147 00148 // test functions in Fl_Widget_Type.C: 00149 int is_name(const char *c); 00150 const char *array_name(Fl_Widget_Type *o); 00151 int isdeclare(const char *c); 00152 00153 // Search backwards to find the parent menu button and return it's name. 00154 // Also put in i the index into the button's menu item array belonging 00155 // to this menu item. 00156 const char* Fl_Menu_Item_Type::menu_name(int& i) { 00157 i = 0; 00158 Fl_Type* t = prev; 00159 while (t && t->is_menu_item()) { 00160 // be sure to count the {0} that ends a submenu: 00161 if (t->level > t->next->level) i += (t->level - t->next->level); 00162 // detect empty submenu: 00163 else if (t->level == t->next->level && t->is_parent()) i++; 00164 t = t->prev; 00165 i++; 00166 } 00167 return unique_id(t, "menu", t->name(), t->label()); 00168 } 00169 00170 #include "Fluid_Image.h" 00171 00172 void Fl_Menu_Item_Type::write_static() { 00173 if (callback() && is_name(callback()) && !user_defined(callback())) 00174 write_declare("extern void %s(Fl_Menu_*, %s);", callback(), 00175 user_data_type() ? user_data_type() : "void*"); 00176 for (int n=0; n < NUM_EXTRA_CODE; n++) { 00177 if (extra_code(n) && isdeclare(extra_code(n))) 00178 write_declare("%s", extra_code(n)); 00179 } 00180 if (callback() && !is_name(callback())) { 00181 // see if 'o' or 'v' used, to prevent unused argument warnings: 00182 int use_o = 0; 00183 int use_v = 0; 00184 const char *d; 00185 for (d = callback(); *d;) { 00186 if (*d == 'o' && !is_id(d[1])) use_o = 1; 00187 if (*d == 'v' && !is_id(d[1])) use_v = 1; 00188 do d++; while (is_id(*d)); 00189 while (*d && !is_id(*d)) d++; 00190 } 00191 const char* cn = callback_name(); 00192 const char* k = class_name(1); 00193 if (k) { 00194 write_c("\nvoid %s::%s_i(Fl_Menu_*", k, cn); 00195 } else { 00196 write_c("\nstatic void %s(Fl_Menu_*", cn); 00197 } 00198 if (use_o) write_c(" o"); 00199 const char* ut = user_data_type() ? user_data_type() : "void*"; 00200 write_c(", %s", ut); 00201 if (use_v) write_c(" v"); 00202 write_c(") {\n %s", callback()); 00203 if (*(d-1) != ';') { 00204 const char *p = strrchr(callback(), '\n'); 00205 if (p) p ++; 00206 else p = callback(); 00207 // Only add trailing semicolon if the last line is not a preprocessor 00208 // statement... 00209 if (*p != '#' && *p) write_c(";"); 00210 } 00211 write_c("\n}\n"); 00212 if (k) { 00213 write_c("void %s::%s(Fl_Menu_* o, %s v) {\n", k, cn, ut); 00214 write_c(" ((%s*)(o->", k); 00215 Fl_Type* t = parent; while (t->is_menu_item()) t = t->parent; 00216 for (t = t->parent; t && t->is_widget() && !is_class(); t = t->parent) write_c("parent()->"); 00217 write_c("user_data()))->%s_i(o,v);\n}\n", cn); 00218 } 00219 } 00220 if (image) { 00221 if (image->written != write_number) { 00222 image->write_static(); 00223 image->written = write_number; 00224 } 00225 } 00226 if (next && next->is_menu_item()) return; 00227 // okay, when we hit last item in the menu we have to write the 00228 // entire array out: 00229 const char* k = class_name(1); 00230 if (k) { 00231 int i; 00232 if (i18n_type) write_c("\nunsigned char %s::%s_i18n_done = 0;", k, menu_name(i)); 00233 write_c("\nFl_Menu_Item %s::%s[] = {\n", k, menu_name(i)); 00234 } else { 00235 int i; 00236 if (i18n_type) write_c("\nunsigned char %s_i18n_done = 0;", menu_name(i)); 00237 write_c("\nFl_Menu_Item %s[] = {\n", menu_name(i)); 00238 } 00239 Fl_Type* t = prev; while (t && t->is_menu_item()) t = t->prev; 00240 for (Fl_Type* q = t->next; q && q->is_menu_item(); q = q->next) { 00241 ((Fl_Menu_Item_Type*)q)->write_item(); 00242 int thislevel = q->level; if (q->is_parent()) thislevel++; 00243 int nextlevel = 00244 (q->next && q->next->is_menu_item()) ? q->next->level : t->level+1; 00245 while (thislevel > nextlevel) {write_c(" {0,0,0,0,0,0,0,0,0},\n"); thislevel--;} 00246 } 00247 write_c(" {0,0,0,0,0,0,0,0,0}\n};\n"); 00248 00249 if (k) { 00250 // Write menu item variables... 00251 t = prev; while (t && t->is_menu_item()) t = t->prev; 00252 for (Fl_Type* q = t->next; q && q->is_menu_item(); q = q->next) { 00253 Fl_Menu_Item_Type *m = (Fl_Menu_Item_Type*)q; 00254 const char *c = array_name(m); 00255 if (c) { 00256 if (c==m->name()) { 00257 // assign a menu item address directly to a variable 00258 int i; 00259 const char* n = ((Fl_Menu_Item_Type *)q)->menu_name(i); 00260 write_c("Fl_Menu_Item* %s::%s = %s::%s + %d;\n", k, c, k, n, i); 00261 } else { 00262 // if the name is an array, only define the array. 00263 // The actual assignment is in write_code1() 00264 write_c("Fl_Menu_Item* %s::%s;\n", k, c); 00265 } 00266 } 00267 } 00268 } 00269 } 00270 00271 int Fl_Menu_Item_Type::flags() { 00272 int i = o->type(); 00273 if (((Fl_Button*)o)->value()) i |= FL_MENU_VALUE; 00274 if (!o->active()) i |= FL_MENU_INACTIVE; 00275 if (!o->visible()) i |= FL_MENU_INVISIBLE; 00276 if (is_parent()) { 00277 if (user_data() == NULL) i |= FL_SUBMENU; 00278 else i |= FL_SUBMENU_POINTER; 00279 } 00280 if (hotspot()) i |= FL_MENU_DIVIDER; 00281 return i; 00282 } 00283 00284 void Fl_Menu_Item_Type::write_item() { 00285 static const char * const labeltypes[] = { 00286 "FL_NORMAL_LABEL", 00287 "FL_NO_LABEL", 00288 "FL_SHADOW_LABEL", 00289 "FL_ENGRAVED_LABEL", 00290 "FL_EMBOSSED_LABEL", 00291 "FL_MULTI_LABEL", 00292 "FL_ICON_LABEL", 00293 "FL_IMAGE_LABEL" 00294 }; 00295 00296 write_c(" {"); 00297 if (image) write_c("0"); 00298 else if (label()) write_cstring(label()); // we will call i18n when the widget is instantiated for the first time 00299 else write_c("\"\""); 00300 if (((Fl_Button*)o)->shortcut()) { 00301 int s = ((Fl_Button*)o)->shortcut(); 00302 if (use_FL_COMMAND && (s & (FL_CTRL|FL_META))) { 00303 write_c(", FL_COMMAND|0x%x, ", s & ~(FL_CTRL|FL_META)); 00304 } else { 00305 write_c(", 0x%x, ", s); 00306 } 00307 } else 00308 write_c(", 0, "); 00309 if (callback()) { 00310 const char* k = is_name(callback()) ? 0 : class_name(1); 00311 if (k) { 00312 write_c(" (Fl_Callback*)%s::%s,", k, callback_name()); 00313 } else { 00314 write_c(" (Fl_Callback*)%s,", callback_name()); 00315 } 00316 } else 00317 write_c(" 0,"); 00318 if (user_data()) 00319 write_c(" (void*)(%s),", user_data()); 00320 else 00321 write_c(" 0,"); 00322 write_c(" %d, %s, %d, %d, %d", flags(), 00323 labeltypes[o->labeltype()], o->labelfont(), o->labelsize(), o->labelcolor()); 00324 write_c("},\n"); 00325 } 00326 00327 void Fl_Menu_Item_Type::write_code1() { 00328 int i; const char* mname = menu_name(i); 00329 if (!prev->is_menu_item()) { 00330 // for first menu item, declare the array 00331 if (class_name(1)) { 00332 if (i18n_type) write_h(" static unsigned char %s_i18n_done;\n", mname); 00333 write_h(" static Fl_Menu_Item %s[];\n", mname); 00334 } else { 00335 if (i18n_type) write_h("extern unsigned char %s_i18n_done;\n", mname); 00336 write_h("extern Fl_Menu_Item %s[];\n", mname); 00337 } 00338 } 00339 00340 const char *c = array_name(this); 00341 if (c) { 00342 if (class_name(1)) { 00343 write_public(public_); 00344 write_h(" static Fl_Menu_Item *%s;\n", c); 00345 } else { 00346 if (c==name()) 00347 write_h("#define %s (%s+%d)\n", c, mname, i); 00348 else 00349 write_h("extern Fl_Menu_Item *%s;\n", c); 00350 } 00351 } 00352 00353 if (callback()) { 00354 if (!is_name(callback()) && class_name(1)) { 00355 const char* cn = callback_name(); 00356 const char* ut = user_data_type() ? user_data_type() : "void*"; 00357 write_public(0); 00358 write_h(" void %s_i(Fl_Menu_*, %s);\n", cn, ut); 00359 write_h(" static void %s(Fl_Menu_*, %s);\n", cn, ut); 00360 } 00361 } 00362 00363 int init = 0; 00364 // if the name is an array variable, assign the value here 00365 if (name() && strchr(name(), '[')) { 00366 write_c("%s%s = &%s[%d];\n", indent(), name(), mname, i); 00367 } 00368 if (image) { 00369 if (!init) { 00370 init = 1; 00371 write_c("%s{ Fl_Menu_Item* o = &%s[%d];\n", indent(), mname, i); 00372 } 00373 image->write_code("o"); 00374 } 00375 for (int n=0; n < NUM_EXTRA_CODE; n++) 00376 if (extra_code(n) && !isdeclare(extra_code(n))) { 00377 if (!init) { 00378 init = 1; 00379 write_c("%s{ Fl_Menu_Item* o = &%s[%d];\n", indent(), mname, i); 00380 } 00381 write_c("%s %s\n", indent(), extra_code(n)); 00382 } 00383 if (init) write_c("%s}\n",indent()); 00384 } 00385 00386 void Fl_Menu_Item_Type::write_code2() {} 00387 00389 // This is the base class for widgets that contain a menu (ie 00390 // subclasses of Fl_Menu_. 00391 // This is a parent widget and menu items can be added as 00392 // children. An actual array of Fl_Menu_Items is kept parallel 00393 // with the child objects and updated as they change. 00394 00395 void Fl_Menu_Type::build_menu() { 00396 Fl_Menu_* w = (Fl_Menu_*)o; 00397 // count how many Fl_Menu_Item structures needed: 00398 int n = 0; 00399 Fl_Type* q; 00400 for (q = next; q && q->level > level; q = q->next) { 00401 if (q->is_parent()) n++; // space for null at end of submenu 00402 n++; 00403 } 00404 if (!n) { 00405 if (menusize) delete[] (Fl_Menu_Item*)(w->menu()); 00406 w->menu(0); 00407 menusize = 0; 00408 } else { 00409 n++; // space for null at end of menu 00410 if (menusize<n) { 00411 if (menusize) delete[] (Fl_Menu_Item*)(w->menu()); 00412 menusize = n+10; 00413 w->menu(new Fl_Menu_Item[menusize]); 00414 } 00415 // fill them all in: 00416 Fl_Menu_Item* m = (Fl_Menu_Item*)(w->menu()); 00417 int lvl = level+1; 00418 for (q = next; q && q->level > level; q = q->next) { 00419 Fl_Menu_Item_Type* i = (Fl_Menu_Item_Type*)q; 00420 if (i->o->image()) i->o->image()->label(m); 00421 else { 00422 m->label(i->o->label() ? i->o->label() : "(nolabel)"); 00423 m->labeltype(i->o->labeltype()); 00424 } 00425 m->shortcut(((Fl_Button*)(i->o))->shortcut()); 00426 m->callback(0,(void*)i); 00427 m->flags = i->flags(); 00428 m->labelfont(i->o->labelfont()); 00429 m->labelsize(i->o->labelsize()); 00430 m->labelcolor(i->o->labelcolor()); 00431 if (q->is_parent()) {lvl++; m->flags |= FL_SUBMENU;} 00432 m++; 00433 int l1 = 00434 (q->next && q->next->is_menu_item()) ? q->next->level : level; 00435 while (lvl > l1) {m->label(0); m++; lvl--;} 00436 lvl = l1; 00437 } 00438 } 00439 o->redraw(); 00440 } 00441 00442 Fl_Type* Fl_Menu_Type::click_test(int, int) { 00443 if (selected) return 0; // let user move the widget 00444 Fl_Menu_* w = (Fl_Menu_*)o; 00445 if (!menusize) return 0; 00446 const Fl_Menu_Item* save = w->mvalue(); 00447 w->value((Fl_Menu_Item*)0); 00448 Fl::pushed(w); 00449 w->handle(FL_PUSH); 00450 const Fl_Menu_Item* m = w->mvalue(); 00451 if (m) { 00452 // restore the settings of toggles & radio items: 00453 if (m->flags & (FL_MENU_RADIO | FL_MENU_TOGGLE)) build_menu(); 00454 return (Fl_Type*)(m->user_data()); 00455 } 00456 w->value(save); 00457 return this; 00458 } 00459 00460 void Fl_Menu_Type::write_code2() { 00461 if (next && next->is_menu_item()) { 00462 if (i18n_type) { 00463 // take care of i18n now! 00464 Fl_Menu_Item_Type *mi = (Fl_Menu_Item_Type*)next; 00465 int i, nItem = 0, nLabel = 0; 00466 const char *mName = mi->menu_name(i); 00467 for (Fl_Type* q = next; q && q->is_menu_item(); q = q->next) { 00468 if (((Fl_Menu_Item_Type*)q)->label()) nLabel++; 00469 nItem++; 00470 } 00471 if (nLabel) { 00472 write_c("%sif (!%s_i18n_done) {\n", indent(), mName); 00473 write_c("%s int i=0;\n", indent()); 00474 write_c("%s for ( ; i<%d; i++)\n", indent(), nItem); 00475 write_c("%s if (%s[i].label())\n", indent(), mName); 00476 switch (i18n_type) { 00477 case 1: 00478 write_c("%s %s[i].label(%s(%s[i].label()));\n", 00479 indent(), mName, i18n_function, mName); 00480 break; 00481 case 2: 00482 write_c("%s %s[i].label(catgets(%s,%s,i+%d,%s[i].label()));\n", 00483 indent(), mName, i18n_file[0] ? i18n_file : "_catalog", 00484 i18n_set, mi->msgnum(), mName); 00485 break; 00486 } 00487 write_c("%s %s_i18n_done = 1;\n", indent(), mName); 00488 write_c("%s}\n", indent()); 00489 } 00490 } 00491 write_c("%s%s->menu(%s);\n", indent(), name() ? name() : "o", 00492 unique_id(this, "menu", name(), label())); 00493 } 00494 Fl_Widget_Type::write_code2(); 00495 } 00496 00497 void Fl_Menu_Type::copy_properties() { 00498 Fl_Widget_Type::copy_properties(); 00499 Fl_Menu_ *s = (Fl_Menu_*)o, *d = (Fl_Menu_*)live_widget; 00500 d->menu(s->menu()); 00501 d->down_box(s->down_box()); 00502 d->textcolor(s->textcolor()); 00503 d->textfont(s->textfont()); 00504 d->textsize(s->textsize()); 00505 } 00506 00508 00509 #include <FL/Fl_Menu_Button.H> 00510 Fl_Menu_Item button_type_menu[] = { 00511 {"normal",0,0,(void*)0}, 00512 {"popup1",0,0,(void*)Fl_Menu_Button::POPUP1}, 00513 {"popup2",0,0,(void*)Fl_Menu_Button::POPUP2}, 00514 {"popup3",0,0,(void*)Fl_Menu_Button::POPUP3}, 00515 {"popup12",0,0,(void*)Fl_Menu_Button::POPUP12}, 00516 {"popup23",0,0,(void*)Fl_Menu_Button::POPUP23}, 00517 {"popup13",0,0,(void*)Fl_Menu_Button::POPUP13}, 00518 {"popup123",0,0,(void*)Fl_Menu_Button::POPUP123}, 00519 {0}}; 00520 00521 Fl_Menu_Button_Type Fl_Menu_Button_type; 00522 00524 00525 Fl_Menu_Item dummymenu[] = {{"CHOICE"},{0}}; 00526 00527 Fl_Choice_Type Fl_Choice_type; 00528 00529 Fl_Input_Choice_Type Fl_Input_Choice_type; 00530 00531 void Fl_Input_Choice_Type::copy_properties() { 00532 Fl_Widget_Type::copy_properties(); 00533 Fl_Input_Choice *s = (Fl_Input_Choice*)o, *d = (Fl_Input_Choice*)live_widget; 00534 d->menu(s->menu()); 00535 d->down_box(s->down_box()); 00536 d->textcolor(s->textcolor()); 00537 d->textfont(s->textfont()); 00538 d->textsize(s->textsize()); 00539 } 00540 00541 Fl_Type* Fl_Input_Choice_Type::click_test(int, int) { 00542 if (selected) return 0; // let user move the widget 00543 Fl_Menu_* w = ((Fl_Input_Choice*)o)->menubutton(); 00544 if (!menusize) return 0; 00545 const Fl_Menu_Item* save = w->mvalue(); 00546 w->value((Fl_Menu_Item*)0); 00547 Fl::pushed(w); 00548 w->handle(FL_PUSH); 00549 const Fl_Menu_Item* m = w->mvalue(); 00550 if (m) { 00551 // restore the settings of toggles & radio items: 00552 if (m->flags & (FL_MENU_RADIO | FL_MENU_TOGGLE)) build_menu(); 00553 return (Fl_Type*)(m->user_data()); 00554 } 00555 w->value(save); 00556 return this; 00557 } 00558 00560 00561 Fl_Menu_Bar_Type Fl_Menu_Bar_type; 00562 00564 // Shortcut entry item in panel: 00565 00566 #include <FL/Fl_Output.H> 00567 #include "Shortcut_Button.h" 00568 #include <FL/fl_draw.H> 00569 00570 void Shortcut_Button::draw() { 00571 if (value()) draw_box(FL_DOWN_BOX, (Fl_Color)9); 00572 else draw_box(FL_UP_BOX, FL_WHITE); 00573 fl_font(FL_HELVETICA,14); fl_color(FL_FOREGROUND_COLOR); 00574 if (use_FL_COMMAND && (svalue & (FL_CTRL|FL_META))) { 00575 char buf[1024]; 00576 fl_snprintf(buf, 1023, "Command+%s", fl_shortcut_label(svalue&~(FL_CTRL|FL_META))); 00577 fl_draw(buf,x()+6,y(),w(),h(),FL_ALIGN_LEFT); 00578 } else { 00579 fl_draw(fl_shortcut_label(svalue),x()+6,y(),w(),h(),FL_ALIGN_LEFT); 00580 } 00581 } 00582 00583 int Shortcut_Button::handle(int e) { 00584 when(0); type(FL_TOGGLE_BUTTON); 00585 if (e == FL_KEYBOARD) { 00586 if (!value()) return 0; 00587 int v = Fl::event_text()[0]; 00588 if ( (v > 32 && v < 0x7f) || (v > 0xa0 && v <= 0xff) ) { 00589 if (isupper(v)) { 00590 v = tolower(v); 00591 v |= FL_SHIFT; 00592 } 00593 v = v | (Fl::event_state()&(FL_META|FL_ALT|FL_CTRL)); 00594 } else { 00595 v = (Fl::event_state()&(FL_META|FL_ALT|FL_CTRL|FL_SHIFT)) | Fl::event_key(); 00596 if (v == FL_BackSpace && svalue) v = 0; 00597 } 00598 if (v != svalue) {svalue = v; set_changed(); redraw(); do_callback(); } 00599 return 1; 00600 } else if (e == FL_UNFOCUS) { 00601 int c = changed(); value(0); if (c) set_changed(); 00602 return 1; 00603 } else if (e == FL_FOCUS) { 00604 return value(); 00605 } else { 00606 int r = Fl_Button::handle(e); 00607 if (e == FL_RELEASE && value() && Fl::focus() != this) take_focus(); 00608 return r; 00609 } 00610 } 00611 00612 void shortcut_in_cb(Shortcut_Button* i, void* v) { 00613 if (v == LOAD) { 00614 if (current_widget->is_button()) 00615 i->svalue = ((Fl_Button*)(current_widget->o))->shortcut(); 00616 else if (current_widget->is_input()) 00617 i->svalue = ((Fl_Input_*)(current_widget->o))->shortcut(); 00618 else if (current_widget->is_value_input()) 00619 i->svalue = ((Fl_Value_Input*)(current_widget->o))->shortcut(); 00620 else if (current_widget->is_text_display()) 00621 i->svalue = ((Fl_Text_Display*)(current_widget->o))->shortcut(); 00622 else { 00623 i->hide(); 00624 return; 00625 } 00626 i->show(); 00627 i->redraw(); 00628 } else { 00629 int mod = 0; 00630 for (Fl_Type *o = Fl_Type::first; o; o = o->next) 00631 if (o->selected && o->is_button()) { 00632 Fl_Button* b = (Fl_Button*)(((Fl_Widget_Type*)o)->o); 00633 if (b->shortcut()!=i->svalue) mod = 1; 00634 b->shortcut(i->svalue); 00635 if (o->is_menu_item()) ((Fl_Widget_Type*)o)->redraw(); 00636 } else if (o->selected && o->is_input()) { 00637 Fl_Input_* b = (Fl_Input_*)(((Fl_Widget_Type*)o)->o); 00638 if (b->shortcut()!=i->svalue) mod = 1; 00639 b->shortcut(i->svalue); 00640 } else if (o->selected && o->is_value_input()) { 00641 Fl_Value_Input* b = (Fl_Value_Input*)(((Fl_Widget_Type*)o)->o); 00642 if (b->shortcut()!=i->svalue) mod = 1; 00643 b->shortcut(i->svalue); 00644 } else if (o->selected && o->is_text_display()) { 00645 Fl_Text_Display* b = (Fl_Text_Display*)(((Fl_Widget_Type*)o)->o); 00646 if (b->shortcut()!=i->svalue) mod = 1; 00647 b->shortcut(i->svalue); 00648 } 00649 if (mod) set_modflag(1); 00650 } 00651 } 00652 00653 // 00654 // End of "$Id: Fl_Menu_Type.cxx 7903 2010-11-28 21:06:39Z matt $". 00655 //