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)  

Fl_Sys_Menu_Bar.cxx

Go to the documentation of this file.
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 //