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
This commit is contained in:
parent
b176f4d3f6
commit
6b69461ea9
1
FL/mac.H
1
FL/mac.H
@ -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:
|
||||
|
||||
@ -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 */,
|
||||
|
||||
@ -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 */,
|
||||
|
||||
@ -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$".
|
||||
//
|
||||
437
src/Fl_Sys_Menu_Bar.mm
Normal file
437
src/Fl_Sys_Menu_Bar.mm
Normal file
@ -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$".
|
||||
//
|
||||
215
src/Fl_cocoa.mm
215
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()
|
||||
{
|
||||
|
||||
@ -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 \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user