|
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_Sys_Menu_Bar.cxx 7518 2010-04-16 19:27:28Z manolo $" 00003 // 00004 // MacOS system menu bar widget 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 00055 #if defined(__APPLE__) || defined(FL_DOXYGEN) 00056 00057 #include <FL/x.H> 00058 #include <FL/Fl.H> 00059 #include <FL/Fl_Sys_Menu_Bar.H> 00060 00061 #include "flstring.h" 00062 #include <stdio.h> 00063 #include <ctype.h> 00064 #include <stdarg.h> 00065 00066 #define MenuHandle void * 00067 00068 typedef const Fl_Menu_Item *pFl_Menu_Item; 00069 00070 00071 /* 00072 * Set a shortcut for an Apple menu item using the FLTK shortcut descriptor. 00073 */ 00074 static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) 00075 { 00076 if ( !m->shortcut_ ) 00077 return; 00078 if ( m->flags & FL_SUBMENU ) 00079 return; 00080 if ( m->flags & FL_SUBMENU_POINTER ) 00081 return; 00082 char key = m->shortcut_ & 0xff; 00083 if ( !isalnum( key ) ) 00084 return; 00085 00086 void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); 00087 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, menuItem, m->shortcut_ & 0xff ); 00088 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, menuItem, m->shortcut_ ); 00089 } 00090 00091 00092 /* 00093 * Set the Toggle and Radio flag based on FLTK flags 00094 */ 00095 static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) 00096 { 00097 if ( m->flags & FL_MENU_TOGGLE ) 00098 { 00099 void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); 00100 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); 00101 } 00102 else if ( m->flags & FL_MENU_RADIO ) { 00103 void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); 00104 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); 00105 } 00106 } 00107 00108 00109 /* 00110 * create a sub menu for a specific menu handle 00111 */ 00112 static void createSubMenu( void * mh, pFl_Menu_Item &mm ) 00113 { 00114 void *submenu; 00115 int miCnt, flags; 00116 00117 void *menuItem; 00118 submenu = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::initWithTitle, mm->text); 00119 int cnt; 00120 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, mh, &cnt); 00121 cnt--; 00122 menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, cnt); 00123 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setSubmenu, menuItem, submenu); 00124 if ( mm->flags & FL_MENU_INACTIVE ) { 00125 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, menuItem, 0); 00126 } 00127 mm++; 00128 00129 while ( mm->text ) 00130 { 00131 int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); 00132 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, submenu, flRank, &miCnt); 00133 setMenuFlags( submenu, miCnt, mm ); 00134 setMenuShortcut( submenu, miCnt, mm ); 00135 if ( mm->flags & FL_MENU_INACTIVE ) { 00136 void *item = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, submenu, miCnt); 00137 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, item, 0); 00138 } 00139 flags = mm->flags; 00140 if ( mm->flags & FL_SUBMENU ) 00141 { 00142 createSubMenu( submenu, mm ); 00143 } 00144 else if ( mm->flags & FL_SUBMENU_POINTER ) 00145 { 00146 const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; 00147 createSubMenu( submenu, smm ); 00148 } 00149 if ( flags & FL_MENU_DIVIDER ) { 00150 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addSeparatorItem, submenu); 00151 } 00152 mm++; 00153 } 00154 } 00155 00156 00157 /* 00158 * convert a complete Fl_Menu_Item array into a series of menus in the top menu bar 00159 * ALL PREVIOUS SYSTEM MENUS, EXCEPT APPLICATION MENU, ARE REPLACED BY THE NEW DATA 00160 */ 00161 static void convertToMenuBar(const Fl_Menu_Item *mm) 00162 { 00163 int count;//first, delete all existing system menus 00164 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, fl_system_menu, &count); 00165 for(int i = count - 1; i > 0; i--) { 00166 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, i); 00167 } 00168 //now convert FLTK stuff into MacOS menus 00169 for (;;) 00170 { 00171 if ( !mm || !mm->text ) 00172 break; 00173 char visible = mm->visible() ? 1 : 0; 00174 int flRank = mm - fl_sys_menu_bar->Fl_Menu_::menu(); 00175 Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, fl_system_menu, flRank, NULL); 00176 00177 if ( mm->flags & FL_SUBMENU ) 00178 createSubMenu( fl_system_menu, mm ); 00179 else if ( mm->flags & FL_SUBMENU_POINTER ) { 00180 const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; 00181 createSubMenu( fl_system_menu, smm ); 00182 } 00183 if ( visible ) { 00184 // InsertMenu( mh, 0 ); 00185 } 00186 mm++; 00187 } 00188 } 00189 00190 00198 void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) 00199 { 00200 fl_open_display(); 00201 Fl_Menu_Bar::menu( m ); 00202 convertToMenuBar(m); 00203 } 00204 00205 00214 int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) 00215 { 00216 fl_open_display(); 00217 int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags); 00218 convertToMenuBar(Fl_Menu_::menu()); 00219 return rank; 00220 } 00221 00230 int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) 00231 { 00232 fl_open_display(); 00233 int rank = Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags); 00234 convertToMenuBar(Fl_Menu_::menu()); 00235 return rank; 00236 } 00237 00238 void Fl_Sys_Menu_Bar::clear() 00239 { 00240 Fl_Menu_::clear(); 00241 convertToMenuBar(NULL); 00242 } 00243 00244 int Fl_Sys_Menu_Bar::clear_submenu(int index) 00245 { 00246 int retval = Fl_Menu_::clear_submenu(index); 00247 if (retval != -1) convertToMenuBar(Fl_Menu_::menu()); 00248 return retval; 00249 } 00250 00256 void Fl_Sys_Menu_Bar::remove(int rank) 00257 { 00258 Fl_Menu_::remove(rank); 00259 convertToMenuBar(Fl_Menu_::menu()); 00260 } 00261 00262 00269 void Fl_Sys_Menu_Bar::replace(int rank, const char *name) 00270 { 00271 doMenuOrItemOperation(renameItem, rank, name); 00272 fl_sys_menu_bar->Fl_Menu_::replace(rank, name); 00273 } 00274 00275 00276 /* 00277 * Draw the menu bar. 00278 * Nothing here because the OS does this for us. 00279 */ 00280 void Fl_Sys_Menu_Bar::draw() { 00281 } 00282 00283 00284 #endif /* __APPLE__ */ 00285 00286 // 00287 // End of "$Id: Fl_Sys_Menu_Bar.cxx 7518 2010-04-16 19:27:28Z manolo $". 00288 //