diff options
| author | Manolo Gouy <Manolo> | 2013-04-16 14:02:42 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2013-04-16 14:02:42 +0000 |
| commit | 6b69461ea9d84c405ffb7f41e1d8b4b306088407 (patch) | |
| tree | 8f427a2f4e1d9823cd26f7b15d7fe239780ff35f | |
| parent | b176f4d3f61f668f52bb773aca18f68d5ed2a1ce (diff) | |
Renamed src/Fl_Sys_Menu_Bar.cxx to src/Fl_Sys_Menu_Bar.mm because objective-c code is used.
Some code is transferred from Fl_cocoa.mm thus reducing somewhat this very large source file.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9885 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | FL/mac.H | 1 | ||||
| -rw-r--r-- | ide/Xcode3/FLTK.xcodeproj/project.pbxproj | 8 | ||||
| -rw-r--r-- | ide/Xcode4/FLTK.xcodeproj/project.pbxproj | 8 | ||||
| -rw-r--r-- | src/Fl_Sys_Menu_Bar.cxx | 289 | ||||
| -rw-r--r-- | src/Fl_Sys_Menu_Bar.mm | 437 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 215 | ||||
| -rw-r--r-- | src/Makefile | 4 |
7 files changed, 448 insertions, 514 deletions
@@ -83,7 +83,6 @@ inline void XDestroyRegion(Fl_Region r) { free(r); } } -extern void *fl_system_menu; extern void *fl_default_cursor; // This object contains all mac-specific stuff about a window: diff --git a/ide/Xcode3/FLTK.xcodeproj/project.pbxproj b/ide/Xcode3/FLTK.xcodeproj/project.pbxproj index dfa1d4bb1..723912601 100644 --- a/ide/Xcode3/FLTK.xcodeproj/project.pbxproj +++ b/ide/Xcode3/FLTK.xcodeproj/project.pbxproj @@ -134,7 +134,6 @@ 319E158B9FA80488D676A040 /* fltk_jpeg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C39FA04F3B7CD8E53876D0F4 /* fltk_jpeg.framework */; }; 31F6473A9B5FD4FFB078BA78 /* fltk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEB0F8FE6383384180570D94 /* fltk.framework */; }; 3222D7D927BF1220D08F1DF8 /* fltk.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FEB0F8FE6383384180570D94 /* fltk.framework */; }; - 32824BE9A80F72339A5B441F /* Fl_Sys_Menu_Bar.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 30662FB4292F9C613576933B /* Fl_Sys_Menu_Bar.cxx */; }; 33175A3FB04A133479A558BA /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A4DF1725F38E4341C5C663 /* pngwrite.c */; }; 339D0DFC256DE06A10F214B3 /* Fl_Wizard.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 9951B49F640C2C15321EED9C /* Fl_Wizard.cxx */; }; 33FCC793A92F544711E09A1E /* fltk_png.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98A16A4EC098BA7DB21E13DC /* fltk_png.framework */; }; @@ -328,6 +327,7 @@ 7F66B1D912BB924C00C67B59 /* Fl_cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */; }; 7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */; }; 7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */; }; + 7FFDE4AD171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */; }; 812129561A1981D6DEFBCBFB /* Fl_Positioner.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 05BBBFE4BED0452E5D6A81F7 /* Fl_Positioner.cxx */; }; 812761E94039F13357F56EE6 /* fltk_png.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98A16A4EC098BA7DB21E13DC /* fltk_png.framework */; }; 813BAC8244B19F51594C89C4 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = D33C668435685F7CCB359EE2 /* pngrio.c */; }; @@ -4155,7 +4155,6 @@ 2DD93178E8AFA850DAC293FC /* fl_dnd.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fl_dnd.cxx; path = ../../src/fl_dnd.cxx; sourceTree = SOURCE_ROOT; }; 2DE25DB4CE986C1857B5ECF7 /* Fl_Native_File_Chooser.cxx */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Fl_Native_File_Chooser.cxx; path = ../../src/Fl_Native_File_Chooser.cxx; sourceTree = SOURCE_ROOT; }; 2E774D7FE17DC45AFDF985FE /* message.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = message.cxx; path = ../../test/message.cxx; sourceTree = SOURCE_ROOT; }; - 30662FB4292F9C613576933B /* Fl_Sys_Menu_Bar.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Sys_Menu_Bar.cxx; path = ../../src/Fl_Sys_Menu_Bar.cxx; sourceTree = SOURCE_ROOT; }; 31D736821E68F01A1A11FC9F /* Fl_Help_View.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Help_View.H; path = ../../FL/Fl_Help_View.H; sourceTree = SOURCE_ROOT; }; 31FF037FBCA8B6C0CACB0A37 /* list_visuals.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = list_visuals.cxx; path = ../../test/list_visuals.cxx; sourceTree = SOURCE_ROOT; }; 323779B8DE42371A98337337 /* CubeView.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CubeView.cxx; path = ../../test/CubeView.cxx; sourceTree = SOURCE_ROOT; }; @@ -4338,6 +4337,7 @@ 7F784151AF1B748D0F3DB1C0 /* forms.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = forms.cxx; path = ../../test/forms.cxx; sourceTree = SOURCE_ROOT; }; 7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; }; 7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; }; 800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_XBM_Image.cxx; path = ../../src/Fl_XBM_Image.cxx; sourceTree = SOURCE_ROOT; }; 806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Group.cxx; path = ../../src/Fl_Group.cxx; sourceTree = SOURCE_ROOT; }; 80CD4956321634F723D3C40B /* fluid.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = fluid.icns; path = icons/fluid.icns; sourceTree = "<group>"; }; @@ -5440,6 +5440,7 @@ 7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */, 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */, 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */, + 7FFDE4AC171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm */, F4EFF27D730BED51EF0EAA8D /* Fl.cxx */, 19C5DB6F3DD5011DAE6F79AB /* Fl_Adjuster.cxx */, 3F000DD5F091F66BC42822E3 /* Fl_Bitmap.cxx */, @@ -5495,7 +5496,6 @@ 57639C1D5415FB55436556A2 /* Fl_Shared_Image.cxx */, 9D942824B8FC886F6FCD853D /* Fl_Single_Window.cxx */, 5AF5119D08DFC92EA1032671 /* Fl_Slider.cxx */, - 30662FB4292F9C613576933B /* Fl_Sys_Menu_Bar.cxx */, 116F849BE68830F05CA66B9A /* Fl_Table.cxx */, 351BFCA4747AF494F84FFE36 /* Fl_Table_Row.cxx */, D5F75B6C9483B2BB47965789 /* Fl_Tabs.cxx */, @@ -9357,6 +9357,7 @@ 7F66B1D912BB924C00C67B59 /* Fl_cocoa.mm in Sources */, 7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */, 7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */, + 7FFDE4AD171D8AA3008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */, ED83B85BA678C8C9B5E91535 /* Fl.cxx in Sources */, B371C5FF1106E69056784D6C /* Fl_Adjuster.cxx in Sources */, 274F92CF30A586E0F8E21530 /* Fl_Bitmap.cxx in Sources */, @@ -9411,7 +9412,6 @@ 2C4DB237B4B8ACD2FB305BD5 /* Fl_Shared_Image.cxx in Sources */, ED169E1E1FC93C1F97D21AC4 /* Fl_Single_Window.cxx in Sources */, 29A99477531233BE9391CE66 /* Fl_Slider.cxx in Sources */, - 32824BE9A80F72339A5B441F /* Fl_Sys_Menu_Bar.cxx in Sources */, DB29DA4D89702B490E69B569 /* Fl_Table.cxx in Sources */, 644FEEF43A0CCBD89E2CE6FC /* Fl_Table_Row.cxx in Sources */, CDCB453B3493D8E96E80DFF7 /* Fl_Tabs.cxx in Sources */, diff --git a/ide/Xcode4/FLTK.xcodeproj/project.pbxproj b/ide/Xcode4/FLTK.xcodeproj/project.pbxproj index 7c01becab..5ebf93b79 100644 --- a/ide/Xcode4/FLTK.xcodeproj/project.pbxproj +++ b/ide/Xcode4/FLTK.xcodeproj/project.pbxproj @@ -133,7 +133,6 @@ 319E158B9FA80488D676A040 /* fltk_jpeg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C39FA04F3B7CD8E53876D0F4 /* fltk_jpeg.framework */; }; 31F6473A9B5FD4FFB078BA78 /* fltk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEB0F8FE6383384180570D94 /* fltk.framework */; }; 3222D7D927BF1220D08F1DF8 /* fltk.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = FEB0F8FE6383384180570D94 /* fltk.framework */; }; - 32824BE9A80F72339A5B441F /* Fl_Sys_Menu_Bar.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 30662FB4292F9C613576933B /* Fl_Sys_Menu_Bar.cxx */; }; 33175A3FB04A133479A558BA /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A4DF1725F38E4341C5C663 /* pngwrite.c */; }; 339D0DFC256DE06A10F214B3 /* Fl_Wizard.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 9951B49F640C2C15321EED9C /* Fl_Wizard.cxx */; }; 33FCC793A92F544711E09A1E /* fltk_png.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 98A16A4EC098BA7DB21E13DC /* fltk_png.framework */; }; @@ -332,6 +331,7 @@ 7FDBB8F616B2D1FA00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92031F16B1A909000FC50F /* Localizable.strings */; }; 7FDBB8F716B2D1FF00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92031C16B1A909000FC50F /* Localizable.strings */; }; 7FDBB8F816B2D20A00AE76EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F92031916B1A909000FC50F /* Localizable.strings */; }; + 7FFDE552171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7FFDE551171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm */; }; 812129561A1981D6DEFBCBFB /* Fl_Positioner.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 05BBBFE4BED0452E5D6A81F7 /* Fl_Positioner.cxx */; }; 812761E94039F13357F56EE6 /* fltk_png.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 98A16A4EC098BA7DB21E13DC /* fltk_png.framework */; }; 813BAC8244B19F51594C89C4 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = D33C668435685F7CCB359EE2 /* pngrio.c */; }; @@ -4145,7 +4145,6 @@ 2DD93178E8AFA850DAC293FC /* fl_dnd.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fl_dnd.cxx; path = ../../src/fl_dnd.cxx; sourceTree = SOURCE_ROOT; }; 2DE25DB4CE986C1857B5ECF7 /* Fl_Native_File_Chooser.cxx */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = Fl_Native_File_Chooser.cxx; path = ../../src/Fl_Native_File_Chooser.cxx; sourceTree = SOURCE_ROOT; }; 2E774D7FE17DC45AFDF985FE /* message.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = message.cxx; path = ../../test/message.cxx; sourceTree = SOURCE_ROOT; }; - 30662FB4292F9C613576933B /* Fl_Sys_Menu_Bar.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Sys_Menu_Bar.cxx; path = ../../src/Fl_Sys_Menu_Bar.cxx; sourceTree = SOURCE_ROOT; }; 31D736821E68F01A1A11FC9F /* Fl_Help_View.H */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Fl_Help_View.H; path = ../../FL/Fl_Help_View.H; sourceTree = SOURCE_ROOT; }; 31FF037FBCA8B6C0CACB0A37 /* list_visuals.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = list_visuals.cxx; path = ../../test/list_visuals.cxx; sourceTree = SOURCE_ROOT; }; 323779B8DE42371A98337337 /* CubeView.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CubeView.cxx; path = ../../test/CubeView.cxx; sourceTree = SOURCE_ROOT; }; @@ -4333,6 +4332,7 @@ 7F92032616B1A90A000FC50F /* Spanish */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = Spanish; path = Localizable.strings; sourceTree = "<group>"; }; 7FAC914955D699539F73B996 /* bitmap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bitmap.cxx; path = ../../test/bitmap.cxx; sourceTree = SOURCE_ROOT; }; 7FC91721DA7888C8A1FD762E /* input_choice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = input_choice.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7FFDE551171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Fl_Sys_Menu_Bar.mm; path = ../../src/Fl_Sys_Menu_Bar.mm; sourceTree = SOURCE_ROOT; }; 800E34DEF9E503C5EC6C4FA5 /* Fl_XBM_Image.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_XBM_Image.cxx; path = ../../src/Fl_XBM_Image.cxx; sourceTree = SOURCE_ROOT; }; 806103D71A8CD0075BF8E1DA /* Fl_Group.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fl_Group.cxx; path = ../../src/Fl_Group.cxx; sourceTree = SOURCE_ROOT; }; 80CD4956321634F723D3C40B /* fluid.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = fluid.icns; path = icons/fluid.icns; sourceTree = "<group>"; }; @@ -5434,6 +5434,7 @@ 7F66B1D612BB924C00C67B59 /* Fl_cocoa.mm */, 7F66B1D712BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm */, 7F66B1D812BB924C00C67B59 /* Fl_Quartz_Printer.mm */, + 7FFDE551171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm */, F4EFF27D730BED51EF0EAA8D /* Fl.cxx */, 19C5DB6F3DD5011DAE6F79AB /* Fl_Adjuster.cxx */, 3F000DD5F091F66BC42822E3 /* Fl_Bitmap.cxx */, @@ -5489,7 +5490,6 @@ 57639C1D5415FB55436556A2 /* Fl_Shared_Image.cxx */, 9D942824B8FC886F6FCD853D /* Fl_Single_Window.cxx */, 5AF5119D08DFC92EA1032671 /* Fl_Slider.cxx */, - 30662FB4292F9C613576933B /* Fl_Sys_Menu_Bar.cxx */, 116F849BE68830F05CA66B9A /* Fl_Table.cxx */, 351BFCA4747AF494F84FFE36 /* Fl_Table_Row.cxx */, D5F75B6C9483B2BB47965789 /* Fl_Tabs.cxx */, @@ -9396,6 +9396,7 @@ 7F66B1D912BB924C00C67B59 /* Fl_cocoa.mm in Sources */, 7F66B1DA12BB924C00C67B59 /* Fl_Native_File_Chooser_MAC.mm in Sources */, 7F66B1DB12BB924C00C67B59 /* Fl_Quartz_Printer.mm in Sources */, + 7FFDE552171D8D0D008753A3 /* Fl_Sys_Menu_Bar.mm in Sources */, ED83B85BA678C8C9B5E91535 /* Fl.cxx in Sources */, B371C5FF1106E69056784D6C /* Fl_Adjuster.cxx in Sources */, 274F92CF30A586E0F8E21530 /* Fl_Bitmap.cxx in Sources */, @@ -9450,7 +9451,6 @@ 2C4DB237B4B8ACD2FB305BD5 /* Fl_Shared_Image.cxx in Sources */, ED169E1E1FC93C1F97D21AC4 /* Fl_Single_Window.cxx in Sources */, 29A99477531233BE9391CE66 /* Fl_Slider.cxx in Sources */, - 32824BE9A80F72339A5B441F /* Fl_Sys_Menu_Bar.cxx in Sources */, DB29DA4D89702B490E69B569 /* Fl_Table.cxx in Sources */, 644FEEF43A0CCBD89E2CE6FC /* Fl_Table_Row.cxx in Sources */, CDCB453B3493D8E96E80DFF7 /* Fl_Tabs.cxx in Sources */, diff --git a/src/Fl_Sys_Menu_Bar.cxx b/src/Fl_Sys_Menu_Bar.cxx deleted file mode 100644 index b3ed78073..000000000 --- a/src/Fl_Sys_Menu_Bar.cxx +++ /dev/null @@ -1,289 +0,0 @@ -// -// "$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. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// http://www.fltk.org/COPYING.php -// -// 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 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 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(FL_DOXYGEN) - -#include <FL/x.H> -#include <FL/Fl.H> -#include <FL/Fl_Sys_Menu_Bar.H> - -#include "flstring.h" -#include <stdio.h> -#include <ctype.h> -#include <stdarg.h> - -#define MenuHandle void * - -typedef const Fl_Menu_Item *pFl_Menu_Item; - - -/* - * Set a shortcut for an Apple menu item using the FLTK shortcut descriptor. - */ -static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) -{ - if ( !m->shortcut_ ) - return; - if ( m->flags & FL_SUBMENU ) - return; - if ( m->flags & FL_SUBMENU_POINTER ) - return; - char key = m->shortcut_ & 0xff; - if ( !isalnum( key ) ) - return; - - void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, menuItem, m->shortcut_ & 0xff ); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, menuItem, m->shortcut_ ); -} - - -/* - * Set the Toggle and Radio flag based on FLTK flags - */ -static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) -{ - if ( m->flags & FL_MENU_TOGGLE ) - { - void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); - } - else if ( m->flags & FL_MENU_RADIO ) { - void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE ); - } -} - - -/* - * create a sub menu for a specific menu handle - */ -static void createSubMenu( void * mh, pFl_Menu_Item &mm, const Fl_Menu_Item *mitem) -{ - void *submenu; - int miCnt, flags; - - void *menuItem; - submenu = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::initWithTitle, mitem->text); - int cnt; - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, mh, &cnt); - cnt--; - menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, cnt); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setSubmenu, menuItem, submenu); - - while ( mm->text ) - { - char visible = mm->visible() ? 1 : 0; - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, submenu, mm, &miCnt); - setMenuFlags( submenu, miCnt, mm ); - setMenuShortcut( submenu, miCnt, mm ); - if ( mm->flags & FL_MENU_INACTIVE || mitem->flags & FL_MENU_INACTIVE) { - void *item = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, submenu, miCnt); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, item, 0); - } - flags = mm->flags; - if ( mm->flags & FL_SUBMENU ) - { - mm++; - createSubMenu( submenu, mm, mm - 1 ); - } - else if ( mm->flags & FL_SUBMENU_POINTER ) - { - const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; - createSubMenu( submenu, smm, mm ); - } - if ( flags & FL_MENU_DIVIDER ) { - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addSeparatorItem, submenu); - } - if ( !visible ) { - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, submenu, miCnt); - } - mm++; - } -} - - -/* - * convert a complete Fl_Menu_Item 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 Fl_Menu_Item *mm) -{ - int rank; - int count;//first, delete all existing system menus - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, fl_system_menu, &count); - for(int i = count - 1; i > 0; i--) { - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, i); - } - //now convert FLTK stuff into MacOS menus - for (;;) - { - if ( !mm || !mm->text ) - break; - char visible = mm->visible() ? 1 : 0; - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, fl_system_menu, mm, &rank); - - if ( mm->flags & FL_SUBMENU ) { - mm++; - createSubMenu( fl_system_menu, mm, mm - 1); - } - else if ( mm->flags & FL_SUBMENU_POINTER ) { - const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; - createSubMenu( fl_system_menu, smm, mm); - } - if ( !visible ) { - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, rank); - } - mm++; - } -} - - -/** - * @brief 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 ); - 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 Fl_Menu_::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) - */ -int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) -{ - fl_open_display(); - int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags); - convertToMenuBar(Fl_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 Fl_Menu_::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) - */ -int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) -{ - fl_open_display(); - int rank = Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags); - convertToMenuBar(Fl_Menu_::menu()); - return rank; -} - -void Fl_Sys_Menu_Bar::clear() -{ - Fl_Menu_::clear(); - convertToMenuBar(NULL); -} - -int Fl_Sys_Menu_Bar::clear_submenu(int index) -{ - int retval = Fl_Menu_::clear_submenu(index); - if (retval != -1) convertToMenuBar(Fl_Menu_::menu()); - return retval; -} - -/** - * @brief remove an item from the system menu bar - * - * @param rank the rank of the item to remove - */ -void Fl_Sys_Menu_Bar::remove(int rank) -{ - Fl_Menu_::remove(rank); - convertToMenuBar(Fl_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 Fl_Sys_Menu_Bar::replace(int rank, const char *name) -{ - Fl_Menu_::replace(rank, name); - convertToMenuBar(Fl_Menu_::menu()); -} - - -/* - * Draw the menu bar. - * Nothing here because the OS does this for us. - */ -void Fl_Sys_Menu_Bar::draw() { -} - - -Fl_Sys_Menu_Bar::Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l) -: Fl_Menu_Bar(x,y,w,h,l) -{ - deactivate(); // don't let the old area take events - fl_sys_menu_bar = this; -} - - -#endif /* __APPLE__ */ - -// -// End of "$Id$". -// diff --git a/src/Fl_Sys_Menu_Bar.mm b/src/Fl_Sys_Menu_Bar.mm new file mode 100644 index 000000000..a14a53215 --- /dev/null +++ b/src/Fl_Sys_Menu_Bar.mm @@ -0,0 +1,437 @@ +// +// "$Id$" +// +// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2013 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// http://www.fltk.org/COPYING.php +// +// 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 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 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(FL_DOXYGEN) +#include <FL/Fl_Menu_Item.H> +#include <FL/Fl_Sys_Menu_Bar.H> +#include <FL/x.H> +#include <FL/Fl.H> + +#import <Cocoa/Cocoa.h> + +#include "flstring.h" +#include <stdio.h> +#include <ctype.h> +#include <stdarg.h> + +typedef const Fl_Menu_Item *pFl_Menu_Item; + +Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0; + +static char *remove_ampersand(const char *s); +extern void (*fl_lock_function)(); +extern void (*fl_unlock_function)(); + +@interface FLMenuItem : NSMenuItem { +} +- (void) doCallback:(id)unused; +- (void) directCallback:(id)unused; +- (const Fl_Menu_Item*) getFlItem; +- (void) setKeyEquivalent:(char)value; +- (void) setKeyEquivalentModifierMask:(int)value; ++ (int) addNewItem:(const Fl_Menu_Item*)mitem menu:(NSMenu*)menu; +@end + +@implementation FLMenuItem +- (const Fl_Menu_Item*) getFlItem +{ + return *(const Fl_Menu_Item **)[(NSData*)[self representedObject] bytes]; +} +- (void) doCallback:(id)unused +{ + fl_lock_function(); + const Fl_Menu_Item *item = [self getFlItem]; + fl_sys_menu_bar->picked(item); + if ( item->flags & FL_MENU_TOGGLE ) { // update the menu toggle symbol + [self setState:(item->value() ? NSOnState : NSOffState)]; + } + else if ( item->flags & FL_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 & FL_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 & FL_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(); + Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes]; + if ( item && item->callback() ) item->do_callback(NULL); + fl_unlock_function(); +} +- (void) setKeyEquivalent:(char)key +{ + NSString *equiv = [[NSString alloc] initWithBytes:&key length:1 encoding:NSASCIIStringEncoding]; + [super setKeyEquivalent:equiv]; + [equiv release]; +} +- (void) setKeyEquivalentModifierMask:(int)value +{ + NSUInteger macMod = 0; + if ( value & FL_META ) macMod = NSCommandKeyMask; + if ( value & FL_SHIFT || isupper(value) ) macMod |= NSShiftKeyMask; + if ( value & FL_ALT ) macMod |= NSAlternateKeyMask; + if ( value & FL_CTRL ) macMod |= NSControlKeyMask; + [super setKeyEquivalentModifierMask:macMod]; +} ++ (int) addNewItem:(const Fl_Menu_Item*)mitem menu:(NSMenu*)menu +{ + 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(Fl_Menu_Item*)]; + [item setRepresentedObject:pointer]; + [menu addItem:item]; + CFRelease(cfname); + [item setTarget:item]; + int retval = [menu indexOfItem:item]; + [item release]; + return retval; +} +@end + + +void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut) +{ + fl_open_display(); + Fl_Menu_Item aboutItem; + memset(&aboutItem, 0, sizeof(Fl_Menu_Item)); + 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()) { + [item setKeyEquivalent:(aboutItem.shortcut() & 0xff)]; + [item setKeyEquivalentModifierMask:aboutItem.shortcut()]; + } + NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)]; + [item setRepresentedObject:pointer]; + [appleMenu insertItem:item atIndex:0]; + CFRelease(cfname); + [item setTarget:item]; +} + +/* + * Set a shortcut for an Apple menu item using the FLTK shortcut descriptor. + */ +static void setMenuShortcut( NSMenu* mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( !m->shortcut_ ) + return; + if ( m->flags & FL_SUBMENU ) + return; + if ( m->flags & FL_SUBMENU_POINTER ) + return; + char key = m->shortcut_ & 0xff; + if ( !isalnum( key ) ) + return; + + FLMenuItem* menuItem = (FLMenuItem*)[mh itemAtIndex:miCnt]; + [menuItem setKeyEquivalent:(m->shortcut_ & 0xff)]; + [menuItem setKeyEquivalentModifierMask:m->shortcut_]; +} + + +/* + * Set the Toggle and Radio flag based on FLTK flags + */ +static void setMenuFlags( NSMenu* mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( m->flags & FL_MENU_TOGGLE ) + { + NSMenuItem *menuItem = [mh itemAtIndex:miCnt]; + [menuItem setState:(m->flags & FL_MENU_VALUE ? NSOnState : NSOffState)]; + } + else if ( m->flags & FL_MENU_RADIO ) { + NSMenuItem *menuItem = [mh itemAtIndex:miCnt]; + [menuItem setState:(m->flags & FL_MENU_VALUE ? NSOnState : NSOffState)]; + } +} + +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; +} + + +/* + * create a sub menu for a specific menu handle + */ +static void createSubMenu( NSMenu *mh, pFl_Menu_Item &mm, const Fl_Menu_Item *mitem) +{ + NSMenu *submenu; + int miCnt, flags; + + NSMenuItem *menuItem; + char *ts = remove_ampersand(mitem->text); + CFStringRef title = CFStringCreateWithCString(NULL, ts, kCFStringEncodingUTF8); + free(ts); + submenu = [[NSMenu alloc] initWithTitle:(NSString*)title]; + CFRelease(title); + [submenu setAutoenablesItems:NO]; + + int cnt; + cnt = [mh numberOfItems]; + cnt--; + menuItem = [mh itemAtIndex:cnt]; + [menuItem setSubmenu:submenu]; + [submenu release]; + + while ( mm->text ) + { + char visible = mm->visible() ? 1 : 0; + miCnt = [FLMenuItem addNewItem:mm menu:submenu]; + setMenuFlags( submenu, miCnt, mm ); + setMenuShortcut( submenu, miCnt, mm ); + if ( mm->flags & FL_MENU_INACTIVE || mitem->flags & FL_MENU_INACTIVE) { + NSMenuItem *item = [submenu itemAtIndex:miCnt]; + [item setEnabled:NO]; + } + flags = mm->flags; + if ( mm->flags & FL_SUBMENU ) + { + mm++; + createSubMenu( submenu, mm, mm - 1 ); + } + else if ( mm->flags & FL_SUBMENU_POINTER ) + { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( submenu, smm, mm ); + } + if ( flags & FL_MENU_DIVIDER ) { + [submenu addItem:[NSMenuItem separatorItem]]; + } + if ( !visible ) { + [submenu removeItem:[submenu itemAtIndex:miCnt]]; + } + mm++; + } +} + + +/* + * convert a complete Fl_Menu_Item 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 Fl_Menu_Item *mm) +{ + NSMenu *fl_system_menu = [NSApp mainMenu]; + int rank; + int count;//first, delete all existing system menus + 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 = [FLMenuItem addNewItem:mm menu:fl_system_menu]; + + if ( mm->flags & FL_SUBMENU ) { + mm++; + createSubMenu(fl_system_menu, mm, mm - 1); + } + else if ( mm->flags & FL_SUBMENU_POINTER ) { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)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 Fl_Menu_Item + */ +void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) +{ + fl_open_display(); + Fl_Menu_Bar::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 Fl_Menu_::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) + */ +int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) +{ + fl_open_display(); + int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags); + convertToMenuBar(Fl_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 Fl_Menu_::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) + */ +int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags) +{ + fl_open_display(); + int rank = Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags); + convertToMenuBar(Fl_Menu_::menu()); + return rank; +} + +void Fl_Sys_Menu_Bar::clear() +{ + Fl_Menu_::clear(); + convertToMenuBar(NULL); +} + +int Fl_Sys_Menu_Bar::clear_submenu(int index) +{ + int retval = Fl_Menu_::clear_submenu(index); + if (retval != -1) convertToMenuBar(Fl_Menu_::menu()); + return retval; +} + +/** + * @brief remove an item from the system menu bar + * + * @param rank the rank of the item to remove + */ +void Fl_Sys_Menu_Bar::remove(int rank) +{ + Fl_Menu_::remove(rank); + convertToMenuBar(Fl_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 Fl_Sys_Menu_Bar::replace(int rank, const char *name) +{ + Fl_Menu_::replace(rank, name); + convertToMenuBar(Fl_Menu_::menu()); +} + + +/* + * Draw the menu bar. + * Nothing here because the OS does this for us. + */ +void Fl_Sys_Menu_Bar::draw() { +} + + +Fl_Sys_Menu_Bar::Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l) +: Fl_Menu_Bar(x,y,w,h,l) +{ + deactivate(); // don't let the old area take events + fl_sys_menu_bar = this; +} + + +#endif /* __APPLE__ */ + +// +// End of "$Id$". +// diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index a17ed7782..61916e3e5 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -41,7 +41,7 @@ extern "C" { #include <FL/x.H> #include <FL/Fl_Window.H> #include <FL/Fl_Tooltip.H> -#include <FL/Fl_Sys_Menu_Bar.H> +#include <FL/Fl_Menu_Item.H> #include <FL/Fl_Printer.H> #include <FL/Fl_Input_.H> #include <FL/Fl_Secret_Input.H> @@ -95,8 +95,6 @@ Fl_Display_Device *Fl_Display_Device::_display = new Fl_Display_Device(new Fl_Qu // public variables CGContextRef fl_gc = 0; -void *fl_system_menu; // this is really a NSMenu* -Fl_Sys_Menu_Bar *fl_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 @@ -1345,7 +1343,6 @@ void fl_open_display() { } } if (![NSApp servicesMenu]) createAppleMenu(); - fl_system_menu = [NSApp mainMenu]; main_screen_height = [[[NSScreen screens] objectAtIndex:0] frame].size.height; [[NSNotificationCenter defaultCenter] addObserver:[FLWindowDelegate createOnce] selector:@selector(anyWindowWillClose:) @@ -3181,216 +3178,6 @@ static void createAppleMenu(void) [menuItem release]; } -@interface FLMenuItem : NSMenuItem { -} -- (void) doCallback:(id)unused; -- (void) directCallback:(id)unused; -- (const Fl_Menu_Item*) getFlItem; -@end -@implementation FLMenuItem -- (const Fl_Menu_Item*) getFlItem -{ - return *(const Fl_Menu_Item **)[(NSData*)[self representedObject] bytes]; -} -- (void) doCallback:(id)unused -{ - fl_lock_function(); - const Fl_Menu_Item *item = [self getFlItem]; - fl_sys_menu_bar->picked(item); - if ( item->flags & FL_MENU_TOGGLE ) { // update the menu toggle symbol - [self setState:(item->value() ? NSOnState : NSOffState)]; - } - else if ( item->flags & FL_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 & FL_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 & FL_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(); - Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes]; - if ( item && item->callback() ) item->do_callback(NULL); - fl_unlock_function(); -} -@end - -void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut) -{ - fl_open_display(); - Fl_Menu_Item aboutItem; - memset(&aboutItem, 0, sizeof(Fl_Menu_Item)); - 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()) { - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, item, aboutItem.shortcut() & 0xff); - Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, item, aboutItem.shortcut() ); - } - NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)]; - [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 *Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::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 == Fl_Sys_Menu_Bar::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 == Fl_Sys_Menu_Bar::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 == Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask) { // arguments: NSMenuItem*, int - item = va_arg(ap, NSMenuItem*); - value = va_arg(ap, int); - NSUInteger macMod = 0; - if ( value & FL_META ) macMod = NSCommandKeyMask; - if ( value & FL_SHIFT || isupper(value) ) macMod |= NSShiftKeyMask; - if ( value & FL_ALT ) macMod |= NSAlternateKeyMask; - if ( value & FL_CTRL ) macMod |= NSControlKeyMask; - [item setKeyEquivalentModifierMask:macMod]; - } - else if (operation == Fl_Sys_Menu_Bar::setState) { // arguments: NSMenuItem*, int - item = va_arg(ap, NSMenuItem*); - value = va_arg(ap, int); - [item setState:(value ? NSOnState : NSOffState)]; - } - else if (operation == Fl_Sys_Menu_Bar::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 == Fl_Sys_Menu_Bar::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 == Fl_Sys_Menu_Bar::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 == Fl_Sys_Menu_Bar::setEnabled) { // arguments: NSMenuItem*, int - item = va_arg(ap, NSMenuItem*); - value = va_arg(ap, int); - [item setEnabled:(value ? YES : NO)]; - } - else if (operation == Fl_Sys_Menu_Bar::addSeparatorItem) { // arguments: NSMenu* - menu = va_arg(ap, NSMenu*); - [menu addItem:[NSMenuItem separatorItem]]; - } - else if (operation == Fl_Sys_Menu_Bar::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 == Fl_Sys_Menu_Bar::removeItem) { // arguments: NSMenu*, int - menu = va_arg(ap, NSMenu*); - value = va_arg(ap, int); - [menu removeItem:[menu itemAtIndex:value]]; - } - else if (operation == Fl_Sys_Menu_Bar::addNewItem) { // arguments: NSMenu *menu, Fl_Menu_Item* mitem, int *prank - // creates a new menu item at the end of 'menu' - // attaches the item of fl_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*); - Fl_Menu_Item *mitem = va_arg(ap, Fl_Menu_Item *); - 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(Fl_Menu_Item*)]; - [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() { diff --git a/src/Makefile b/src/Makefile index 3098f19bb..e9e2aa248 100644 --- a/src/Makefile +++ b/src/Makefile @@ -49,7 +49,6 @@ CPPFILES = \ Fl_Menu.cxx \ Fl_Menu_.cxx \ Fl_Menu_Bar.cxx \ - Fl_Sys_Menu_Bar.cxx \ Fl_Menu_Button.cxx \ Fl_Menu_Window.cxx \ Fl_Menu_add.cxx \ @@ -161,7 +160,8 @@ CPPFILES = \ OBJCPPFILES = \ Fl_cocoa.mm \ Fl_Quartz_Printer.mm \ - Fl_Native_File_Chooser_MAC.mm + Fl_Native_File_Chooser_MAC.mm \ + Fl_Sys_Menu_Bar.mm FLCPPFILES = \ forms_compatability.cxx \ |
