diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 2001-11-27 17:44:08 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2001-11-27 17:44:08 +0000 |
| commit | 2b85bf81680e2243ef5a5daf85d9eb04321c7278 (patch) | |
| tree | dc7d3e1cdbd44ed10b358412098b73d24b64d143 /src/Fl_Sys_Menu_Bar.cxx | |
| parent | 4dc5732a3e0f376786d1d6b788e5cf601439e890 (diff) | |
Preliminary commit of my MacOS X work.
**** THIS CODE COMPILES BUT DOES NOT WORK. ****
TODO: fix event handling - getting blank windows, etc.
TODO: re-port OpenGL code.
TODO: add support for images with alpha.
TODO: add support for more then just beeps in fl_beep().
TODO: other stuff I'm sure...
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1765 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Sys_Menu_Bar.cxx')
| -rw-r--r-- | src/Fl_Sys_Menu_Bar.cxx | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/src/Fl_Sys_Menu_Bar.cxx b/src/Fl_Sys_Menu_Bar.cxx new file mode 100644 index 000000000..399b22c61 --- /dev/null +++ b/src/Fl_Sys_Menu_Bar.cxx @@ -0,0 +1,314 @@ +// +// "$Id: Fl_Sys_Menu_Bar.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $" +// +// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org". +// + +/** + * Tis code is a quick hack! It was written as a proove of concept. + * It has been tested on the "menubar" sample program and provides + * basic functionality. + * + * To use the System Menu Bar, simply replace the main Fl_Menu_Bar + * in an application with Fl_Sys_Menu_Bar. + * + * FLTK features not supported by the Mac System menu + * + * - no invisible menu items + * - no sybolic labels + * - embossed labels will be underlined instead + * - no font sizes + * - Shortcut Characters should be English alphanumeric only, no modifiers yet + * - no disable main menus + * - changes to menubar in run-time don't update! + * (disable, etc. - toggle and readio button do!) + * + * No care was taken to clean up the menu bar after destruction! + * ::menu(bar) should only be called once! + * Many other calls of the parent class don't work. + * Changing the menu items has no effect on the menu bar. + */ + +#include <FL/X.H> +#include <FL/Fl.H> +#include <FL/Fl_Sys_Menu_Bar.H> + +#include <string.h> +#include <stdio.h> +#include <ctype.h> + +typedef const Fl_Menu_Item *pFl_Menu_Item; + +/** + * copy the text of a menuitem into a buffer. + * Skip all '&' which would mark the shortcut in FLTK + * Skip all Mac control characters ('(', '<', ';', '^', '!' ) + */ +static void catMenuText( const char *src, char *dst ) +{ + char c; + while ( *dst ) + dst++; + if ( *src == '-' ) + src++; + while ( ( c = *src++ ) ) + { + if ( !strchr( "&(<;^!", c ) ) + *dst++ = c; + } + *dst = 0; +} + +/** + * append a marker to identify the menu font style + * <B, I, U, O, and S + */ +static void catMenuFont( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->labeltype_ && !m->labelfont_ ) + return; + while ( *dst ) + dst++; + + if ( m->labelfont_ & FL_BOLD ) + strcat( dst, "<B" ); + if ( m->labelfont_ & FL_ITALIC ) + strcat( dst, "<I" ); + //if ( m->labelfont_ & FL_UNDERLINE ) + // strcat( dst, "<U" ); + + if ( m->labeltype_ == FL_EMBOSSED_LABEL ) + strcat( dst, "<U" ); + else if ( m->labeltype_ == FL_ENGRAVED_LABEL ) + strcat( dst, "<O" ); + else if ( m->labeltype_ == FL_SHADOW_LABEL ) + strcat( dst, "<S" ); + //else if ( m->labeltype_ == FL_SYMBOL_LABEL ) + ; // not supported +} + +/** + * append a marker to identify the menu shortcut + * <B, I, U, O, and S +enum { +ÊÊÊÊkMenuNoModifiersÊÊÊÊÊÊÊÊ= 0, +ÊÊÊÊkMenuShiftModifierÊÊÊÊÊÊ= (1 << 0), +ÊÊÊÊkMenuOptionModifierÊÊÊÊÊ= (1 << 1), +ÊÊÊÊkMenuControlModifierÊÊÊÊ= (1 << 2), +ÊÊÊÊkMenuNoCommandModifierÊÊ= (1 << 3) +}; + */ +static void setShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( !m->shortcut_ ) + return; + char key = m->shortcut_ & 0xff; + if ( !isalnum( key ) ) + return; + char mod = m->shortcut_ & 0xff00; + + long macMod = kMenuNoModifiers; + if ( mod & FL_SHIFT ) macMod |= kMenuShiftModifier; + if ( mod & FL_CTRL ) macMod |= kMenuOptionModifier; + if ( !(mod & FL_ALT) ) macMod |= kMenuNoCommandModifier; + + SetItemCmd( mh, miCnt, key ); + SetMenuItemModifiers( mh, miCnt, macMod ); +} + +static void catMenuShortcut( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->shortcut_ ) + return; + char c = m->shortcut_ & 0xff; + if ( !isalnum( c & 0xff ) ) + return; + while ( *dst ) + dst++; + if ( m->shortcut_ & FL_ALT ) + { + sprintf( dst, "/%c", toupper( c ) ); + } + //if ( isalnum( mm->shortcut_ ) && !( mm->flags & FL_SUBMENU ) ) + //sprintf( buf+strlen(buf), "/%c", mm->shortcut_ ); +} + +static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( m->flags & FL_MENU_TOGGLE ) + { + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + } + else if ( m->flags & FL_MENU_RADIO ) + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); +} + +static void catMenuFlags( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->flags ) + return; + while ( *dst ) + dst++; + if ( m->flags & FL_MENU_INACTIVE ) + strcat( dst, "(" ); +} + +/** + * create a sub menu for a specific menu handle + */ +static void createSubMenu( MenuHandle mh, int &cnt, pFl_Menu_Item &mm ) +{ + char buf[255]; + int miCnt = 1; + while ( mm->text ) + { + MenuHandle smh; + buf[1] = 0; + catMenuFont( mm, buf+1 ); + catMenuShortcut( mm, buf+1 ); + catMenuText( mm->text, buf+1 ); + catMenuFlags( mm, buf+1 ); + if ( mm->flags & (FL_SUBMENU | FL_SUBMENU_POINTER) ) + { + cnt++; + smh = NewMenu( cnt, (unsigned char*)"\001 " ); + sprintf( buf+1+strlen(buf+1), "/\033!%c", cnt ); + } + if ( mm->flags & FL_MENU_DIVIDER ) + strcat( buf+1, ";-" ); + buf[0] = strlen( buf+1 ); + AppendMenu( mh, (unsigned char*)buf ); + // insert Appearanc manager functions here! + setMenuFlags( mh, miCnt, mm ); + SetMenuItemRefCon( mh, miCnt, (UInt32)mm ); + miCnt++; + if ( mm->flags & FL_MENU_DIVIDER ) + miCnt++; + if ( mm->flags & FL_SUBMENU ) + { + createSubMenu( smh, cnt, ++mm ); + } + else if ( mm->flags & FL_SUBMENU_POINTER ) + { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( mh, cnt, smm ); + } + mm++; + } + InsertMenu( mh, -1 ); +} + + +/** + * create a system menu bar using the given list of menu structs + * + * \author Matthias Melcher + * + * @param m list of Fl_Menu_Item + */ +void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) +{ + fl_open_display(); + Fl_Menu_Bar::menu( m ); + fl_sys_menu_bar = this; + + char buf[255]; + int cnt = 1; // first menu is no 2. no 1 is the Apple Menu + + const Fl_Menu_Item *mm = m; + for (;;) + { + if ( !mm->text ) + break; + buf[1] = 0; + catMenuText( mm->text, buf+1 ); + buf[0] = strlen( buf+1 ); + MenuHandle mh = NewMenu( ++cnt, (unsigned char*)buf ); + if ( mm->flags & FL_SUBMENU ) + createSubMenu( mh, cnt, ++mm ); + else if ( mm->flags & FL_SUBMENU_POINTER ) + { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( mh, cnt, smm ); + } + + InsertMenu( mh, 0 ); + if ( mm->flags & FL_MENU_INACTIVE ) DisableItem( mh, 0 ); + mm++; + } + DrawMenuBar(); +} + +/* +const Fl_Menu_Item* Fl_Sys_Menu_Bar::picked(const Fl_Menu_Item* v) { + Fl_menu_Item *ret = Fl_Menu_Bar::picked( v ); + + if ( m->flags & FL_MENU_TOGGLE ) + { + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + } + + return ret; +} +*/ + +void Fl_Sys_Menu_Bar::draw() { +/* -- nothing to do, system should take care of this + draw_box(); + if (!menu() || !menu()->text) return; + const Fl_Menu_Item* m; + int X = x()+6; + for (m=menu(); m->text; m = m->next()) { + int W = m->measure(0,this) + 16; + m->draw(X, y(), W, h(), this); + X += W; + } + */ +} + +/* +int Fl_Menu_Bar::handle(int event) { + const Fl_Menu_Item* v; + if (menu() && menu()->text) switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; + case FL_PUSH: + v = 0; + J1: + v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); + picked(v); + return 1; + case FL_SHORTCUT: + if (visible_r()) { + v = menu()->find_shortcut(); + if (v && v->submenu()) goto J1; + } + return test_shortcut() != 0; + } + return 0; +} +*/ + +// +// End of "$Id: Fl_Sys_Menu_Bar.cxx,v 1.1.2.1 2001/11/27 17:44:06 easysw Exp $". +// |
