| @@ -127,6 +127,7 @@ OBJECTS := \ | |||
| $(OBJDIR)/juce_Component_49f01dfa.o \ | |||
| $(OBJDIR)/juce_ComponentListener_e0eda7ce.o \ | |||
| $(OBJDIR)/juce_Desktop_e3b47b99.o \ | |||
| $(OBJDIR)/juce_ModalComponentManager_b87bddba.o \ | |||
| $(OBJDIR)/juce_ArrowButton_ebac7066.o \ | |||
| $(OBJDIR)/juce_Button_886d3491.o \ | |||
| $(OBJDIR)/juce_DrawableButton_e03899cf.o \ | |||
| @@ -793,6 +794,11 @@ $(OBJDIR)/juce_Desktop_e3b47b99.o: ../../src/gui/components/juce_Desktop.cpp | |||
| @echo "Compiling juce_Desktop.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_ModalComponentManager_b87bddba.o: ../../src/gui/components/juce_ModalComponentManager.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_ModalComponentManager.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_ArrowButton_ebac7066.o: ../../src/gui/components/buttons/juce_ArrowButton.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_ArrowButton.cpp" | |||
| @@ -96,6 +96,7 @@ | |||
| 621B7B0B518E63E69122C13E = { isa = PBXBuildFile; fileRef = D0D9267E200BD462361810F7; }; | |||
| 97982824572C18827047D92A = { isa = PBXBuildFile; fileRef = E13F33E386E1A0D5FC546521; }; | |||
| 927E7250FCE62E838599DF83 = { isa = PBXBuildFile; fileRef = 621B3A4B154182F69DDE2989; }; | |||
| 9AE6891C35CE161CB1707B4B = { isa = PBXBuildFile; fileRef = 2FFF9AFE4BD9437CE096E52B; }; | |||
| 06994A713C38F415C4E8A009 = { isa = PBXBuildFile; fileRef = 18EE6576A9ED098632CE5155; }; | |||
| 98F737B7459895BFCDC7965E = { isa = PBXBuildFile; fileRef = 8B1C747E63EEF036AD9AF3D8; }; | |||
| 7033A0968B1C81A821CCC296 = { isa = PBXBuildFile; fileRef = 1C3D15546065C1A9AA5AA0C6; }; | |||
| @@ -550,6 +551,8 @@ | |||
| A0D6308567AAA50D1163D9D3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentListener.h; path = ../../src/gui/components/juce_ComponentListener.h; sourceTree = SOURCE_ROOT; }; | |||
| 621B3A4B154182F69DDE2989 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Desktop.cpp; path = ../../src/gui/components/juce_Desktop.cpp; sourceTree = SOURCE_ROOT; }; | |||
| A1F58C1A972425C2B43DD1B3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Desktop.h; path = ../../src/gui/components/juce_Desktop.h; sourceTree = SOURCE_ROOT; }; | |||
| 2FFF9AFE4BD9437CE096E52B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ModalComponentManager.cpp; path = ../../src/gui/components/juce_ModalComponentManager.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 41C8C324F13ADA3423FC3B0F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ModalComponentManager.h; path = ../../src/gui/components/juce_ModalComponentManager.h; sourceTree = SOURCE_ROOT; }; | |||
| 18EE6576A9ED098632CE5155 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ArrowButton.cpp; path = ../../src/gui/components/buttons/juce_ArrowButton.cpp; sourceTree = SOURCE_ROOT; }; | |||
| EB182DC4124FEFFFC87D12C4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ArrowButton.h; path = ../../src/gui/components/buttons/juce_ArrowButton.h; sourceTree = SOURCE_ROOT; }; | |||
| 8B1C747E63EEF036AD9AF3D8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Button.cpp; path = ../../src/gui/components/buttons/juce_Button.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1455,6 +1458,8 @@ | |||
| A0D6308567AAA50D1163D9D3, | |||
| 621B3A4B154182F69DDE2989, | |||
| A1F58C1A972425C2B43DD1B3, | |||
| 2FFF9AFE4BD9437CE096E52B, | |||
| 41C8C324F13ADA3423FC3B0F, | |||
| 2DB55F83F4310F0C4E4E03AA, | |||
| 17B11D96CDB313ED60D8CFE0, | |||
| BCB2FFE7C2A4084A267F57F2, | |||
| @@ -1930,6 +1935,7 @@ | |||
| 621B7B0B518E63E69122C13E, | |||
| 97982824572C18827047D92A, | |||
| 927E7250FCE62E838599DF83, | |||
| 9AE6891C35CE161CB1707B4B, | |||
| 06994A713C38F415C4E8A009, | |||
| 98F737B7459895BFCDC7965E, | |||
| 7033A0968B1C81A821CCC296, | |||
| @@ -349,6 +349,8 @@ | |||
| <File RelativePath="..\..\src\gui\components\juce_ComponentListener.h"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_Desktop.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_Desktop.h"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_ModalComponentManager.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_ModalComponentManager.h"/> | |||
| <Filter Name="buttons"> | |||
| <File RelativePath="..\..\src\gui\components\buttons\juce_ArrowButton.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\buttons\juce_ArrowButton.h"/> | |||
| @@ -349,6 +349,8 @@ | |||
| <File RelativePath="..\..\src\gui\components\juce_ComponentListener.h"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_Desktop.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_Desktop.h"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_ModalComponentManager.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_ModalComponentManager.h"/> | |||
| <Filter Name="buttons"> | |||
| <File RelativePath="..\..\src\gui\components\buttons\juce_ArrowButton.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\buttons\juce_ArrowButton.h"/> | |||
| @@ -351,6 +351,8 @@ | |||
| <File RelativePath="..\..\src\gui\components\juce_ComponentListener.h"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_Desktop.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_Desktop.h"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_ModalComponentManager.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\juce_ModalComponentManager.h"/> | |||
| <Filter Name="buttons"> | |||
| <File RelativePath="..\..\src\gui\components\buttons\juce_ArrowButton.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\buttons\juce_ArrowButton.h"/> | |||
| @@ -210,6 +210,7 @@ | |||
| <ClCompile Include="..\..\src\gui\components\juce_Component.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\components\juce_ComponentListener.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\components\juce_Desktop.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\components\juce_ModalComponentManager.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\components\buttons\juce_ArrowButton.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\components\buttons\juce_Button.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\components\buttons\juce_DrawableButton.cpp"/> | |||
| @@ -549,6 +550,7 @@ | |||
| <ClInclude Include="..\..\src\gui\components\juce_Component.h"/> | |||
| <ClInclude Include="..\..\src\gui\components\juce_ComponentListener.h"/> | |||
| <ClInclude Include="..\..\src\gui\components\juce_Desktop.h"/> | |||
| <ClInclude Include="..\..\src\gui\components\juce_ModalComponentManager.h"/> | |||
| <ClInclude Include="..\..\src\gui\components\buttons\juce_ArrowButton.h"/> | |||
| <ClInclude Include="..\..\src\gui\components\buttons\juce_Button.h"/> | |||
| <ClInclude Include="..\..\src\gui\components\buttons\juce_DrawableButton.h"/> | |||
| @@ -430,6 +430,9 @@ | |||
| <ClCompile Include="..\..\src\gui\components\juce_Desktop.cpp"> | |||
| <Filter>Juce\Source\gui\components</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\src\gui\components\juce_ModalComponentManager.cpp"> | |||
| <Filter>Juce\Source\gui\components</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\src\gui\components\buttons\juce_ArrowButton.cpp"> | |||
| <Filter>Juce\Source\gui\components\buttons</Filter> | |||
| </ClCompile> | |||
| @@ -1521,6 +1524,9 @@ | |||
| <ClInclude Include="..\..\src\gui\components\juce_Desktop.h"> | |||
| <Filter>Juce\Source\gui\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\gui\components\juce_ModalComponentManager.h"> | |||
| <Filter>Juce\Source\gui\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\gui\components\buttons\juce_ArrowButton.h"> | |||
| <Filter>Juce\Source\gui\components\buttons</Filter> | |||
| </ClInclude> | |||
| @@ -96,6 +96,7 @@ | |||
| 621B7B0B518E63E69122C13E = { isa = PBXBuildFile; fileRef = D0D9267E200BD462361810F7; }; | |||
| 97982824572C18827047D92A = { isa = PBXBuildFile; fileRef = E13F33E386E1A0D5FC546521; }; | |||
| 927E7250FCE62E838599DF83 = { isa = PBXBuildFile; fileRef = 621B3A4B154182F69DDE2989; }; | |||
| 9AE6891C35CE161CB1707B4B = { isa = PBXBuildFile; fileRef = 2FFF9AFE4BD9437CE096E52B; }; | |||
| 06994A713C38F415C4E8A009 = { isa = PBXBuildFile; fileRef = 18EE6576A9ED098632CE5155; }; | |||
| 98F737B7459895BFCDC7965E = { isa = PBXBuildFile; fileRef = 8B1C747E63EEF036AD9AF3D8; }; | |||
| 7033A0968B1C81A821CCC296 = { isa = PBXBuildFile; fileRef = 1C3D15546065C1A9AA5AA0C6; }; | |||
| @@ -550,6 +551,8 @@ | |||
| A0D6308567AAA50D1163D9D3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentListener.h; path = ../../src/gui/components/juce_ComponentListener.h; sourceTree = SOURCE_ROOT; }; | |||
| 621B3A4B154182F69DDE2989 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Desktop.cpp; path = ../../src/gui/components/juce_Desktop.cpp; sourceTree = SOURCE_ROOT; }; | |||
| A1F58C1A972425C2B43DD1B3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Desktop.h; path = ../../src/gui/components/juce_Desktop.h; sourceTree = SOURCE_ROOT; }; | |||
| 2FFF9AFE4BD9437CE096E52B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ModalComponentManager.cpp; path = ../../src/gui/components/juce_ModalComponentManager.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 41C8C324F13ADA3423FC3B0F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ModalComponentManager.h; path = ../../src/gui/components/juce_ModalComponentManager.h; sourceTree = SOURCE_ROOT; }; | |||
| 18EE6576A9ED098632CE5155 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ArrowButton.cpp; path = ../../src/gui/components/buttons/juce_ArrowButton.cpp; sourceTree = SOURCE_ROOT; }; | |||
| EB182DC4124FEFFFC87D12C4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ArrowButton.h; path = ../../src/gui/components/buttons/juce_ArrowButton.h; sourceTree = SOURCE_ROOT; }; | |||
| 8B1C747E63EEF036AD9AF3D8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Button.cpp; path = ../../src/gui/components/buttons/juce_Button.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1455,6 +1458,8 @@ | |||
| A0D6308567AAA50D1163D9D3, | |||
| 621B3A4B154182F69DDE2989, | |||
| A1F58C1A972425C2B43DD1B3, | |||
| 2FFF9AFE4BD9437CE096E52B, | |||
| 41C8C324F13ADA3423FC3B0F, | |||
| 2DB55F83F4310F0C4E4E03AA, | |||
| 17B11D96CDB313ED60D8CFE0, | |||
| BCB2FFE7C2A4084A267F57F2, | |||
| @@ -1930,6 +1935,7 @@ | |||
| 621B7B0B518E63E69122C13E, | |||
| 97982824572C18827047D92A, | |||
| 927E7250FCE62E838599DF83, | |||
| 9AE6891C35CE161CB1707B4B, | |||
| 06994A713C38F415C4E8A009, | |||
| 98F737B7459895BFCDC7965E, | |||
| 7033A0968B1C81A821CCC296, | |||
| @@ -495,6 +495,10 @@ | |||
| file="src/gui/components/juce_Desktop.cpp"/> | |||
| <FILE id="kteq7JUyy" name="juce_Desktop.h" compile="0" resource="0" | |||
| file="src/gui/components/juce_Desktop.h"/> | |||
| <FILE id="OSpcyIq" name="juce_ModalComponentManager.cpp" compile="1" | |||
| resource="0" file="src/gui/components/juce_ModalComponentManager.cpp"/> | |||
| <FILE id="hHLSn88" name="juce_ModalComponentManager.h" compile="0" | |||
| resource="0" file="src/gui/components/juce_ModalComponentManager.h"/> | |||
| <GROUP id="bZKiEBSYn" name="buttons"> | |||
| <FILE id="XWJvOnuh3" name="juce_ArrowButton.cpp" compile="1" resource="0" | |||
| file="src/gui/components/buttons/juce_ArrowButton.cpp"/> | |||
| @@ -223,6 +223,7 @@ | |||
| #include "../src/gui/components/juce_Component.cpp" | |||
| #include "../src/gui/components/juce_ComponentListener.cpp" | |||
| #include "../src/gui/components/juce_Desktop.cpp" | |||
| #include "../src/gui/components/juce_ModalComponentManager.cpp" | |||
| #include "../src/gui/components/buttons/juce_ArrowButton.cpp" | |||
| #include "../src/gui/components/buttons/juce_Button.cpp" | |||
| #include "../src/gui/components/buttons/juce_DrawableButton.cpp" | |||
| @@ -1184,7 +1184,7 @@ protected: | |||
| const String getProjectType() const | |||
| { | |||
| if (project.isGUIApplication()) | |||
| if (project.isGUIApplication() || project.isCommandLineApp()) | |||
| return "Application"; | |||
| else if (project.isAudioPlugin() || project.isBrowserPlugin()) | |||
| return "DynamicLibrary"; | |||
| @@ -13,12 +13,12 @@ | |||
| jucerVersion="3.0.0"> | |||
| <EXPORTFORMATS> | |||
| <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK" | |||
| juceFolder="../../../juce"/> | |||
| juceFolder="../.."/> | |||
| <VS2005 targetFolder="Builds/VisualStudio2005" vstFolder="c:\SDKs\vstsdk2.4" | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce"/> | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/> | |||
| <VS2008 targetFolder="Builds/VisualStudio2008" vstFolder="c:\SDKs\vstsdk2.4" | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce"/> | |||
| <LINUX_MAKE targetFolder="Builds/Linux" vstFolder="~/SDKs/vstsdk2.4" juceFolder="../../../juce"/> | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/> | |||
| <LINUX_MAKE targetFolder="Builds/Linux" vstFolder="~/SDKs/vstsdk2.4" juceFolder="../.."/> | |||
| </EXPORTFORMATS> | |||
| <CONFIGURATIONS> | |||
| <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="Plugin Host" | |||
| @@ -11,11 +11,11 @@ | |||
| bundleIdentifier="com.rawmaterialsoftware.JuceDemoPlugin" jucerVersion="3.0.0"> | |||
| <EXPORTFORMATS> | |||
| <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK" | |||
| juceFolder="../../../../juce" objCExtraSuffix="JuceDemo"/> | |||
| juceFolder="../../.." objCExtraSuffix="JuceDemo"/> | |||
| <VS2005 targetFolder="Builds/VisualStudio2005" vstFolder="c:\SDKs\vstsdk2.4" | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../../juce"/> | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../.." libraryType="1"/> | |||
| <VS2008 targetFolder="Builds/VisualStudio2008" vstFolder="c:\SDKs\vstsdk2.4" | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../../juce"/> | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../.." libraryType="1"/> | |||
| </EXPORTFORMATS> | |||
| <CONFIGURATIONS> | |||
| <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="JuceDemoPlugin" | |||
| @@ -12,14 +12,14 @@ | |||
| pluginAUViewClass="HelloWorldAU_V1" pluginRTASCategory="" bundleIdentifier="com.rawmaterialsoftware.jucehelloworld"> | |||
| <EXPORTFORMATS> | |||
| <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK" | |||
| juceFolder="../../../juce"/> | |||
| juceFolder="../.."/> | |||
| <XCODE_IPHONE targetFolder="Builds/iPhone" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK" | |||
| juceFolder="../../../juce"/> | |||
| juceFolder="../.."/> | |||
| <VS2005 targetFolder="Builds/VisualStudio2005" vstFolder="c:\SDKs\vstsdk2.4" | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce"/> | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/> | |||
| <VS2008 targetFolder="Builds/VisualStudio2008" vstFolder="c:\SDKs\vstsdk2.4" | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce"/> | |||
| <LINUX_MAKE targetFolder="Builds/Linux" vstFolder="~/SDKs/vstsdk2.4" juceFolder="../../../juce"/> | |||
| rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/> | |||
| <LINUX_MAKE targetFolder="Builds/Linux" vstFolder="~/SDKs/vstsdk2.4" juceFolder="../.."/> | |||
| </EXPORTFORMATS> | |||
| <CONFIGURATIONS> | |||
| <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="HelloWorld" | |||
| @@ -64,7 +64,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 19 | |||
| #define JUCE_BUILDNUMBER 20 | |||
| /** Current Juce version number. | |||
| @@ -14254,7 +14254,7 @@ private: | |||
| static classname* _singletonInstance; \ | |||
| static JUCE_NAMESPACE::CriticalSection _singletonLock; \ | |||
| \ | |||
| static classname* getInstance() \ | |||
| static classname* JUCE_CALLTYPE getInstance() \ | |||
| { \ | |||
| if (_singletonInstance == 0) \ | |||
| {\ | |||
| @@ -14282,12 +14282,12 @@ private: | |||
| return _singletonInstance; \ | |||
| } \ | |||
| \ | |||
| static inline classname* getInstanceWithoutCreating() throw() \ | |||
| static inline classname* JUCE_CALLTYPE getInstanceWithoutCreating() throw() \ | |||
| { \ | |||
| return _singletonInstance; \ | |||
| } \ | |||
| \ | |||
| static void deleteInstance() \ | |||
| static void JUCE_CALLTYPE deleteInstance() \ | |||
| { \ | |||
| const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \ | |||
| if (_singletonInstance != 0) \ | |||
| @@ -24927,6 +24927,167 @@ private: | |||
| #endif // __JUCE_BORDERSIZE_JUCEHEADER__ | |||
| /*** End of inlined file: juce_BorderSize.h ***/ | |||
| /*** Start of inlined file: juce_ModalComponentManager.h ***/ | |||
| #ifndef __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| #define __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| /*** Start of inlined file: juce_DeletedAtShutdown.h ***/ | |||
| #ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ | |||
| #define __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ | |||
| /** | |||
| Classes derived from this will be automatically deleted when the application exits. | |||
| After JUCEApplication::shutdown() has been called, any objects derived from | |||
| DeletedAtShutdown which are still in existence will be deleted in the reverse | |||
| order to that in which they were created. | |||
| So if you've got a singleton and don't want to have to explicitly delete it, just | |||
| inherit from this and it'll be taken care of. | |||
| */ | |||
| class JUCE_API DeletedAtShutdown | |||
| { | |||
| protected: | |||
| /** Creates a DeletedAtShutdown object. */ | |||
| DeletedAtShutdown(); | |||
| /** Destructor. | |||
| It's ok to delete these objects explicitly - it's only the ones left | |||
| dangling at the end that will be deleted automatically. | |||
| */ | |||
| virtual ~DeletedAtShutdown(); | |||
| public: | |||
| /** Deletes all extant objects. | |||
| This shouldn't be used by applications, as it's called automatically | |||
| in the shutdown code of the JUCEApplication class. | |||
| */ | |||
| static void deleteAll(); | |||
| private: | |||
| DeletedAtShutdown (const DeletedAtShutdown&); | |||
| DeletedAtShutdown& operator= (const DeletedAtShutdown&); | |||
| static CriticalSection& getLock(); | |||
| static Array <DeletedAtShutdown*>& getObjects(); | |||
| }; | |||
| #endif // __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ | |||
| /*** End of inlined file: juce_DeletedAtShutdown.h ***/ | |||
| /** | |||
| Manages the system's stack of modal components. | |||
| Normally you'll just use the Component methods to invoke modal states in components, | |||
| and won't have to deal with this class directly, but this is the singleton object that's | |||
| used internally to manage the stack. | |||
| @see Component::enterModalState, Component::exitModalState, Component::isCurrentlyModal, | |||
| Component::getCurrentlyModalComponent, Component::isCurrentlyBlockedByAnotherModalComponent | |||
| */ | |||
| class JUCE_API ModalComponentManager : public AsyncUpdater, | |||
| public DeletedAtShutdown | |||
| { | |||
| public: | |||
| /** Receives callbacks when a modal component is dismissed. | |||
| You can register a callback using Component::enterModalState() or | |||
| ModalComponentManager::attachCallback(). | |||
| */ | |||
| class Callback | |||
| { | |||
| public: | |||
| /** */ | |||
| Callback() {} | |||
| /** Destructor. */ | |||
| virtual ~Callback() {} | |||
| /** Called to indicate that a modal component has been dismissed. | |||
| You can register a callback using Component::enterModalState() or | |||
| ModalComponentManager::attachCallback(). | |||
| The returnValue parameter is the value that was passed to Component::exitModalState() | |||
| when the component was dismissed. | |||
| The callback object will be deleted shortly after this method is called. | |||
| */ | |||
| virtual void modalStateFinished (int returnValue) = 0; | |||
| }; | |||
| /** Returns the number of components currently being shown modally. | |||
| @see getModalComponent | |||
| */ | |||
| int getNumModalComponents() const; | |||
| /** Returns one of the components being shown modally. | |||
| An index of 0 is the most recently-shown, topmost component. | |||
| */ | |||
| Component* getModalComponent (int index) const; | |||
| /** Returns true if the specified component is in a modal state. */ | |||
| bool isModal (Component* component) const; | |||
| /** Returns true if the specified component is currently the topmost modal component. */ | |||
| bool isFrontModalComponent (Component* component) const; | |||
| /** Adds a new callback that will be called when the specified modal component is dismissed. | |||
| If the component is modal, then when it is dismissed, either by being hidden, or by calling | |||
| Component::exitModalState(), then the Callback::modalStateFinished() method will be | |||
| called. | |||
| Each component can have any number of callbacks associated with it, and this one is added | |||
| to that list. | |||
| The object that is passed in will be deleted by the manager when it's no longer needed. If | |||
| the given component is not currently modal, the callback object is deleted immediately and | |||
| no action is taken. | |||
| */ | |||
| void attachCallback (Component* component, Callback* callback); | |||
| /** Runs the event loop until the currently topmost modal component is dismissed, and | |||
| returns the exit code for that component. | |||
| */ | |||
| int runEventLoopForCurrentComponent(); | |||
| juce_DeclareSingleton_SingleThreaded_Minimal (ModalComponentManager); | |||
| protected: | |||
| /** Creates a ModalComponentManager. | |||
| You shouldn't ever call the constructor - it's a singleton, so use ModalComponentManager::getInstance() | |||
| */ | |||
| ModalComponentManager(); | |||
| /** Destructor. */ | |||
| ~ModalComponentManager(); | |||
| /** @internal */ | |||
| void handleAsyncUpdate(); | |||
| private: | |||
| class ModalItem; | |||
| class ReturnValueRetriever; | |||
| friend class Component; | |||
| friend class OwnedArray <ModalItem>; | |||
| OwnedArray <ModalItem> stack; | |||
| void startModal (Component* component, Callback* callback); | |||
| void endModal (Component* component, int returnValue); | |||
| void endModal (Component* component); | |||
| }; | |||
| #endif // __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| /*** End of inlined file: juce_ModalComponentManager.h ***/ | |||
| class LookAndFeel; | |||
| class MouseInputSource; | |||
| class MouseInputSourceInternal; | |||
| @@ -26576,7 +26737,7 @@ public: | |||
| passed into exitModalState(). | |||
| @see enterModalState, exitModalState, isCurrentlyModal, getCurrentlyModalComponent, | |||
| isCurrentlyBlockedByAnotherModalComponent, MessageManager::dispatchNextMessage | |||
| isCurrentlyBlockedByAnotherModalComponent, ModalComponentManager | |||
| */ | |||
| int runModalLoop(); | |||
| @@ -26590,9 +26751,15 @@ public: | |||
| get the focus, which is usually what you'll want it to do. If not, it will leave | |||
| the focus unchanged. | |||
| @see exitModalState, runModalLoop | |||
| The callback is an optional object which will receive a callback when the modal | |||
| component loses its modal status, either by being hidden or when exitModalState() | |||
| is called. If you pass an object in here, the system will take care of deleting it | |||
| later, after making the callback | |||
| @see exitModalState, runModalLoop, ModalComponentManager::attachCallback | |||
| */ | |||
| void enterModalState (bool takeKeyboardFocus = true); | |||
| void enterModalState (bool takeKeyboardFocus = true, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| /** Ends a component's modal state. | |||
| @@ -27717,53 +27884,6 @@ public: | |||
| #define __JUCE_DESKTOP_JUCEHEADER__ | |||
| /*** Start of inlined file: juce_DeletedAtShutdown.h ***/ | |||
| #ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ | |||
| #define __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ | |||
| /** | |||
| Classes derived from this will be automatically deleted when the application exits. | |||
| After JUCEApplication::shutdown() has been called, any objects derived from | |||
| DeletedAtShutdown which are still in existence will be deleted in the reverse | |||
| order to that in which they were created. | |||
| So if you've got a singleton and don't want to have to explicitly delete it, just | |||
| inherit from this and it'll be taken care of. | |||
| */ | |||
| class JUCE_API DeletedAtShutdown | |||
| { | |||
| protected: | |||
| /** Creates a DeletedAtShutdown object. */ | |||
| DeletedAtShutdown(); | |||
| /** Destructor. | |||
| It's ok to delete these objects explicitly - it's only the ones left | |||
| dangling at the end that will be deleted automatically. | |||
| */ | |||
| virtual ~DeletedAtShutdown(); | |||
| public: | |||
| /** Deletes all extant objects. | |||
| This shouldn't be used by applications, as it's called automatically | |||
| in the shutdown code of the JUCEApplication class. | |||
| */ | |||
| static void deleteAll(); | |||
| private: | |||
| DeletedAtShutdown (const DeletedAtShutdown&); | |||
| DeletedAtShutdown& operator= (const DeletedAtShutdown&); | |||
| static CriticalSection& getLock(); | |||
| static Array <DeletedAtShutdown*>& getObjects(); | |||
| }; | |||
| #endif // __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ | |||
| /*** End of inlined file: juce_DeletedAtShutdown.h ***/ | |||
| /*** Start of inlined file: juce_Timer.h ***/ | |||
| #ifndef __JUCE_TIMER_JUCEHEADER__ | |||
| #define __JUCE_TIMER_JUCEHEADER__ | |||
| @@ -34964,12 +35084,19 @@ public: | |||
| in zero. | |||
| @param standardItemHeight if this is non-zero, it will be used as the standard | |||
| height for menu items (apart from custom items) | |||
| @param callback if this is non-zero, the menu will be launched asynchronously, | |||
| returning immediately, and the callback will receive a | |||
| call when the menu is either dismissed or has an item | |||
| selected. This object will be owned and deleted by the | |||
| system, so make sure that it works safely and that any | |||
| pointers that it uses are safely within scope. | |||
| @see showAt | |||
| */ | |||
| int show (int itemIdThatMustBeVisible = 0, | |||
| int minimumWidth = 0, | |||
| int maximumNumColumns = 0, | |||
| int standardItemHeight = 0); | |||
| int standardItemHeight = 0, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| /** Displays the menu at a specific location. | |||
| @@ -34987,7 +35114,8 @@ public: | |||
| int itemIdThatMustBeVisible = 0, | |||
| int minimumWidth = 0, | |||
| int maximumNumColumns = 0, | |||
| int standardItemHeight = 0); | |||
| int standardItemHeight = 0, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| /** Displays the menu as if it's attached to a component such as a button. | |||
| @@ -34999,7 +35127,8 @@ public: | |||
| int itemIdThatMustBeVisible = 0, | |||
| int minimumWidth = 0, | |||
| int maximumNumColumns = 0, | |||
| int standardItemHeight = 0); | |||
| int standardItemHeight = 0, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| /** Closes any menus that are currently open. | |||
| @@ -35098,6 +35227,7 @@ private: | |||
| friend class ItemComponent; | |||
| friend class Window; | |||
| friend class PopupMenuCustomComponent; | |||
| friend class MenuBarComponent; | |||
| friend class OwnedArray <Item>; | |||
| friend class ScopedPointer <Window>; | |||
| @@ -35107,16 +35237,16 @@ private: | |||
| void addSeparatorIfPending(); | |||
| int showMenu (int x, int y, int w, int h, | |||
| int showMenu (const Rectangle<int>& target, | |||
| int itemIdThatMustBeVisible, | |||
| int minimumWidth, | |||
| int maximumNumColumns, | |||
| int standardItemHeight, | |||
| bool alignToRectangle, | |||
| Component* componentAttachedTo); | |||
| Component* componentAttachedTo, | |||
| ModalComponentManager::Callback* callback); | |||
| friend class MenuBarComponent; | |||
| Component* createMenuComponent (int x, int y, int w, int h, | |||
| Component* createMenuComponent (const Rectangle<int>& target, | |||
| int itemIdThatMustBeVisible, | |||
| int minimumWidth, | |||
| int maximumNumColumns, | |||
| @@ -35660,10 +35790,6 @@ public: | |||
| /** @internal */ | |||
| bool isTextInputActive() const; | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| /** This adds the items to the popup menu. | |||
| By default it adds the cut/copy/paste items, but you can override this if | |||
| @@ -35701,6 +35827,10 @@ protected: | |||
| */ | |||
| virtual void performPopupMenuAction (int menuItemID); | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| /** Scrolls the minimum distance needed to get the caret into view. */ | |||
| void scrollToMakeSureCursorIsVisible(); | |||
| @@ -36462,6 +36592,9 @@ private: | |||
| bool isRealItem() const throw(); | |||
| }; | |||
| class Callback; | |||
| friend class Callback; | |||
| OwnedArray <ItemInfo> items; | |||
| Value currentId; | |||
| int lastCurrentId; | |||
| @@ -50012,7 +50145,16 @@ public: | |||
| Leave the width or height as 0 to use the default size | |||
| */ | |||
| bool show (int width = 0,int height = 0); | |||
| bool show (int width = 0, int height = 0); | |||
| /** Displays and runs the dialog box modally. | |||
| This will show the box with the specified size at the specified location, | |||
| returning true if the user pressed 'ok', or false if they cancelled. | |||
| Leave the width or height as 0 to use the default size. | |||
| */ | |||
| bool showAt (int x, int y, int width, int height); | |||
| /** A set of colour IDs to use to change the colour of various aspects of the box. | |||
| @@ -50628,6 +50770,9 @@ private: | |||
| #endif | |||
| #ifndef __JUCE_DESKTOP_JUCEHEADER__ | |||
| #endif | |||
| #ifndef __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| #endif | |||
| #ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__ | |||
| @@ -51809,6 +51954,10 @@ public: | |||
| */ | |||
| void setModel (MenuBarModel* newModel); | |||
| /** Returns the current menu bar model being used. | |||
| */ | |||
| MenuBarModel* getModel() const throw(); | |||
| /** Pops up one of the menu items. | |||
| This lets you manually open one of the menus - it could be triggered by a | |||
| @@ -51833,8 +51982,6 @@ public: | |||
| /** @internal */ | |||
| void mouseMove (const MouseEvent& e); | |||
| /** @internal */ | |||
| void inputAttemptWhenModal(); | |||
| /** @internal */ | |||
| void handleCommandMessage (int commandId); | |||
| /** @internal */ | |||
| bool keyPressed (const KeyPress& key); | |||
| @@ -51847,20 +51994,22 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class AsyncCallback; | |||
| friend class AsyncCallback; | |||
| MenuBarModel* model; | |||
| StringArray menuNames; | |||
| Array <int> xPositions; | |||
| int itemUnderMouse, currentPopupIndex, topLevelIndexClicked, indexToShowAgain; | |||
| int itemUnderMouse, currentPopupIndex, topLevelIndexClicked; | |||
| int lastMouseX, lastMouseY; | |||
| bool inModalState; | |||
| ScopedPointer <Component> currentPopup; | |||
| int getItemAt (int x, int y); | |||
| void setItemUnderMouse (int index); | |||
| void setOpenItem (int index); | |||
| void updateItemUnderMouse (int x, int y); | |||
| void hideCurrentMenu(); | |||
| void timerCallback(); | |||
| void repaintMenuItem (int index); | |||
| void menuDismissed (int topLevelIndex, int itemId); | |||
| MenuBarComponent (const MenuBarComponent&); | |||
| MenuBarComponent& operator= (const MenuBarComponent&); | |||
| @@ -93,7 +93,7 @@ | |||
| static classname* _singletonInstance; \ | |||
| static JUCE_NAMESPACE::CriticalSection _singletonLock; \ | |||
| \ | |||
| static classname* getInstance() \ | |||
| static classname* JUCE_CALLTYPE getInstance() \ | |||
| { \ | |||
| if (_singletonInstance == 0) \ | |||
| {\ | |||
| @@ -121,12 +121,12 @@ | |||
| return _singletonInstance; \ | |||
| } \ | |||
| \ | |||
| static inline classname* getInstanceWithoutCreating() throw() \ | |||
| static inline classname* JUCE_CALLTYPE getInstanceWithoutCreating() throw() \ | |||
| { \ | |||
| return _singletonInstance; \ | |||
| } \ | |||
| \ | |||
| static void deleteInstance() \ | |||
| static void JUCE_CALLTYPE deleteInstance() \ | |||
| { \ | |||
| const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \ | |||
| if (_singletonInstance != 0) \ | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 19 | |||
| #define JUCE_BUILDNUMBER 20 | |||
| /** Current Juce version number. | |||
| @@ -525,15 +525,40 @@ void ComboBox::labelTextChanged (Label*) | |||
| //============================================================================== | |||
| class ComboBox::Callback : public ModalComponentManager::Callback | |||
| { | |||
| public: | |||
| Callback (ComboBox* const box_) | |||
| : box (box_) | |||
| { | |||
| } | |||
| void modalStateFinished (int returnValue) | |||
| { | |||
| if (box != 0) | |||
| { | |||
| box->menuActive = false; | |||
| if (returnValue != 0) | |||
| box->setSelectedId (returnValue); | |||
| } | |||
| } | |||
| private: | |||
| Component::SafePointer<ComboBox> box; | |||
| Callback (const Callback&); | |||
| Callback& operator= (const Callback&); | |||
| }; | |||
| void ComboBox::showPopup() | |||
| { | |||
| if (! menuActive) | |||
| { | |||
| const int selectedId = getSelectedId(); | |||
| Component::SafePointer<Component> deletionWatcher (this); | |||
| PopupMenu menu; | |||
| menu.setLookAndFeel (&getLookAndFeel()); | |||
| for (int i = 0; i < items.size(); ++i) | |||
| @@ -552,19 +577,9 @@ void ComboBox::showPopup() | |||
| if (items.size() == 0) | |||
| menu.addItem (1, noChoicesMessage, false); | |||
| const int itemHeight = jlimit (12, 24, getHeight()); | |||
| menuActive = true; | |||
| const int resultId = menu.showAt (this, selectedId, | |||
| getWidth(), 1, itemHeight); | |||
| if (deletionWatcher == 0) | |||
| return; | |||
| menuActive = false; | |||
| if (resultId != 0) | |||
| setSelectedId (resultId); | |||
| menu.showAt (this, selectedId, getWidth(), 1, jlimit (12, 24, getHeight()), | |||
| new Callback (this)); | |||
| } | |||
| } | |||
| @@ -388,6 +388,9 @@ private: | |||
| bool isRealItem() const throw(); | |||
| }; | |||
| class Callback; | |||
| friend class Callback; | |||
| OwnedArray <ItemInfo> items; | |||
| Value currentId; | |||
| int lastCurrentId; | |||
| @@ -1773,6 +1773,28 @@ void TextEditor::paintOverChildren (Graphics& g) | |||
| } | |||
| //============================================================================== | |||
| class TextEditorMenuPerformer : public ModalComponentManager::Callback | |||
| { | |||
| public: | |||
| TextEditorMenuPerformer (TextEditor* const editor_) | |||
| : editor (editor_) | |||
| { | |||
| } | |||
| void modalStateFinished (int returnValue) | |||
| { | |||
| if (editor != 0 && returnValue != 0) | |||
| editor->performPopupMenuAction (returnValue); | |||
| } | |||
| private: | |||
| Component::SafePointer<TextEditor> editor; | |||
| TextEditorMenuPerformer (const TextEditorMenuPerformer&); | |||
| TextEditorMenuPerformer& operator= (const TextEditorMenuPerformer&); | |||
| }; | |||
| void TextEditor::mouseDown (const MouseEvent& e) | |||
| { | |||
| beginDragAutoRepeat (100); | |||
| @@ -1791,12 +1813,7 @@ void TextEditor::mouseDown (const MouseEvent& e) | |||
| m.setLookAndFeel (&getLookAndFeel()); | |||
| addPopupMenuItems (m, &e); | |||
| menuActive = true; | |||
| const int result = m.show(); | |||
| menuActive = false; | |||
| if (result != 0) | |||
| performPopupMenuAction (result); | |||
| m.show (0, 0, 0, 0, new TextEditorMenuPerformer (this)); | |||
| } | |||
| } | |||
| } | |||
| @@ -2221,7 +2238,7 @@ void TextEditor::enablementChanged() | |||
| //============================================================================== | |||
| UndoManager* TextEditor::getUndoManager() throw() | |||
| { | |||
| return isReadOnly() ? &undoManager : 0; | |||
| return isReadOnly() ? 0 : &undoManager; | |||
| } | |||
| void TextEditor::clearInternal (UndoManager* const um) | |||
| @@ -538,9 +538,6 @@ public: | |||
| /** @internal */ | |||
| bool isTextInputActive() const; | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| //============================================================================== | |||
| /** This adds the items to the popup menu. | |||
| @@ -579,6 +576,10 @@ protected: | |||
| */ | |||
| virtual void performPopupMenuAction (int menuItemID); | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| //============================================================================== | |||
| /** Scrolls the minimum distance needed to get the caret into view. */ | |||
| void scrollToMakeSureCursorIsVisible(); | |||
| @@ -75,6 +75,11 @@ FileChooserDialogBox::~FileChooserDialogBox() | |||
| //============================================================================== | |||
| bool FileChooserDialogBox::show (int w, int h) | |||
| { | |||
| return showAt (-1, -1, w, h); | |||
| } | |||
| bool FileChooserDialogBox::showAt (int x, int y, int w, int h) | |||
| { | |||
| if (w <= 0) | |||
| { | |||
| @@ -88,7 +93,10 @@ bool FileChooserDialogBox::show (int w, int h) | |||
| if (h <= 0) | |||
| h = 500; | |||
| centreWithSize (w, h); | |||
| if (x < 0 || y < 0) | |||
| centreWithSize (w, h); | |||
| else | |||
| setBounds (x, y, w, h); | |||
| const bool ok = (runModalLoop() != 0); | |||
| setVisible (false); | |||
| @@ -103,8 +103,16 @@ public: | |||
| Leave the width or height as 0 to use the default size | |||
| */ | |||
| bool show (int width = 0,int height = 0); | |||
| bool show (int width = 0, int height = 0); | |||
| /** Displays and runs the dialog box modally. | |||
| This will show the box with the specified size at the specified location, | |||
| returning true if the user pressed 'ok', or false if they cancelled. | |||
| Leave the width or height as 0 to use the default size. | |||
| */ | |||
| bool showAt (int x, int y, int width, int height); | |||
| //============================================================================== | |||
| /** A set of colour IDs to use to change the colour of various aspects of the box. | |||
| @@ -39,15 +39,12 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "../../events/juce_MessageManager.h" | |||
| #include "../../events/juce_Timer.h" | |||
| #include "../../core/juce_Time.h" | |||
| #include "../../core/juce_Singleton.h" | |||
| #include "../../core/juce_PlatformUtilities.h" | |||
| #include "mouse/juce_MouseInputSource.h" | |||
| //============================================================================== | |||
| Component* Component::currentlyFocusedComponent = 0; | |||
| static Array <Component*> modalComponentStack, modalComponentReturnValueKeys; | |||
| static Array <int> modalReturnValues; | |||
| //============================================================================== | |||
| #define checkMessageManagerIsLocked jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
| enum ComponentMessageNumbers | |||
| { | |||
| @@ -55,10 +52,8 @@ enum ComponentMessageNumbers | |||
| exitModalStateMessage = 0x7fff0002 | |||
| }; | |||
| //============================================================================== | |||
| #define checkMessageManagerIsLocked jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
| static uint32 nextComponentUID = 0; | |||
| Component* Component::currentlyFocusedComponent = 0; | |||
| //============================================================================== | |||
| @@ -106,8 +101,6 @@ Component::~Component() | |||
| if (flags.hasHeavyweightPeerFlag) | |||
| removeFromDesktop(); | |||
| modalComponentStack.removeValue (this); | |||
| for (int i = childComponentList_.size(); --i >= 0;) | |||
| childComponentList_.getUnchecked(i)->parentComponent_ = 0; | |||
| @@ -1330,59 +1323,17 @@ int Component::runModalLoop() | |||
| if (! MessageManager::getInstance()->isThisTheMessageThread()) | |||
| { | |||
| // use a callback so this can be called from non-gui threads | |||
| return (int) (pointer_sized_int) | |||
| MessageManager::getInstance() | |||
| ->callFunctionOnMessageThread (&runModalLoopCallback, this); | |||
| return (int) (pointer_sized_int) MessageManager::getInstance() | |||
| ->callFunctionOnMessageThread (&runModalLoopCallback, this); | |||
| } | |||
| SafePointer<Component> prevFocused (getCurrentlyFocusedComponent()); | |||
| if (! isCurrentlyModal()) | |||
| enterModalState(); | |||
| JUCE_TRY | |||
| { | |||
| while (flags.currentlyModalFlag && flags.visibleFlag) | |||
| { | |||
| if (! MessageManager::getInstance()->runDispatchLoopUntil (20)) | |||
| break; | |||
| enterModalState (true); | |||
| // check whether this component was deleted during the last message | |||
| if (! isValidMessageListener()) | |||
| break; | |||
| } | |||
| } | |||
| #if JUCE_CATCH_UNHANDLED_EXCEPTIONS | |||
| catch (const std::exception& e) | |||
| { | |||
| JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); | |||
| return 0; | |||
| } | |||
| catch (...) | |||
| { | |||
| JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__); | |||
| return 0; | |||
| } | |||
| #endif | |||
| const int modalIndex = modalComponentReturnValueKeys.indexOf (this); | |||
| int returnValue = 0; | |||
| if (modalIndex >= 0) | |||
| { | |||
| modalComponentReturnValueKeys.remove (modalIndex); | |||
| returnValue = modalReturnValues.remove (modalIndex); | |||
| } | |||
| modalComponentStack.removeValue (this); | |||
| if (prevFocused != 0) | |||
| prevFocused->grabKeyboardFocus(); | |||
| return returnValue; | |||
| return ModalComponentManager::getInstance()->runEventLoopForCurrentComponent(); | |||
| } | |||
| void Component::enterModalState (const bool takeKeyboardFocus_) | |||
| void Component::enterModalState (const bool takeKeyboardFocus_, ModalComponentManager::Callback* const callback) | |||
| { | |||
| // if component methods are being called from threads other than the message | |||
| // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. | |||
| @@ -1394,10 +1345,7 @@ void Component::enterModalState (const bool takeKeyboardFocus_) | |||
| if (! isCurrentlyModal()) | |||
| { | |||
| modalComponentStack.add (this); | |||
| modalComponentReturnValueKeys.add (this); | |||
| modalReturnValues.add (0); | |||
| ModalComponentManager::getInstance()->startModal (this, callback); | |||
| flags.currentlyModalFlag = true; | |||
| setVisible (true); | |||
| @@ -1412,20 +1360,7 @@ void Component::exitModalState (const int returnValue) | |||
| { | |||
| if (MessageManager::getInstance()->isThisTheMessageThread()) | |||
| { | |||
| const int modalIndex = modalComponentReturnValueKeys.indexOf (this); | |||
| if (modalIndex >= 0) | |||
| { | |||
| modalReturnValues.set (modalIndex, returnValue); | |||
| } | |||
| else | |||
| { | |||
| modalComponentReturnValueKeys.add (this); | |||
| modalReturnValues.add (returnValue); | |||
| } | |||
| modalComponentStack.removeValue (this); | |||
| ModalComponentManager::getInstance()->endModal (this, returnValue); | |||
| flags.currentlyModalFlag = false; | |||
| bringModalComponentToFront(); | |||
| @@ -1455,14 +1390,12 @@ bool Component::isCurrentlyBlockedByAnotherModalComponent() const | |||
| int JUCE_CALLTYPE Component::getNumCurrentlyModalComponents() throw() | |||
| { | |||
| return modalComponentStack.size(); | |||
| return ModalComponentManager::getInstance()->getNumModalComponents(); | |||
| } | |||
| Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent (int index) throw() | |||
| { | |||
| Component* const c = static_cast <Component*> (modalComponentStack [modalComponentStack.size() - index - 1]); | |||
| return c->isValidComponent() ? c : 0; | |||
| return ModalComponentManager::getInstance()->getModalComponent (index); | |||
| } | |||
| void Component::bringModalComponentToFront() | |||
| @@ -41,6 +41,8 @@ | |||
| #include "../../text/juce_StringArray.h" | |||
| #include "../../containers/juce_Array.h" | |||
| #include "../../containers/juce_NamedValueSet.h" | |||
| #include "juce_ModalComponentManager.h" | |||
| class LookAndFeel; | |||
| class MouseInputSource; | |||
| class MouseInputSourceInternal; | |||
| @@ -1728,7 +1730,7 @@ public: | |||
| passed into exitModalState(). | |||
| @see enterModalState, exitModalState, isCurrentlyModal, getCurrentlyModalComponent, | |||
| isCurrentlyBlockedByAnotherModalComponent, MessageManager::dispatchNextMessage | |||
| isCurrentlyBlockedByAnotherModalComponent, ModalComponentManager | |||
| */ | |||
| int runModalLoop(); | |||
| @@ -1742,9 +1744,15 @@ public: | |||
| get the focus, which is usually what you'll want it to do. If not, it will leave | |||
| the focus unchanged. | |||
| @see exitModalState, runModalLoop | |||
| The callback is an optional object which will receive a callback when the modal | |||
| component loses its modal status, either by being hidden or when exitModalState() | |||
| is called. If you pass an object in here, the system will take care of deleting it | |||
| later, after making the callback | |||
| @see exitModalState, runModalLoop, ModalComponentManager::attachCallback | |||
| */ | |||
| void enterModalState (bool takeKeyboardFocus = true); | |||
| void enterModalState (bool takeKeyboardFocus = true, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| /** Ends a component's modal state. | |||
| @@ -0,0 +1,267 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-10 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "../../core/juce_StandardHeader.h" | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "juce_Component.h" | |||
| #include "juce_ModalComponentManager.h" | |||
| #include "../../events/juce_MessageManager.h" | |||
| #include "../../application/juce_Application.h" | |||
| //============================================================================== | |||
| class ModalComponentManager::ModalItem : public ComponentListener | |||
| { | |||
| public: | |||
| ModalItem (Component* const comp, Callback* const callback) | |||
| : component (comp), returnValue (0), isActive (true), isDeleted (false) | |||
| { | |||
| if (callback != 0) | |||
| callbacks.add (callback); | |||
| jassert (comp != 0); | |||
| component->addComponentListener (this); | |||
| } | |||
| ~ModalItem() | |||
| { | |||
| if (! isDeleted) | |||
| component->removeComponentListener (this); | |||
| } | |||
| void componentBeingDeleted (Component&) | |||
| { | |||
| isDeleted = true; | |||
| cancel(); | |||
| } | |||
| void componentVisibilityChanged (Component&) | |||
| { | |||
| if (! component->isShowing()) | |||
| cancel(); | |||
| } | |||
| void componentParentHierarchyChanged (Component&) | |||
| { | |||
| if (! component->isShowing()) | |||
| cancel(); | |||
| } | |||
| void cancel() | |||
| { | |||
| if (isActive) | |||
| { | |||
| isActive = false; | |||
| ModalComponentManager::getInstance()->triggerAsyncUpdate(); | |||
| } | |||
| } | |||
| Component* component; | |||
| OwnedArray<Callback> callbacks; | |||
| int returnValue; | |||
| bool isActive, isDeleted; | |||
| private: | |||
| ModalItem (const ModalItem&); | |||
| ModalItem& operator= (const ModalItem&); | |||
| }; | |||
| //============================================================================== | |||
| ModalComponentManager::ModalComponentManager() | |||
| { | |||
| } | |||
| ModalComponentManager::~ModalComponentManager() | |||
| { | |||
| clearSingletonInstance(); | |||
| } | |||
| juce_ImplementSingleton_SingleThreaded (ModalComponentManager); | |||
| //============================================================================== | |||
| void ModalComponentManager::startModal (Component* component, Callback* callback) | |||
| { | |||
| if (component != 0) | |||
| stack.add (new ModalItem (component, callback)); | |||
| } | |||
| void ModalComponentManager::attachCallback (Component* component, Callback* callback) | |||
| { | |||
| if (callback != 0) | |||
| { | |||
| ScopedPointer<Callback> callbackDeleter (callback); | |||
| for (int i = stack.size(); --i >= 0;) | |||
| { | |||
| ModalItem* const item = stack.getUnchecked(i); | |||
| if (item->component == component) | |||
| { | |||
| item->callbacks.add (callback); | |||
| callbackDeleter.release(); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void ModalComponentManager::endModal (Component* component) | |||
| { | |||
| for (int i = stack.size(); --i >= 0;) | |||
| { | |||
| ModalItem* const item = stack.getUnchecked(i); | |||
| if (item->component == component) | |||
| item->cancel(); | |||
| } | |||
| } | |||
| void ModalComponentManager::endModal (Component* component, int returnValue) | |||
| { | |||
| for (int i = stack.size(); --i >= 0;) | |||
| { | |||
| ModalItem* const item = stack.getUnchecked(i); | |||
| if (item->component == component) | |||
| { | |||
| item->returnValue = returnValue; | |||
| item->cancel(); | |||
| } | |||
| } | |||
| } | |||
| int ModalComponentManager::getNumModalComponents() const | |||
| { | |||
| int n = 0; | |||
| for (int i = 0; i < stack.size(); ++i) | |||
| if (stack.getUnchecked(i)->isActive) | |||
| ++n; | |||
| return n; | |||
| } | |||
| Component* ModalComponentManager::getModalComponent (const int index) const | |||
| { | |||
| int n = 0; | |||
| for (int i = stack.size(); --i >= 0;) | |||
| { | |||
| const ModalItem* const item = stack.getUnchecked(i); | |||
| if (item->isActive) | |||
| if (n++ == index) | |||
| return item->component; | |||
| } | |||
| return 0; | |||
| } | |||
| bool ModalComponentManager::isModal (Component* const comp) const | |||
| { | |||
| for (int i = stack.size(); --i >= 0;) | |||
| { | |||
| const ModalItem* const item = stack.getUnchecked(i); | |||
| if (item->isActive && item->component == comp) | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| bool ModalComponentManager::isFrontModalComponent (Component* const comp) const | |||
| { | |||
| return comp == getModalComponent (0); | |||
| } | |||
| void ModalComponentManager::handleAsyncUpdate() | |||
| { | |||
| for (int i = stack.size(); --i >= 0;) | |||
| { | |||
| const ModalItem* const item = stack.getUnchecked(i); | |||
| if (! item->isActive) | |||
| { | |||
| for (int j = item->callbacks.size(); --j >= 0;) | |||
| item->callbacks.getUnchecked(j)->modalStateFinished (item->returnValue); | |||
| stack.remove (i); | |||
| } | |||
| } | |||
| } | |||
| class ModalComponentManager::ReturnValueRetriever : public ModalComponentManager::Callback | |||
| { | |||
| public: | |||
| ReturnValueRetriever (int& value_, bool& finished_) : value (value_), finished (finished_) {} | |||
| ~ReturnValueRetriever() {} | |||
| void modalStateFinished (int returnValue) | |||
| { | |||
| finished = true; | |||
| value = returnValue; | |||
| } | |||
| private: | |||
| int& value; | |||
| bool& finished; | |||
| ReturnValueRetriever (const ReturnValueRetriever&); | |||
| ReturnValueRetriever& operator= (const ReturnValueRetriever&); | |||
| }; | |||
| int ModalComponentManager::runEventLoopForCurrentComponent() | |||
| { | |||
| // This can only be run from the message thread! | |||
| jassert (MessageManager::getInstance()->isThisTheMessageThread()); | |||
| Component* currentlyModal = getModalComponent (0); | |||
| if (currentlyModal == 0) | |||
| return 0; | |||
| Component::SafePointer<Component> prevFocused (Component::getCurrentlyFocusedComponent()); | |||
| int returnValue = 0; | |||
| bool finished = false; | |||
| attachCallback (currentlyModal, new ReturnValueRetriever (returnValue, finished)); | |||
| JUCE_TRY | |||
| { | |||
| while (! finished) | |||
| { | |||
| if (! MessageManager::getInstance()->runDispatchLoopUntil (20)) | |||
| break; | |||
| } | |||
| } | |||
| JUCE_CATCH_EXCEPTION | |||
| if (prevFocused != 0) | |||
| prevFocused->grabKeyboardFocus(); | |||
| return returnValue; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -0,0 +1,144 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-10 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #ifndef __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| #define __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| #include "../../core/juce_Singleton.h" | |||
| #include "../../events/juce_AsyncUpdater.h" | |||
| #include "../../utilities/juce_DeletedAtShutdown.h" | |||
| //============================================================================== | |||
| /** | |||
| Manages the system's stack of modal components. | |||
| Normally you'll just use the Component methods to invoke modal states in components, | |||
| and won't have to deal with this class directly, but this is the singleton object that's | |||
| used internally to manage the stack. | |||
| @see Component::enterModalState, Component::exitModalState, Component::isCurrentlyModal, | |||
| Component::getCurrentlyModalComponent, Component::isCurrentlyBlockedByAnotherModalComponent | |||
| */ | |||
| class JUCE_API ModalComponentManager : public AsyncUpdater, | |||
| public DeletedAtShutdown | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Receives callbacks when a modal component is dismissed. | |||
| You can register a callback using Component::enterModalState() or | |||
| ModalComponentManager::attachCallback(). | |||
| */ | |||
| class Callback | |||
| { | |||
| public: | |||
| /** */ | |||
| Callback() {} | |||
| /** Destructor. */ | |||
| virtual ~Callback() {} | |||
| /** Called to indicate that a modal component has been dismissed. | |||
| You can register a callback using Component::enterModalState() or | |||
| ModalComponentManager::attachCallback(). | |||
| The returnValue parameter is the value that was passed to Component::exitModalState() | |||
| when the component was dismissed. | |||
| The callback object will be deleted shortly after this method is called. | |||
| */ | |||
| virtual void modalStateFinished (int returnValue) = 0; | |||
| }; | |||
| //============================================================================== | |||
| /** Returns the number of components currently being shown modally. | |||
| @see getModalComponent | |||
| */ | |||
| int getNumModalComponents() const; | |||
| /** Returns one of the components being shown modally. | |||
| An index of 0 is the most recently-shown, topmost component. | |||
| */ | |||
| Component* getModalComponent (int index) const; | |||
| /** Returns true if the specified component is in a modal state. */ | |||
| bool isModal (Component* component) const; | |||
| /** Returns true if the specified component is currently the topmost modal component. */ | |||
| bool isFrontModalComponent (Component* component) const; | |||
| /** Adds a new callback that will be called when the specified modal component is dismissed. | |||
| If the component is modal, then when it is dismissed, either by being hidden, or by calling | |||
| Component::exitModalState(), then the Callback::modalStateFinished() method will be | |||
| called. | |||
| Each component can have any number of callbacks associated with it, and this one is added | |||
| to that list. | |||
| The object that is passed in will be deleted by the manager when it's no longer needed. If | |||
| the given component is not currently modal, the callback object is deleted immediately and | |||
| no action is taken. | |||
| */ | |||
| void attachCallback (Component* component, Callback* callback); | |||
| /** Runs the event loop until the currently topmost modal component is dismissed, and | |||
| returns the exit code for that component. | |||
| */ | |||
| int runEventLoopForCurrentComponent(); | |||
| //============================================================================== | |||
| juce_DeclareSingleton_SingleThreaded_Minimal (ModalComponentManager); | |||
| protected: | |||
| /** Creates a ModalComponentManager. | |||
| You shouldn't ever call the constructor - it's a singleton, so use ModalComponentManager::getInstance() | |||
| */ | |||
| ModalComponentManager(); | |||
| /** Destructor. */ | |||
| ~ModalComponentManager(); | |||
| /** @internal */ | |||
| void handleAsyncUpdate(); | |||
| private: | |||
| class ModalItem; | |||
| class ReturnValueRetriever; | |||
| friend class Component; | |||
| friend class OwnedArray <ModalItem>; | |||
| OwnedArray <ModalItem> stack; | |||
| void startModal (Component* component, Callback* callback); | |||
| void endModal (Component* component, int returnValue); | |||
| void endModal (Component* component); | |||
| }; | |||
| #endif // __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| @@ -32,31 +32,14 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "../lookandfeel/juce_LookAndFeel.h" | |||
| //============================================================================== | |||
| class DummyMenuComponent : public Component | |||
| { | |||
| DummyMenuComponent (const DummyMenuComponent&); | |||
| DummyMenuComponent& operator= (const DummyMenuComponent&); | |||
| public: | |||
| DummyMenuComponent() {} | |||
| ~DummyMenuComponent() {} | |||
| void inputAttemptWhenModal() | |||
| { | |||
| exitModalState (0); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| MenuBarComponent::MenuBarComponent (MenuBarModel* model_) | |||
| : model (0), | |||
| itemUnderMouse (-1), | |||
| currentPopupIndex (-1), | |||
| indexToShowAgain (-1), | |||
| topLevelIndexClicked (0), | |||
| lastMouseX (0), | |||
| lastMouseY (0), | |||
| inModalState (false) | |||
| lastMouseY (0) | |||
| { | |||
| setRepaintsOnMouseActivity (true); | |||
| setWantsKeyboardFocus (false); | |||
| @@ -68,9 +51,12 @@ MenuBarComponent::MenuBarComponent (MenuBarModel* model_) | |||
| MenuBarComponent::~MenuBarComponent() | |||
| { | |||
| setModel (0); | |||
| Desktop::getInstance().removeGlobalMouseListener (this); | |||
| currentPopup = 0; | |||
| } | |||
| MenuBarModel* MenuBarComponent::getModel() const throw() | |||
| { | |||
| return model; | |||
| } | |||
| void MenuBarComponent::setModel (MenuBarModel* const newModel) | |||
| @@ -158,144 +144,102 @@ void MenuBarComponent::repaintMenuItem (int index) | |||
| } | |||
| } | |||
| void MenuBarComponent::updateItemUnderMouse (int x, int y) | |||
| void MenuBarComponent::setItemUnderMouse (const int index) | |||
| { | |||
| const int newItem = getItemAt (x, y); | |||
| if (itemUnderMouse != newItem) | |||
| if (itemUnderMouse != index) | |||
| { | |||
| repaintMenuItem (itemUnderMouse); | |||
| itemUnderMouse = newItem; | |||
| itemUnderMouse = index; | |||
| repaintMenuItem (itemUnderMouse); | |||
| } | |||
| } | |||
| void MenuBarComponent::hideCurrentMenu() | |||
| void MenuBarComponent::setOpenItem (int index) | |||
| { | |||
| currentPopup = 0; | |||
| repaint(); | |||
| } | |||
| void MenuBarComponent::showMenu (int index) | |||
| { | |||
| if (index != currentPopupIndex) | |||
| if (currentPopupIndex != index) | |||
| { | |||
| if (inModalState) | |||
| { | |||
| hideCurrentMenu(); | |||
| indexToShowAgain = index; | |||
| return; | |||
| } | |||
| repaintMenuItem (currentPopupIndex); | |||
| currentPopupIndex = index; | |||
| repaintMenuItem (currentPopupIndex); | |||
| indexToShowAgain = -1; | |||
| currentPopupIndex = -1; | |||
| itemUnderMouse = index; | |||
| currentPopup = 0; | |||
| menuBarItemsChanged (0); | |||
| if (index >= 0) | |||
| Desktop::getInstance().addGlobalMouseListener (this); | |||
| else | |||
| Desktop::getInstance().removeGlobalMouseListener (this); | |||
| } | |||
| } | |||
| Component::SafePointer<Component> prevFocused (getCurrentlyFocusedComponent()); | |||
| Component::SafePointer<Component> deletionChecker (this); | |||
| void MenuBarComponent::updateItemUnderMouse (int x, int y) | |||
| { | |||
| setItemUnderMouse (getItemAt (x, y)); | |||
| } | |||
| enterModalState (false); | |||
| inModalState = true; | |||
| int result = 0; | |||
| ApplicationCommandManager* managerOfChosenCommand = 0; | |||
| class MenuBarComponent::AsyncCallback : public ModalComponentManager::Callback | |||
| { | |||
| public: | |||
| AsyncCallback (MenuBarComponent* const bar_, const int topLevelIndex_) | |||
| : bar (bar_), topLevelIndex (topLevelIndex_) | |||
| { | |||
| } | |||
| Desktop::getInstance().addGlobalMouseListener (this); | |||
| ~AsyncCallback() {} | |||
| for (;;) | |||
| { | |||
| const int x = getScreenX() + xPositions [itemUnderMouse]; | |||
| const int w = xPositions [itemUnderMouse + 1] - xPositions [itemUnderMouse]; | |||
| currentPopupIndex = itemUnderMouse; | |||
| indexToShowAgain = -1; | |||
| repaint(); | |||
| if (((unsigned int) itemUnderMouse) < (unsigned int) menuNames.size()) | |||
| { | |||
| PopupMenu m (model->getMenuForIndex (itemUnderMouse, | |||
| menuNames [itemUnderMouse])); | |||
| if (m.lookAndFeel == 0) | |||
| m.setLookAndFeel (&getLookAndFeel()); | |||
| currentPopup = m.createMenuComponent (x, getScreenY(), | |||
| w, getHeight(), | |||
| 0, w, 0, 0, | |||
| true, this, | |||
| &managerOfChosenCommand, | |||
| this); | |||
| } | |||
| if (currentPopup == 0) | |||
| { | |||
| currentPopup = new DummyMenuComponent(); | |||
| addAndMakeVisible (currentPopup); | |||
| } | |||
| currentPopup->enterModalState (false); | |||
| currentPopup->toFront (false); // need to do this after making it modal, or it could | |||
| // be stuck behind other comps that are already modal.. | |||
| result = currentPopup->runModalLoop(); | |||
| if (deletionChecker == 0) | |||
| return; | |||
| const int lastPopupIndex = currentPopupIndex; | |||
| currentPopup = 0; | |||
| currentPopupIndex = -1; | |||
| if (result != 0) | |||
| { | |||
| topLevelIndexClicked = lastPopupIndex; | |||
| break; | |||
| } | |||
| else if (indexToShowAgain >= 0) | |||
| { | |||
| menuBarItemsChanged (0); | |||
| repaint(); | |||
| itemUnderMouse = indexToShowAgain; | |||
| if (((unsigned int) itemUnderMouse) >= (unsigned int) menuNames.size()) | |||
| break; | |||
| } | |||
| else | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| void modalStateFinished (int returnValue) | |||
| { | |||
| if (bar != 0) | |||
| bar->menuDismissed (topLevelIndex, returnValue); | |||
| } | |||
| Desktop::getInstance().removeGlobalMouseListener (this); | |||
| private: | |||
| Component::SafePointer<MenuBarComponent> bar; | |||
| const int topLevelIndex; | |||
| inModalState = false; | |||
| exitModalState (0); | |||
| AsyncCallback (const AsyncCallback&); | |||
| AsyncCallback& operator= (const AsyncCallback&); | |||
| }; | |||
| if (prevFocused != 0) | |||
| prevFocused->grabKeyboardFocus(); | |||
| void MenuBarComponent::showMenu (int index) | |||
| { | |||
| if (index != currentPopupIndex) | |||
| { | |||
| PopupMenu::dismissAllActiveMenus(); | |||
| menuBarItemsChanged (0); | |||
| const Point<int> mousePos (getMouseXYRelative()); | |||
| updateItemUnderMouse (mousePos.getX(), mousePos.getY()); | |||
| repaint(); | |||
| setOpenItem (index); | |||
| setItemUnderMouse (index); | |||
| if (result != 0) | |||
| if (index >= 0) | |||
| { | |||
| if (managerOfChosenCommand != 0) | |||
| { | |||
| ApplicationCommandTarget::InvocationInfo info (result); | |||
| info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu; | |||
| PopupMenu m (model->getMenuForIndex (itemUnderMouse, | |||
| menuNames [itemUnderMouse])); | |||
| if (m.lookAndFeel == 0) | |||
| m.setLookAndFeel (&getLookAndFeel()); | |||
| managerOfChosenCommand->invoke (info, true); | |||
| } | |||
| const Rectangle<int> itemPos (xPositions [index], 0, xPositions [index + 1] - xPositions [index], getHeight()); | |||
| postCommandMessage (result); | |||
| m.showMenu (itemPos + getScreenPosition(), | |||
| 0, itemPos.getWidth(), 0, 0, true, this, | |||
| new AsyncCallback (this, index)); | |||
| } | |||
| } | |||
| } | |||
| void MenuBarComponent::menuDismissed (int topLevelIndex, int itemId) | |||
| { | |||
| topLevelIndexClicked = topLevelIndex; | |||
| postCommandMessage (itemId); | |||
| } | |||
| void MenuBarComponent::handleCommandMessage (int commandId) | |||
| { | |||
| if (model != 0) | |||
| const Point<int> mousePos (getMouseXYRelative()); | |||
| updateItemUnderMouse (mousePos.getX(), mousePos.getY()); | |||
| if (! isCurrentlyBlockedByAnotherModalComponent()) | |||
| setOpenItem (-1); | |||
| if (commandId != 0 && model != 0) | |||
| model->menuItemSelected (commandId, topLevelIndexClicked); | |||
| } | |||
| @@ -327,7 +271,6 @@ void MenuBarComponent::mouseDown (const MouseEvent& e) | |||
| void MenuBarComponent::mouseDrag (const MouseEvent& e) | |||
| { | |||
| const MouseEvent e2 (e.getEventRelativeTo (this)); | |||
| const int item = getItemAt (e2.x, e2.y); | |||
| if (item >= 0) | |||
| @@ -340,8 +283,11 @@ void MenuBarComponent::mouseUp (const MouseEvent& e) | |||
| updateItemUnderMouse (e2.x, e2.y); | |||
| if (itemUnderMouse < 0 && dynamic_cast <DummyMenuComponent*> (static_cast <Component*> (currentPopup)) != 0) | |||
| hideCurrentMenu(); | |||
| if (itemUnderMouse < 0 && getLocalBounds().contains (e2.x, e2.y)) | |||
| { | |||
| setOpenItem (-1); | |||
| PopupMenu::dismissAllActiveMenus(); | |||
| } | |||
| } | |||
| void MenuBarComponent::mouseMove (const MouseEvent& e) | |||
| @@ -387,11 +333,6 @@ bool MenuBarComponent::keyPressed (const KeyPress& key) | |||
| return used; | |||
| } | |||
| void MenuBarComponent::inputAttemptWhenModal() | |||
| { | |||
| hideCurrentMenu(); | |||
| } | |||
| void MenuBarComponent::menuBarItemsChanged (MenuBarModel* /*menuBarModel*/) | |||
| { | |||
| StringArray newNames; | |||
| @@ -410,8 +351,7 @@ void MenuBarComponent::menuBarItemsChanged (MenuBarModel* /*menuBarModel*/) | |||
| void MenuBarComponent::menuCommandInvoked (MenuBarModel* /*menuBarModel*/, | |||
| const ApplicationCommandTarget::InvocationInfo& info) | |||
| { | |||
| if (model == 0 | |||
| || (info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) != 0) | |||
| if (model == 0 || (info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) != 0) | |||
| return; | |||
| for (int i = 0; i < menuNames.size(); ++i) | |||
| @@ -420,10 +360,8 @@ void MenuBarComponent::menuCommandInvoked (MenuBarModel* /*menuBarModel*/, | |||
| if (menu.containsCommandItem (info.commandID)) | |||
| { | |||
| itemUnderMouse = i; | |||
| repaintMenuItem (i); | |||
| setItemUnderMouse (i); | |||
| startTimer (200); | |||
| break; | |||
| } | |||
| } | |||
| @@ -60,6 +60,10 @@ public: | |||
| */ | |||
| void setModel (MenuBarModel* newModel); | |||
| /** Returns the current menu bar model being used. | |||
| */ | |||
| MenuBarModel* getModel() const throw(); | |||
| //============================================================================== | |||
| /** Pops up one of the menu items. | |||
| @@ -86,8 +90,6 @@ public: | |||
| /** @internal */ | |||
| void mouseMove (const MouseEvent& e); | |||
| /** @internal */ | |||
| void inputAttemptWhenModal(); | |||
| /** @internal */ | |||
| void handleCommandMessage (int commandId); | |||
| /** @internal */ | |||
| bool keyPressed (const KeyPress& key); | |||
| @@ -102,20 +104,22 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class AsyncCallback; | |||
| friend class AsyncCallback; | |||
| MenuBarModel* model; | |||
| StringArray menuNames; | |||
| Array <int> xPositions; | |||
| int itemUnderMouse, currentPopupIndex, topLevelIndexClicked, indexToShowAgain; | |||
| int itemUnderMouse, currentPopupIndex, topLevelIndexClicked; | |||
| int lastMouseX, lastMouseY; | |||
| bool inModalState; | |||
| ScopedPointer <Component> currentPopup; | |||
| int getItemAt (int x, int y); | |||
| void setItemUnderMouse (int index); | |||
| void setOpenItem (int index); | |||
| void updateItemUnderMouse (int x, int y); | |||
| void hideCurrentMenu(); | |||
| void timerCallback(); | |||
| void repaintMenuItem (int index); | |||
| void menuDismissed (int topLevelIndex, int itemId); | |||
| MenuBarComponent (const MenuBarComponent&); | |||
| MenuBarComponent& operator= (const MenuBarComponent&); | |||
| @@ -309,8 +309,7 @@ public: | |||
| static Window* create (const PopupMenu& menu, | |||
| const bool dismissOnMouseUp, | |||
| Window* const owner_, | |||
| const int minX, const int maxX, | |||
| const int minY, const int maxY, | |||
| const Rectangle<int>& target, | |||
| const int minimumWidth, | |||
| const int maximumNumColumns, | |||
| const int standardItemHeight, | |||
| @@ -348,14 +347,14 @@ public: | |||
| mw->componentAttachedTo = componentAttachedTo; | |||
| mw->componentAttachedToOriginal = componentAttachedTo; | |||
| mw->calculateWindowPos (minX, maxX, minY, maxY, alignToRectangle); | |||
| mw->calculateWindowPos (target, alignToRectangle); | |||
| mw->setTopLeftPosition (mw->windowPos.getX(), | |||
| mw->windowPos.getY()); | |||
| mw->updateYPositions(); | |||
| if (itemIdThatMustBeVisible != 0) | |||
| { | |||
| const int y = minY - mw->windowPos.getY(); | |||
| const int y = target.getY() - mw->windowPos.getY(); | |||
| mw->ensureItemIsVisible (itemIdThatMustBeVisible, | |||
| (((unsigned int) y) < (unsigned int) mw->windowPos.getHeight()) ? y : -1); | |||
| } | |||
| @@ -804,13 +803,10 @@ private: | |||
| } | |||
| //============================================================================== | |||
| void calculateWindowPos (const int minX, const int maxX, | |||
| const int minY, const int maxY, | |||
| const bool alignToRectangle) | |||
| void calculateWindowPos (const Rectangle<int>& target, const bool alignToRectangle) | |||
| { | |||
| const Rectangle<int> mon (Desktop::getInstance() | |||
| .getMonitorAreaContaining (Point<int> ((minX + maxX) / 2, | |||
| (minY + maxY) / 2), | |||
| .getMonitorAreaContaining (target.getCentre(), | |||
| #if JUCE_MAC | |||
| true)); | |||
| #else | |||
| @@ -822,19 +818,19 @@ private: | |||
| if (alignToRectangle) | |||
| { | |||
| x = minX; | |||
| x = target.getX(); | |||
| const int spaceUnder = mon.getHeight() - (maxY - mon.getY()); | |||
| const int spaceOver = minY - mon.getY(); | |||
| const int spaceUnder = mon.getHeight() - (target.getBottom() - mon.getY()); | |||
| const int spaceOver = target.getY() - mon.getY(); | |||
| if (heightToUse < spaceUnder - 30 || spaceUnder >= spaceOver) | |||
| y = maxY; | |||
| y = target.getBottom(); | |||
| else | |||
| y = minY - heightToUse; | |||
| y = target.getY() - heightToUse; | |||
| } | |||
| else | |||
| { | |||
| bool tendTowardsRight = (minX + maxX) / 2 < mon.getCentreX(); | |||
| bool tendTowardsRight = target.getCentreX() < mon.getCentreX(); | |||
| if (owner != 0) | |||
| { | |||
| @@ -843,38 +839,38 @@ private: | |||
| const bool ownerGoingRight = (owner->getX() + owner->getWidth() / 2 | |||
| > owner->owner->getX() + owner->owner->getWidth() / 2); | |||
| if (ownerGoingRight && maxX + widthToUse < mon.getRight() - 4) | |||
| if (ownerGoingRight && target.getRight() + widthToUse < mon.getRight() - 4) | |||
| tendTowardsRight = true; | |||
| else if ((! ownerGoingRight) && minX > widthToUse + 4) | |||
| else if ((! ownerGoingRight) && target.getX() > widthToUse + 4) | |||
| tendTowardsRight = false; | |||
| } | |||
| else if (maxX + widthToUse < mon.getRight() - 32) | |||
| else if (target.getRight() + widthToUse < mon.getRight() - 32) | |||
| { | |||
| tendTowardsRight = true; | |||
| } | |||
| } | |||
| const int biggestSpace = jmax (mon.getRight() - maxX, | |||
| minX - mon.getX()) - 32; | |||
| const int biggestSpace = jmax (mon.getRight() - target.getRight(), | |||
| target.getX() - mon.getX()) - 32; | |||
| if (biggestSpace < widthToUse) | |||
| { | |||
| layoutMenuItems (biggestSpace + (maxX - minX) / 3, widthToUse, heightToUse); | |||
| layoutMenuItems (biggestSpace + target.getWidth() / 3, widthToUse, heightToUse); | |||
| if (numColumns > 1) | |||
| layoutMenuItems (biggestSpace - 4, widthToUse, heightToUse); | |||
| tendTowardsRight = (mon.getRight() - maxX) >= (minX - mon.getX()); | |||
| tendTowardsRight = (mon.getRight() - target.getRight()) >= (target.getX() - mon.getX()); | |||
| } | |||
| if (tendTowardsRight) | |||
| x = jmin (mon.getRight() - widthToUse - 4, maxX); | |||
| x = jmin (mon.getRight() - widthToUse - 4, target.getRight()); | |||
| else | |||
| x = jmax (mon.getX() + 4, minX - widthToUse); | |||
| x = jmax (mon.getX() + 4, target.getX() - widthToUse); | |||
| y = minY; | |||
| if ((minY + maxY) / 2 > mon.getCentreY()) | |||
| y = jmax (mon.getY(), maxY - heightToUse); | |||
| y = target.getY(); | |||
| if (target.getCentreY() > mon.getCentreY()) | |||
| y = jmax (mon.getY(), target.getBottom() - heightToUse); | |||
| } | |||
| x = jmax (mon.getX() + 1, jmin (mon.getRight() - (widthToUse + 6), x)); | |||
| @@ -1107,13 +1103,10 @@ private: | |||
| if (childComp->isValidComponent() && childComp->itemInfo.hasActiveSubMenu()) | |||
| { | |||
| const Point<int> topLeft (childComp->relativePositionToGlobal (Point<int>())); | |||
| const Point<int> bottomRight (childComp->relativePositionToGlobal (Point<int> (childComp->getWidth(), childComp->getHeight()))); | |||
| activeSubMenu = Window::create (*(childComp->itemInfo.subMenu), | |||
| dismissOnMouseUp, | |||
| this, | |||
| topLeft.getX(), bottomRight.getX(), topLeft.getY(), bottomRight.getY(), | |||
| childComp->getScreenBounds(), | |||
| 0, maximumNumColumns, | |||
| standardItemHeight, | |||
| false, 0, menuBarComponent, | |||
| @@ -1494,7 +1487,7 @@ void PopupMenu::addSectionHeader (const String& title) | |||
| } | |||
| //============================================================================== | |||
| Component* PopupMenu::createMenuComponent (const int x, const int y, const int w, const int h, | |||
| Component* PopupMenu::createMenuComponent (const Rectangle<int>& target, | |||
| const int itemIdThatMustBeVisible, | |||
| const int minimumWidth, | |||
| const int maximumNumColumns, | |||
| @@ -1504,20 +1497,10 @@ Component* PopupMenu::createMenuComponent (const int x, const int y, const int w | |||
| ApplicationCommandManager** managerOfChosenCommand, | |||
| Component* const componentAttachedTo) | |||
| { | |||
| Window* const pw | |||
| = Window::create (*this, | |||
| ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), | |||
| 0, | |||
| x, x + w, | |||
| y, y + h, | |||
| minimumWidth, | |||
| maximumNumColumns, | |||
| standardItemHeight, | |||
| alignToRectangle, | |||
| itemIdThatMustBeVisible, | |||
| menuBarComponent, | |||
| managerOfChosenCommand, | |||
| componentAttachedTo); | |||
| Window* const pw = Window::create (*this, ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), | |||
| 0, target, minimumWidth, maximumNumColumns, standardItemHeight, | |||
| alignToRectangle, itemIdThatMustBeVisible, menuBarComponent, | |||
| managerOfChosenCommand, componentAttachedTo); | |||
| if (pw != 0) | |||
| pw->setVisible (true); | |||
| @@ -1525,56 +1508,87 @@ Component* PopupMenu::createMenuComponent (const int x, const int y, const int w | |||
| return pw; | |||
| } | |||
| int PopupMenu::showMenu (const int x, const int y, const int w, const int h, | |||
| // This invokes any command manager commands and deletes the menu window when it is dismissed | |||
| class PopupMenuCompletionCallback : public ModalComponentManager::Callback | |||
| { | |||
| public: | |||
| PopupMenuCompletionCallback() | |||
| : managerOfChosenCommand (0) | |||
| { | |||
| } | |||
| ~PopupMenuCompletionCallback() {} | |||
| void modalStateFinished (int result) | |||
| { | |||
| if (managerOfChosenCommand != 0 && result != 0) | |||
| { | |||
| ApplicationCommandTarget::InvocationInfo info (result); | |||
| info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu; | |||
| managerOfChosenCommand->invoke (info, true); | |||
| } | |||
| } | |||
| ApplicationCommandManager* managerOfChosenCommand; | |||
| ScopedPointer<Component> component; | |||
| private: | |||
| PopupMenuCompletionCallback (const PopupMenuCompletionCallback&); | |||
| PopupMenuCompletionCallback& operator= (const PopupMenuCompletionCallback&); | |||
| }; | |||
| int PopupMenu::showMenu (const Rectangle<int>& target, | |||
| const int itemIdThatMustBeVisible, | |||
| const int minimumWidth, | |||
| const int maximumNumColumns, | |||
| const int standardItemHeight, | |||
| const bool alignToRectangle, | |||
| Component* const componentAttachedTo) | |||
| Component* const componentAttachedTo, | |||
| ModalComponentManager::Callback* userCallback) | |||
| { | |||
| ScopedPointer<ModalComponentManager::Callback> userCallbackDeleter (userCallback); | |||
| Component::SafePointer<Component> prevFocused (Component::getCurrentlyFocusedComponent()); | |||
| Component::SafePointer<Component> prevTopLevel ((prevFocused != 0) ? prevFocused->getTopLevelComponent() : 0); | |||
| Window::wasHiddenBecauseOfAppChange() = false; | |||
| int result = 0; | |||
| ApplicationCommandManager* managerOfChosenCommand = 0; | |||
| PopupMenuCompletionCallback* callback = new PopupMenuCompletionCallback(); | |||
| ScopedPointer<PopupMenuCompletionCallback> callbackDeleter (callback); | |||
| ScopedPointer <Component> popupComp (createMenuComponent (x, y, w, h, | |||
| itemIdThatMustBeVisible, | |||
| minimumWidth, | |||
| maximumNumColumns > 0 ? maximumNumColumns : 7, | |||
| standardItemHeight, | |||
| alignToRectangle, 0, | |||
| &managerOfChosenCommand, | |||
| componentAttachedTo)); | |||
| callback->component = createMenuComponent (target, | |||
| itemIdThatMustBeVisible, | |||
| minimumWidth, | |||
| maximumNumColumns > 0 ? maximumNumColumns : 7, | |||
| standardItemHeight, | |||
| alignToRectangle, 0, | |||
| &callback->managerOfChosenCommand, | |||
| componentAttachedTo); | |||
| if (popupComp != 0) | |||
| { | |||
| popupComp->enterModalState (false); | |||
| popupComp->toFront (false); // need to do this after making it modal, or it could | |||
| // be stuck behind other comps that are already modal.. | |||
| if (callback->component == 0) | |||
| return 0; | |||
| result = popupComp->runModalLoop(); | |||
| popupComp = 0; | |||
| callbackDeleter.release(); | |||
| if (! Window::wasHiddenBecauseOfAppChange()) | |||
| { | |||
| if (prevTopLevel != 0) | |||
| prevTopLevel->toFront (true); | |||
| callback->component->enterModalState (false, userCallbackDeleter.release()); | |||
| callback->component->toFront (false); // need to do this after making it modal, or it could | |||
| // be stuck behind other comps that are already modal.. | |||
| if (prevFocused != 0) | |||
| prevFocused->grabKeyboardFocus(); | |||
| } | |||
| } | |||
| ModalComponentManager::getInstance()->attachCallback (callback->component, callback); | |||
| if (userCallback != 0) | |||
| return 0; | |||
| const int result = callback->component->runModalLoop(); | |||
| if (managerOfChosenCommand != 0 && result != 0) | |||
| if (! Window::wasHiddenBecauseOfAppChange()) | |||
| { | |||
| ApplicationCommandTarget::InvocationInfo info (result); | |||
| info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu; | |||
| if (prevTopLevel != 0) | |||
| prevTopLevel->toFront (true); | |||
| managerOfChosenCommand->invoke (info, true); | |||
| if (prevFocused != 0) | |||
| prevFocused->grabKeyboardFocus(); | |||
| } | |||
| return result; | |||
| @@ -1583,7 +1597,8 @@ int PopupMenu::showMenu (const int x, const int y, const int w, const int h, | |||
| int PopupMenu::show (const int itemIdThatMustBeVisible, | |||
| const int minimumWidth, | |||
| const int maximumNumColumns, | |||
| const int standardItemHeight) | |||
| const int standardItemHeight, | |||
| ModalComponentManager::Callback* callback) | |||
| { | |||
| const Point<int> mousePos (Desktop::getMousePosition()); | |||
| @@ -1591,7 +1606,8 @@ int PopupMenu::show (const int itemIdThatMustBeVisible, | |||
| itemIdThatMustBeVisible, | |||
| minimumWidth, | |||
| maximumNumColumns, | |||
| standardItemHeight); | |||
| standardItemHeight, | |||
| callback); | |||
| } | |||
| int PopupMenu::showAt (const int screenX, | |||
| @@ -1599,39 +1615,39 @@ int PopupMenu::showAt (const int screenX, | |||
| const int itemIdThatMustBeVisible, | |||
| const int minimumWidth, | |||
| const int maximumNumColumns, | |||
| const int standardItemHeight) | |||
| const int standardItemHeight, | |||
| ModalComponentManager::Callback* callback) | |||
| { | |||
| return showMenu (screenX, screenY, 1, 1, | |||
| return showMenu (Rectangle<int> (screenX, screenY, 1, 1), | |||
| itemIdThatMustBeVisible, | |||
| minimumWidth, maximumNumColumns, | |||
| standardItemHeight, | |||
| false, 0); | |||
| false, 0, callback); | |||
| } | |||
| int PopupMenu::showAt (Component* componentToAttachTo, | |||
| const int itemIdThatMustBeVisible, | |||
| const int minimumWidth, | |||
| const int maximumNumColumns, | |||
| const int standardItemHeight) | |||
| const int standardItemHeight, | |||
| ModalComponentManager::Callback* callback) | |||
| { | |||
| if (componentToAttachTo != 0) | |||
| { | |||
| return showMenu (componentToAttachTo->getScreenX(), | |||
| componentToAttachTo->getScreenY(), | |||
| componentToAttachTo->getWidth(), | |||
| componentToAttachTo->getHeight(), | |||
| return showMenu (componentToAttachTo->getScreenBounds(), | |||
| itemIdThatMustBeVisible, | |||
| minimumWidth, | |||
| maximumNumColumns, | |||
| standardItemHeight, | |||
| true, componentToAttachTo); | |||
| true, componentToAttachTo, callback); | |||
| } | |||
| else | |||
| { | |||
| return show (itemIdThatMustBeVisible, | |||
| minimumWidth, | |||
| maximumNumColumns, | |||
| standardItemHeight); | |||
| standardItemHeight, | |||
| callback); | |||
| } | |||
| } | |||
| @@ -240,12 +240,19 @@ public: | |||
| in zero. | |||
| @param standardItemHeight if this is non-zero, it will be used as the standard | |||
| height for menu items (apart from custom items) | |||
| @param callback if this is non-zero, the menu will be launched asynchronously, | |||
| returning immediately, and the callback will receive a | |||
| call when the menu is either dismissed or has an item | |||
| selected. This object will be owned and deleted by the | |||
| system, so make sure that it works safely and that any | |||
| pointers that it uses are safely within scope. | |||
| @see showAt | |||
| */ | |||
| int show (int itemIdThatMustBeVisible = 0, | |||
| int minimumWidth = 0, | |||
| int maximumNumColumns = 0, | |||
| int standardItemHeight = 0); | |||
| int standardItemHeight = 0, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| /** Displays the menu at a specific location. | |||
| @@ -264,7 +271,8 @@ public: | |||
| int itemIdThatMustBeVisible = 0, | |||
| int minimumWidth = 0, | |||
| int maximumNumColumns = 0, | |||
| int standardItemHeight = 0); | |||
| int standardItemHeight = 0, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| /** Displays the menu as if it's attached to a component such as a button. | |||
| @@ -276,7 +284,8 @@ public: | |||
| int itemIdThatMustBeVisible = 0, | |||
| int minimumWidth = 0, | |||
| int maximumNumColumns = 0, | |||
| int standardItemHeight = 0); | |||
| int standardItemHeight = 0, | |||
| ModalComponentManager::Callback* callback = 0); | |||
| //============================================================================== | |||
| /** Closes any menus that are currently open. | |||
| @@ -383,6 +392,7 @@ private: | |||
| friend class ItemComponent; | |||
| friend class Window; | |||
| friend class PopupMenuCustomComponent; | |||
| friend class MenuBarComponent; | |||
| friend class OwnedArray <Item>; | |||
| friend class ScopedPointer <Window>; | |||
| @@ -392,16 +402,16 @@ private: | |||
| void addSeparatorIfPending(); | |||
| int showMenu (int x, int y, int w, int h, | |||
| int showMenu (const Rectangle<int>& target, | |||
| int itemIdThatMustBeVisible, | |||
| int minimumWidth, | |||
| int maximumNumColumns, | |||
| int standardItemHeight, | |||
| bool alignToRectangle, | |||
| Component* componentAttachedTo); | |||
| Component* componentAttachedTo, | |||
| ModalComponentManager::Callback* callback); | |||
| friend class MenuBarComponent; | |||
| Component* createMenuComponent (int x, int y, int w, int h, | |||
| Component* createMenuComponent (const Rectangle<int>& target, | |||
| int itemIdThatMustBeVisible, | |||
| int minimumWidth, | |||
| int maximumNumColumns, | |||
| @@ -601,7 +601,7 @@ void Path::addArrow (const Line<float>& line, float lineThickness, | |||
| startNewSubPath (line.getPointAlongLine (0, lineThickness)); | |||
| lineTo (line.getPointAlongLine (0, -lineThickness)); | |||
| lineTo (reversed.getPointAlongLine (0, lineThickness)); | |||
| lineTo (reversed.getPointAlongLine (arrowheadLength, lineThickness)); | |||
| lineTo (reversed.getPointAlongLine (arrowheadLength, arrowheadWidth)); | |||
| lineTo (line.getEnd()); | |||
| lineTo (reversed.getPointAlongLine (arrowheadLength, -arrowheadWidth)); | |||
| @@ -404,6 +404,9 @@ | |||
| #ifndef __JUCE_DESKTOP_JUCEHEADER__ | |||
| #include "gui/components/juce_Desktop.h" | |||
| #endif | |||
| #ifndef __JUCE_MODALCOMPONENTMANAGER_JUCEHEADER__ | |||
| #include "gui/components/juce_ModalComponentManager.h" | |||
| #endif | |||
| #ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__ | |||
| #include "gui/components/keyboard/juce_KeyboardFocusTraverser.h" | |||
| #endif | |||