Author: manolo
Date: 2012-01-13 02:13:47 -0800 (Fri, 13 Jan 2012)
New Revision: 9225
Log:
Moved all system menu-related objective-c code to new file cocoaSysMenuBar.mm
(renamed from SysMenuBar.cxx).
Added:
branches/branch-3.0/src/fltk3/cocoaSysMenuBar.mm
Removed:
branches/branch-3.0/src/fltk3/SysMenuBar.cxx
Modified:
branches/branch-3.0/include/fltk3/SysMenuBar.h
branches/branch-3.0/include/fltk3/osx.h
branches/branch-3.0/src/Makefile
branches/branch-3.0/src/fltk3/cocoa.mm
Modified: branches/branch-3.0/include/fltk3/SysMenuBar.h
===================================================================
--- branches/branch-3.0/include/fltk3/SysMenuBar.h 2012-01-12 16:07:08 UTC
(rev 9224)
+++ branches/branch-3.0/include/fltk3/SysMenuBar.h 2012-01-13 10:13:47 UTC
(rev 9225)
@@ -36,6 +36,7 @@
namespace fltk3 {
#if defined(__APPLE__) || defined(FLTK3_DOXYGEN)
+ extern class SysMenuBar *sys_menu_bar;
/**
@brief A class to create, modify and delete menus that appear on Mac OS X
in the menu bar at the top of the screen.
@@ -71,12 +72,6 @@
void replace(int rank, const char *name);
void clear();
int clear_submenu(int index);
-#if ! defined(FLTK3_DOXYGEN)
- enum menuOrItemOperation { itemAtIndex, setKeyEquivalent,
setKeyEquivalentModifierMask, setState, initWithTitle,
- numberOfItems, setSubmenu, setEnabled, addSeparatorItem, setTitle,
removeItem, addNewItem };
- // function doMenuOrItemOperation is in file F|_cocoa.mm because it
contains objective-c code
- static void *doMenuOrItemOperation( menuOrItemOperation operation, ...);
-#endif
};
#else
Modified: branches/branch-3.0/include/fltk3/osx.h
===================================================================
--- branches/branch-3.0/include/fltk3/osx.h 2012-01-12 16:07:08 UTC (rev
9224)
+++ branches/branch-3.0/include/fltk3/osx.h 2012-01-13 10:13:47 UTC (rev
9225)
@@ -97,7 +97,6 @@
free(r);
}
}
-extern void *fl_system_menu;
extern void *fl_default_cursor;
// This object contains all mac-specific stuff about a window:
@@ -169,9 +168,6 @@
}
extern CGContextRef fl_gc;
-namespace fltk3 {
- extern class SysMenuBar *sys_menu_bar;
-}
extern Window fl_xid(const fltk3::Window*);
extern fltk3::Window* fl_find(Window xid);
@@ -203,14 +199,6 @@
*/
extern void fl_open_callback(void (*cb)(const char *));
-/**
- * \brief Attaches a callback to the "About myprog" item of the system
application menu.
- *
- * \param cb a callback that will be called by "About myprog" menu item
- * with NULL 1st argument.
- * \param user_data a pointer transmitted as 2nd argument to the callback.
- * \param shortcut optional shortcut to attach to the "About myprog" menu
item (e.g., fltk3::META+'a')
- */
extern void fl_mac_set_about( fltk3::Callback *cb, void *user_data, unsigned
int shortcut = 0);
/** \brief The version number of the running Mac OS X (e.g., 100604 for 10.6.4)
Modified: branches/branch-3.0/src/Makefile
===================================================================
--- branches/branch-3.0/src/Makefile 2012-01-12 16:07:08 UTC (rev 9224)
+++ branches/branch-3.0/src/Makefile 2012-01-13 10:13:47 UTC (rev 9225)
@@ -83,7 +83,6 @@
fltk3/SingleWindow.cxx \
fltk3/Slider.cxx \
fltk3/Style.cxx \
- fltk3/SysMenuBar.cxx \
fltk3/Table.cxx \
fltk3/TableRow.cxx \
fltk3/TabGroup.cxx \
@@ -202,7 +201,8 @@
FLTK3_OBJCPPFILES = \
fltk3/cocoa.mm \
fltk3/cocoaNativeFileChooser.mm \
- fltk3/cocoaQuartzPrinter.mm
+ fltk3/cocoaQuartzPrinter.mm \
+ fltk3/cocoaSysMenuBar.mm
FLTK3_CFILES = \
fltk3/flstring.c \
Deleted: branches/branch-3.0/src/fltk3/SysMenuBar.cxx
Modified: branches/branch-3.0/src/fltk3/cocoa.mm
===================================================================
--- branches/branch-3.0/src/fltk3/cocoa.mm 2012-01-12 16:07:08 UTC (rev
9224)
+++ branches/branch-3.0/src/fltk3/cocoa.mm 2012-01-13 10:13:47 UTC (rev
9225)
@@ -96,8 +96,6 @@
// public variables
CGContextRef fl_gc = 0;
-void *fl_system_menu; // this is really a NSMenu*
-fltk3::SysMenuBar *fltk3::sys_menu_bar = 0;
void *fl_default_cursor; // this is really a NSCursor*
void *fl_capture = 0; // (NSWindow*) we need this to
compensate for a missing(?) mouse capture
bool fl_show_iconic; // true if called from iconize() -
shows the next created window in collapsed state
@@ -1272,7 +1270,6 @@
}
}
if (![NSApp servicesMenu]) createAppleMenu();
- fl_system_menu = [NSApp mainMenu];
main_screen_height = [[[NSScreen screens] objectAtIndex:0]
frame].size.height;
[[NSNotificationCenter defaultCenter] addObserver:[NSApp delegate]
selector:@selector(anyWindowWillClose:)
@@ -2943,216 +2940,7 @@
[menuItem release];
}
-@interface FLMenuItem : NSMenuItem
-- (const fltk3::MenuItem*) getFlItem;
-- (void) doCallback:(id)unused;
-- (void) directCallback:(id)unused;
-@end
-@implementation FLMenuItem
-- (const fltk3::MenuItem*) getFlItem
-{
- return *(const fltk3::MenuItem **)[(NSData*)[self representedObject] bytes];
-}
-- (void) doCallback:(id)unused
-{
- fl_lock_function();
- const fltk3::MenuItem *item = [self getFlItem];
- fltk3::sys_menu_bar->picked(item);
- if ( item->flags & fltk3::MENU_TOGGLE ) { // update the menu toggle symbol
- [self setState:(item->value() ? NSOnState : NSOffState)];
- }
- else if ( item->flags & fltk3::MENU_RADIO ) { // update the menu
radio symbols
- NSMenu* menu = [self menu];
- NSInteger flRank = [menu indexOfItem:self];
- NSInteger last = [menu numberOfItems] - 1;
- int from = flRank;
- while (from > 0) {
- if ([[menu itemAtIndex:from-1] isSeparatorItem]) break;
- item = [(FLMenuItem*)[menu itemAtIndex:from-1] getFlItem];
- if ( !(item->flags & fltk3::MENU_RADIO) ) break;
- from--;
- }
- int to = flRank;
- while (to < last) {
- if ([[menu itemAtIndex:to+1] isSeparatorItem]) break;
- item = [(FLMenuItem*)[menu itemAtIndex:to+1] getFlItem];
- if (!(item->flags & fltk3::MENU_RADIO)) break;
- to++;
- }
- for (int i = from; i <= to; i++) {
- NSMenuItem *nsitem = [menu itemAtIndex:i];
- [nsitem setState:(nsitem != self ? NSOffState : NSOnState)];
- }
- }
- fl_unlock_function();
-}
-- (void) directCallback:(id)unused
-{
- fl_lock_function();
- fltk3::MenuItem *item = (fltk3::MenuItem *)[(NSData*)[self
representedObject] bytes];
- if ( item && item->callback() ) item->do_callback(NULL);
- fl_unlock_function();
-}
-@end
-void fl_mac_set_about( fltk3::Callback *cb, void *user_data, unsigned int
shortcut)
-{
- fl_open_display();
- fltk3::MenuItem aboutItem;
- memset(&aboutItem, 0, sizeof(fltk3::MenuItem));
- aboutItem.callback(cb);
- aboutItem.user_data(user_data);
- aboutItem.shortcut(shortcut);
- NSMenu *appleMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
- CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu
itemAtIndex:0] title]);
- [appleMenu removeItemAtIndex:0];
- FLMenuItem *item = [[[FLMenuItem alloc] initWithTitle:(NSString*)cfname
-
action:@selector(directCallback:)
- keyEquivalent:@""] autorelease];
- if (aboutItem.shortcut()) {
-
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setKeyEquivalent,
item, aboutItem.shortcut() & 0xff);
-
fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::setKeyEquivalentModifierMask,
item, aboutItem.shortcut() );
- }
- NSData *pointer = [NSData dataWithBytes:&aboutItem
length:sizeof(fltk3::MenuItem)];
- [item setRepresentedObject:pointer];
- [appleMenu insertItem:item atIndex:0];
- CFRelease(cfname);
- [item setTarget:item];
-}
-
-static char *remove_ampersand(const char *s)
-{
- char *ret = strdup(s);
- const char *p = s;
- char *q = ret;
- while(*p != 0) {
- if (p[0]=='&') {
- if (p[1]=='&') {
- *q++ = '&'; p+=2;
- } else {
- p++;
- }
- } else {
- *q++ = *p++;
- }
- }
- *q = 0;
- return ret;
-}
-
-void
*fltk3::SysMenuBar::doMenuOrItemOperation(fltk3::SysMenuBar::menuOrItemOperation
operation, ...)
-/* these operations apply to menus, submenus, or menu items
- */
-{
- NSAutoreleasePool *localPool;
- localPool = [[NSAutoreleasePool alloc] init];
- NSMenu *menu;
- NSMenuItem *item;
- int value;
- void *pter;
- void *retval = NULL;
- va_list ap;
- va_start(ap, operation);
-
- if (operation == fltk3::SysMenuBar::itemAtIndex) { // arguments: NSMenu*,
int. Returns the item
- menu = va_arg(ap, NSMenu*);
- value = va_arg(ap, int);
- retval = (void *)[menu itemAtIndex:value];
- }
- else if (operation == fltk3::SysMenuBar::setKeyEquivalent) { // arguments:
NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- char key = value;
- NSString *equiv = [[NSString alloc] initWithBytes:&key length:1
encoding:NSASCIIStringEncoding];
- [item setKeyEquivalent:equiv];
- [equiv release];
- }
- else if (operation == fltk3::SysMenuBar::setKeyEquivalentModifierMask) {
// arguments: NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- NSUInteger macMod = 0;
- if ( value & fltk3::META ) macMod = NSCommandKeyMask;
- if ( value & fltk3::SHIFT || isupper(value) ) macMod |= NSShiftKeyMask;
- if ( value & fltk3::ALT ) macMod |= NSAlternateKeyMask;
- if ( value & fltk3::CTRL ) macMod |= NSControlKeyMask;
- [item setKeyEquivalentModifierMask:macMod];
- }
- else if (operation == fltk3::SysMenuBar::setState) { // arguments:
NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- [item setState:(value ? NSOnState : NSOffState)];
- }
- else if (operation == fltk3::SysMenuBar::initWithTitle) { // arguments:
const char*title. Returns the newly created menu
- // creates a
new (sub)menu
- char *ts = remove_ampersand(va_arg(ap, char *));
- CFStringRef title = CFStringCreateWithCString(NULL, ts,
kCFStringEncodingUTF8);
- free(ts);
- NSMenu *menu = [[NSMenu alloc] initWithTitle:(NSString*)title];
- CFRelease(title);
- [menu setAutoenablesItems:NO];
- retval = (void *)menu;
- }
- else if (operation == fltk3::SysMenuBar::numberOfItems) { // arguments:
NSMenu *menu, int *pcount
- // upon
return, *pcount is set to menu's item count
- menu = va_arg(ap, NSMenu*);
- pter = va_arg(ap, void *);
- *(int*)pter = [menu numberOfItems];
- }
- else if (operation == fltk3::SysMenuBar::setSubmenu) { //
arguments: NSMenuItem *item, NSMenu *menu
- // sets 'menu'
as submenu attached to 'item'
- item = va_arg(ap, NSMenuItem*);
- menu = va_arg(ap, NSMenu*);
- [item setSubmenu:menu];
- [menu release];
- }
- else if (operation == fltk3::SysMenuBar::setEnabled) { //
arguments: NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- [item setEnabled:(value ? YES : NO)];
- }
- else if (operation == fltk3::SysMenuBar::addSeparatorItem) { // arguments:
NSMenu*
- menu = va_arg(ap, NSMenu*);
- [menu addItem:[NSMenuItem separatorItem]];
- }
- else if (operation == fltk3::SysMenuBar::setTitle) { // arguments:
NSMenuItem*, const char *
- item = va_arg(ap, NSMenuItem*);
- char *ts = remove_ampersand(va_arg(ap, char *));
- CFStringRef title = CFStringCreateWithCString(NULL, ts,
kCFStringEncodingUTF8);
- free(ts);
- [item setTitle:(NSString*)title];
- CFRelease(title);
- }
- else if (operation == fltk3::SysMenuBar::removeItem) { //
arguments: NSMenu*, int
- menu = va_arg(ap, NSMenu*);
- value = va_arg(ap, int);
- [menu removeItem:[menu itemAtIndex:value]];
- }
- else if (operation == fltk3::SysMenuBar::addNewItem) { //
arguments: NSMenu *menu, flk3::MenuItem flrank, int *prank
- // creates a new menu item at the end of 'menu'
- // attaches the item of fltk3::sys_menu_bar to it
- // upon return, puts the rank (counted in NSMenu) of the new item in
*prank unless prank is NULL
- menu = va_arg(ap, NSMenu*);
- fltk3::MenuItem *mitem = va_arg(ap, fltk3::MenuItem *);
- int *prank = va_arg(ap, int*);
- char *name = remove_ampersand(mitem->label());
- CFStringRef cfname = CFStringCreateWithCString(NULL, name,
kCFStringEncodingUTF8);
- free(name);
- FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:(NSString*)cfname
- action:@selector(doCallback:)
- keyEquivalent:@""];
- NSData *pointer = [NSData dataWithBytes:&mitem
length:sizeof(fltk3::MenuItem*)];
- [item setRepresentedObject:pointer];
- [menu addItem:item];
- CFRelease(cfname);
- [item setTarget:item];
- if (prank != NULL) *prank = [menu indexOfItem:item];
- [item release];
- }
- va_end(ap);
- [localPool release];
- return retval;
-}
-
void Fl_X::set_key_window()
{
[xid makeKeyWindow];
Copied: branches/branch-3.0/src/fltk3/cocoaSysMenuBar.mm (from rev 9224,
branches/branch-3.0/src/fltk3/SysMenuBar.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3/cocoaSysMenuBar.mm
(rev 0)
+++ branches/branch-3.0/src/fltk3/cocoaSysMenuBar.mm 2012-01-13 10:13:47 UTC
(rev 9225)
@@ -0,0 +1,431 @@
+//
+// "$Id$"
+//
+// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 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 on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/**
+ * This code is a quick hack! It was written as a proof 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 fltk3::MenuBar
+ * in an application with fltk3::SysMenuBar.
+ *
+ * FLTK features not supported by the Mac System menu
+ *
+ * - no invisible menu items
+ * - no symbolic 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 radio 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.
+ * Starting with OS X 10.5, FLTK applications must be created as
+ * a bundle for the System Menu Bar (and maybe other features) to work!
+ */
+
+#if defined(__APPLE__) || defined(FLTK3_DOXYGEN)
+
+#import <Cocoa/Cocoa.h>
+
+#include <fltk3/x.h>
+#include <fltk3/run.h>
+#include <fltk3/SysMenuBar.h>
+
+#include "flstring.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+typedef const fltk3::MenuItem *pFl_Menu_Item;
+
+fltk3::SysMenuBar *fltk3::sys_menu_bar = 0;
+
+extern void (*fl_lock_function)();
+extern void (*fl_unlock_function)();
+
+
+@interface FLMenuItem : NSMenuItem
+- (const fltk3::MenuItem*) getFlItem;
+- (void) doCallback:(id)unused;
+- (void) directCallback:(id)unused;
+- (void)setFLKeyEquivalentModifierMask:(unsigned)value;
+@end
+@implementation FLMenuItem
+- (const fltk3::MenuItem*) getFlItem
+{
+ return *(const fltk3::MenuItem **)[(NSData*)[self representedObject] bytes];
+}
+- (void) doCallback:(id)unused
+{
+ fl_lock_function();
+ const fltk3::MenuItem *item = [self getFlItem];
+ fltk3::sys_menu_bar->picked(item);
+ if ( item->flags & fltk3::MENU_TOGGLE ) { // update the menu toggle symbol
+ [self setState:(item->value() ? NSOnState : NSOffState)];
+ }
+ else if ( item->flags & fltk3::MENU_RADIO ) { // update the menu
radio symbols
+ NSMenu* menu = [self menu];
+ int flRank = [menu indexOfItem:self];
+ int last = [menu numberOfItems] - 1;
+ int from = flRank;
+ while (from > 0) {
+ if ([[menu itemAtIndex:from-1] isSeparatorItem]) break;
+ item = [(FLMenuItem*)[menu itemAtIndex:from-1] getFlItem];
+ if ( !(item->flags & fltk3::MENU_RADIO) ) break;
+ from--;
+ }
+ int to = flRank;
+ while (to < last) {
+ if ([[menu itemAtIndex:to+1] isSeparatorItem]) break;
+ item = [(FLMenuItem*)[menu itemAtIndex:to+1] getFlItem];
+ if (!(item->flags & fltk3::MENU_RADIO)) break;
+ to++;
+ }
+ for (int i = from; i <= to; i++) {
+ NSMenuItem *nsitem = [menu itemAtIndex:i];
+ [nsitem setState:(nsitem != self ? NSOffState : NSOnState)];
+ }
+ }
+ fl_unlock_function();
+}
+- (void) directCallback:(id)unused
+{
+ fl_lock_function();
+ fltk3::MenuItem *item = (fltk3::MenuItem *)[(NSData*)[self
representedObject] bytes];
+ if ( item && item->callback() ) item->do_callback(NULL);
+ fl_unlock_function();
+}
+- (void)setFLKeyEquivalentModifierMask:(unsigned)value
+{
+ NSUInteger macMod = 0;
+ if ( value & fltk3::META ) macMod = NSCommandKeyMask;
+ if ( value & fltk3::SHIFT || isupper(value) ) macMod |= NSShiftKeyMask;
+ if ( value & fltk3::ALT ) macMod |= NSAlternateKeyMask;
+ if ( value & fltk3::CTRL ) macMod |= NSControlKeyMask;
+ [super setKeyEquivalentModifierMask:macMod];
+}
+@end
+
+// creates a new menu item at the end of 'menu'
+// attaches the item of fltk3::sys_menu_bar to it
+// returns the rank (counted in NSMenu) of the new item
+static int addNewItem(NSMenu *menu, const fltk3::MenuItem *mitem, NSString*
cfname)
+{
+ FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:cfname
+ action:@selector(doCallback:)
+ keyEquivalent:@""];
+ NSData *pointer = [NSData dataWithBytes:&mitem
length:sizeof(fltk3::MenuItem*)];
+ [item setRepresentedObject:pointer];
+ [menu addItem:item];
+ [item setTarget:item];
+ [item release];
+ return [menu indexOfItem:item];
+}
+
+/**
+ * \brief Attaches a callback to the "About myprog" item of the system
application menu.
+ *
+ * \param cb a callback that will be called by "About myprog" menu item
+ * with NULL 1st argument.
+ * \param user_data a pointer transmitted as 2nd argument to the callback.
+ * \param shortcut optional shortcut to attach to the "About myprog" menu
item (e.g., fltk3::META+'a')
+ */
+void fl_mac_set_about( fltk3::Callback *cb, void *user_data, unsigned int
shortcut)
+{
+ fl_open_display();
+ fltk3::MenuItem aboutItem;
+ memset(&aboutItem, 0, sizeof(fltk3::MenuItem));
+ aboutItem.callback(cb);
+ aboutItem.user_data(user_data);
+ aboutItem.shortcut(shortcut);
+ NSMenu *appleMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
+ CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu
itemAtIndex:0] title]);
+ [appleMenu removeItemAtIndex:0];
+ FLMenuItem *item = [[[FLMenuItem alloc] initWithTitle:(NSString*)cfname
+
action:@selector(directCallback:)
+ keyEquivalent:@""] autorelease];
+ if (aboutItem.shortcut()) {
+ char sc = aboutItem.shortcut() & 0xff;
+ NSString *equiv = [[NSString alloc] initWithBytes:&sc length:1
encoding:NSASCIIStringEncoding];
+ [item setKeyEquivalent:equiv];
+ [equiv release];
+ [item setFLKeyEquivalentModifierMask:aboutItem.shortcut()];
+ }
+ NSData *pointer = [NSData dataWithBytes:&aboutItem
length:sizeof(fltk3::MenuItem)];
+ [item setRepresentedObject:pointer];
+ [appleMenu insertItem:item atIndex:0];
+ CFRelease(cfname);
+ [item setTarget:item];
+}
+
+
+static NSString* remove_ampersand(const char *s)
+{
+ char *ret = strdup(s);
+ const char *p = s;
+ char *q = ret;
+ while(*p != 0) {
+ if (p[0]=='&') {
+ if (p[1]=='&') {
+ *q++ = '&'; p+=2;
+ } else {
+ p++;
+ }
+ } else {
+ *q++ = *p++;
+ }
+ }
+ *q = 0;
+ NSString* rets = [NSString stringWithUTF8String:ret];
+ free(ret);
+ return rets;
+}
+
+
+/*
+ * Set a shortcut for an Apple menu item using the FLTK shortcut descriptor.
+ */
+static void setMenuShortcut( NSMenu* mh, int miCnt, const fltk3::MenuItem *m )
+{
+ if ( !m->shortcut() )
+ return;
+ if ( m->flags & fltk3::SUBMENU )
+ return;
+ if ( m->flags & fltk3::SUBMENU_POINTER )
+ return;
+ char key = m->shortcut() & 0xff;
+ if ( !isalnum( key ) )
+ return;
+
+ FLMenuItem *menuItem = (FLMenuItem*)[mh itemAtIndex:miCnt];
+ char sc = m->shortcut() & 0xff;
+ NSString *equiv = [[NSString alloc] initWithBytes:&sc length:1
encoding:NSASCIIStringEncoding];
+ [menuItem setKeyEquivalent:equiv];
+ [equiv release];
+ [menuItem setFLKeyEquivalentModifierMask:m->shortcut()];
+}
+
+
+/*
+ * Set the Toggle and Radio flag based on FLTK flags
+ */
+static void setMenuFlags( NSMenu* mh, int miCnt, const fltk3::MenuItem *m )
+{
+ if ( m->flags & fltk3::MENU_TOGGLE || m->flags & fltk3::MENU_RADIO ) {
+ [[mh itemAtIndex:miCnt] setState:(m->flags & fltk3::MENU_VALUE ? NSOnState
: NSOffState)];
+ }
+}
+
+
+/*
+ * create a sub menu for a specific menu handle
+ */
+static void createSubMenu( NSMenu * mh, pFl_Menu_Item &mm, const
fltk3::MenuItem *mitem )
+{
+ NSMenu *submenu;
+ int miCnt, flags;
+
+ NSMenuItem *menuItem;
+ submenu = [[NSMenu alloc] initWithTitle:remove_ampersand(mitem->text)];
+ [submenu setAutoenablesItems:NO];
+ int cnt;
+ cnt = [mh numberOfItems] - 1;
+ menuItem = [mh itemAtIndex:cnt];
+ [menuItem setSubmenu:submenu];
+ [submenu release];
+
+ while ( mm->text )
+ {
+ char visible = mm->visible() ? 1 : 0;
+ miCnt = addNewItem(submenu, mm, remove_ampersand(mm->label()));
+ setMenuFlags( submenu, miCnt, mm );
+ setMenuShortcut( submenu, miCnt, mm );
+ if ( mm->flags & fltk3::MENU_INACTIVE || mitem->flags &
fltk3::MENU_INACTIVE) {
+ [[submenu itemAtIndex:miCnt] setEnabled:NO];
+ }
+ flags = mm->flags;
+ if ( mm->flags & fltk3::SUBMENU )
+ {
+ mm++;
+ createSubMenu( submenu, mm, mm - 1 );
+ }
+ else if ( mm->flags & fltk3::SUBMENU_POINTER )
+ {
+ const fltk3::MenuItem *smm = (fltk3::MenuItem*)mm->user_data_;
+ createSubMenu( submenu, smm, mm );
+ }
+ if ( flags & fltk3::MENU_DIVIDER ) {
+ [submenu addItem:[NSMenuItem separatorItem]];
+ }
+ if ( !visible ) {
+ [submenu removeItem:[submenu itemAtIndex:miCnt]];
+ }
+ mm++;
+ }
+}
+
+
+/*
+ * convert a complete fltk3::MenuItem array into a series of menus in the top
menu bar
+ * ALL PREVIOUS SYSTEM MENUS, EXCEPT THE APPLICATION MENU, ARE REPLACED BY THE
NEW DATA
+ */
+static void convertToMenuBar(const fltk3::MenuItem *mm)
+{
+ int rank;
+ int count;//first, delete all existing system menus
+ NSMenu* fl_system_menu = [NSApp mainMenu];
+ count = [fl_system_menu numberOfItems];
+ for(int i = count - 1; i > 0; i--) {
+ [fl_system_menu removeItem:[fl_system_menu itemAtIndex:i]];
+ }
+ //now convert FLTK stuff into MacOS menus
+ for (;;)
+ {
+ if ( !mm || !mm->text )
+ break;
+ char visible = mm->visible() ? 1 : 0;
+ rank = addNewItem(fl_system_menu, mm, remove_ampersand(mm->label()));
+
+ if ( mm->flags & fltk3::SUBMENU ) {
+ mm++;
+ createSubMenu( fl_system_menu, mm, mm - 1);
+ }
+ else if ( mm->flags & fltk3::SUBMENU_POINTER ) {
+ const fltk3::MenuItem *smm = (fltk3::MenuItem*)mm->user_data_;
+ createSubMenu( fl_system_menu, smm, mm);
+ }
+ if ( !visible ) {
+ [fl_system_menu removeItem:[fl_system_menu itemAtIndex:rank]];
+ }
+ mm++;
+ }
+}
+
+
+/**
+ * @brief create a system menu bar using the given list of menu structs
+ *
+ * \author Matthias Melcher
+ *
+ * @param m list of fltk3::MenuItem
+ */
+void fltk3::SysMenuBar::menu(const fltk3::MenuItem *m)
+{
+ fl_open_display();
+ fltk3::MenuBar::menu( m );
+ convertToMenuBar(m);
+}
+
+
+/**
+ * @brief add to the system menu bar a new menu item
+ *
+ * add to the system menu bar a new menu item, with a title string, shortcut
int,
+ * callback, argument to the callback, and flags.
+ *
+ * @see fltk3::Menu_::add(const char* label, int shortcut, fltk3::Callback
*cb, void *user_data, int flags)
+ */
+int fltk3::SysMenuBar::add(const char* label, unsigned int shortcut,
fltk3::Callback *cb, void *user_data, int flags)
+{
+ fl_open_display();
+ int rank = fltk3::Menu_::add(label, shortcut, cb, user_data, flags);
+ convertToMenuBar(fltk3::Menu_::menu());
+ return rank;
+}
+
+/**
+ * @brief insert in the system menu bar a new menu item
+ *
+ * insert in the system menu bar a new menu item, with a title string,
shortcut int,
+ * callback, argument to the callback, and flags.
+ *
+ * @see fltk3::Menu_::insert(int index, const char* label, int shortcut,
fltk3::Callback *cb, void *user_data, int flags)
+ */
+int fltk3::SysMenuBar::insert(int index, const char* label, unsigned int
shortcut, fltk3::Callback *cb, void *user_data, int flags)
+{
+ fl_open_display();
+ int rank = fltk3::Menu_::insert(index, label, shortcut, cb, user_data,
flags);
+ convertToMenuBar(fltk3::Menu_::menu());
+ return rank;
+}
+
+void fltk3::SysMenuBar::clear()
+{
+ fltk3::Menu_::clear();
+ convertToMenuBar(NULL);
+}
+
+int fltk3::SysMenuBar::clear_submenu(int index)
+{
+ int retval = fltk3::Menu_::clear_submenu(index);
+ if (retval != -1) convertToMenuBar(fltk3::Menu_::menu());
+ return retval;
+}
+
+/**
+ * @brief remove an item from the system menu bar
+ *
+ * @param rank the rank of the item to remove
+ */
+void fltk3::SysMenuBar::remove(int rank)
+{
+ fltk3::Menu_::remove(rank);
+ convertToMenuBar(fltk3::Menu_::menu());
+}
+
+
+/**
+ * @brief rename an item from the system menu bar
+ *
+ * @param rank the rank of the item to rename
+ * @param name the new item name as a UTF8 string
+ */
+void fltk3::SysMenuBar::replace(int rank, const char *name)
+{
+ fltk3::Menu_::replace(rank, name);
+ convertToMenuBar(fltk3::Menu_::menu());
+}
+
+
+/*
+ * Draw the menu bar.
+ * Nothing here because the OS does this for us.
+ */
+void fltk3::SysMenuBar::draw() {
+}
+
+
+#endif /* __APPLE__ */
+
+//
+// End of "$Id$".
+//
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit