| @@ -68,6 +68,26 @@ OBJECTS := \ | |||
| $(OBJDIR)/jucer_MiscUtilities_25b68c82.o \ | |||
| $(OBJDIR)/jucer_StoredSettings_26078d2c.o \ | |||
| $(OBJDIR)/jucer_SourceCodeEditor_461f5487.o \ | |||
| $(OBJDIR)/jucer_ComponentTypeHandler_6bec6262.o \ | |||
| $(OBJDIR)/jucer_ButtonDocument_56c341cc.o \ | |||
| $(OBJDIR)/jucer_ComponentDocument_92868083.o \ | |||
| $(OBJDIR)/jucer_ColouredElement_70cbc839.o \ | |||
| $(OBJDIR)/jucer_PaintElement_653460.o \ | |||
| $(OBJDIR)/jucer_PaintElementPath_908894a5.o \ | |||
| $(OBJDIR)/jucer_ComponentLayoutEditor_aeb44f8d.o \ | |||
| $(OBJDIR)/jucer_ComponentOverlayComponent_fd508d63.o \ | |||
| $(OBJDIR)/jucer_EditingPanelBase_6c2ed9ee.o \ | |||
| $(OBJDIR)/jucer_JucerDocumentEditor_2c581e26.o \ | |||
| $(OBJDIR)/jucer_PaintRoutineEditor_f6ac0344.o \ | |||
| $(OBJDIR)/jucer_PaintRoutinePanel_c309a0d7.o \ | |||
| $(OBJDIR)/jucer_ResourceEditorPanel_a558f2e2.o \ | |||
| $(OBJDIR)/jucer_TestComponent_db757dc4.o \ | |||
| $(OBJDIR)/jucer_BinaryResources_e0f99b46.o \ | |||
| $(OBJDIR)/jucer_ComponentLayout_6ea00129.o \ | |||
| $(OBJDIR)/jucer_GeneratedCode_9ca4ef7e.o \ | |||
| $(OBJDIR)/jucer_JucerDocument_ff8afcc2.o \ | |||
| $(OBJDIR)/jucer_ObjectTypes_4406f01c.o \ | |||
| $(OBJDIR)/jucer_PaintRoutine_e1e891ee.o \ | |||
| $(OBJDIR)/BinaryData_ce4232d4.o \ | |||
| $(OBJDIR)/juce_core_1ee54a40.o \ | |||
| $(OBJDIR)/juce_cryptography_3b1f489a.o \ | |||
| @@ -221,6 +241,106 @@ $(OBJDIR)/jucer_SourceCodeEditor_461f5487.o: ../../Source/Code\ Editor/jucer_Sou | |||
| @echo "Compiling jucer_SourceCodeEditor.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ComponentTypeHandler_6bec6262.o: ../../Source/ComponentEditor/components/jucer_ComponentTypeHandler.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ComponentTypeHandler.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ButtonDocument_56c341cc.o: ../../Source/ComponentEditor/documents/jucer_ButtonDocument.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ButtonDocument.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ComponentDocument_92868083.o: ../../Source/ComponentEditor/documents/jucer_ComponentDocument.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ComponentDocument.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ColouredElement_70cbc839.o: ../../Source/ComponentEditor/paintelements/jucer_ColouredElement.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ColouredElement.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_PaintElement_653460.o: ../../Source/ComponentEditor/paintelements/jucer_PaintElement.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_PaintElement.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_PaintElementPath_908894a5.o: ../../Source/ComponentEditor/paintelements/jucer_PaintElementPath.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_PaintElementPath.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ComponentLayoutEditor_aeb44f8d.o: ../../Source/ComponentEditor/ui/jucer_ComponentLayoutEditor.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ComponentLayoutEditor.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ComponentOverlayComponent_fd508d63.o: ../../Source/ComponentEditor/ui/jucer_ComponentOverlayComponent.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ComponentOverlayComponent.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_EditingPanelBase_6c2ed9ee.o: ../../Source/ComponentEditor/ui/jucer_EditingPanelBase.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_EditingPanelBase.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_JucerDocumentEditor_2c581e26.o: ../../Source/ComponentEditor/ui/jucer_JucerDocumentEditor.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_JucerDocumentEditor.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_PaintRoutineEditor_f6ac0344.o: ../../Source/ComponentEditor/ui/jucer_PaintRoutineEditor.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_PaintRoutineEditor.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_PaintRoutinePanel_c309a0d7.o: ../../Source/ComponentEditor/ui/jucer_PaintRoutinePanel.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_PaintRoutinePanel.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ResourceEditorPanel_a558f2e2.o: ../../Source/ComponentEditor/ui/jucer_ResourceEditorPanel.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ResourceEditorPanel.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_TestComponent_db757dc4.o: ../../Source/ComponentEditor/ui/jucer_TestComponent.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_TestComponent.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_BinaryResources_e0f99b46.o: ../../Source/ComponentEditor/jucer_BinaryResources.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_BinaryResources.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ComponentLayout_6ea00129.o: ../../Source/ComponentEditor/jucer_ComponentLayout.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ComponentLayout.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_GeneratedCode_9ca4ef7e.o: ../../Source/ComponentEditor/jucer_GeneratedCode.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_GeneratedCode.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_JucerDocument_ff8afcc2.o: ../../Source/ComponentEditor/jucer_JucerDocument.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_JucerDocument.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ObjectTypes_4406f01c.o: ../../Source/ComponentEditor/jucer_ObjectTypes.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_ObjectTypes.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_PaintRoutine_e1e891ee.o: ../../Source/ComponentEditor/jucer_PaintRoutine.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_PaintRoutine.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/BinaryData_ce4232d4.o: ../../JuceLibraryCode/BinaryData.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling BinaryData.cpp" | |||
| @@ -16,9 +16,9 @@ | |||
| <key>CFBundleSignature</key> | |||
| <string>????</string> | |||
| <key>CFBundleShortVersionString</key> | |||
| <string>3.0.0</string> | |||
| <string>3.1.0</string> | |||
| <key>CFBundleVersion</key> | |||
| <string>3.0.0</string> | |||
| <string>3.1.0</string> | |||
| <key>NSHumanReadableCopyright</key> | |||
| <string>Raw Material Software Ltd.</string> | |||
| <key>NSHighResolutionCapable</key> | |||
| @@ -38,6 +38,26 @@ | |||
| C9F11BA62D6D092A300363F7 = { isa = PBXBuildFile; fileRef = 0F249640243FBD5717F6ADD9; }; | |||
| F6635694A01FFBF5EF0968DB = { isa = PBXBuildFile; fileRef = 631983AA62673015F8D7453B; }; | |||
| FCE6F604C00039A32649CB69 = { isa = PBXBuildFile; fileRef = 2E680E2C65684A4272AE079A; }; | |||
| 9BF773500BA51A8B5C6C7348 = { isa = PBXBuildFile; fileRef = 65C498761CE166072A202AA0; }; | |||
| 57B1F32A372143B4D3B1C517 = { isa = PBXBuildFile; fileRef = 3E03B7C7A19E63A724EB79F4; }; | |||
| 3DC282564876B1FC88AAA9B3 = { isa = PBXBuildFile; fileRef = 662C76394C5D1B56766FAFD9; }; | |||
| C49E1D32A9DCE3D59BC48B1D = { isa = PBXBuildFile; fileRef = 93B419190CCE92ACAB1ED25B; }; | |||
| E1268E019B434F6B5E9317DC = { isa = PBXBuildFile; fileRef = 1C216FE9B7A5209C5CCF2517; }; | |||
| CE91112DADB97C573C3C674D = { isa = PBXBuildFile; fileRef = 0169ACAA0FAE70CCEEE4F650; }; | |||
| A70F0274076C0D44ED71C980 = { isa = PBXBuildFile; fileRef = EF30A74B566A461A171BBF83; }; | |||
| BD1E0CBE74DDD2F303978E1F = { isa = PBXBuildFile; fileRef = 4E191CDCE7565DB726CF7065; }; | |||
| 8C1CC0E7A772D66635BA482F = { isa = PBXBuildFile; fileRef = 98F42686D9DAC974F2514217; }; | |||
| A69BF71FA90E5A66B6EB2E0F = { isa = PBXBuildFile; fileRef = 9C7FA58D223674C4C2AC6595; }; | |||
| D68DE111AFBD82F0D44A3B69 = { isa = PBXBuildFile; fileRef = B15E33E7342F6EB4F95C9B1D; }; | |||
| EC6A34EC9A9D454BF26AAD32 = { isa = PBXBuildFile; fileRef = 16203C6791259C9718A04C3A; }; | |||
| 8AD28823205783E6F676F254 = { isa = PBXBuildFile; fileRef = DF725A596B7BCD7520CC0A9F; }; | |||
| 34716A3539FD288C09CBA38A = { isa = PBXBuildFile; fileRef = 921752D9B004A15973DDF56F; }; | |||
| 45A53AF13B0D663050632E8C = { isa = PBXBuildFile; fileRef = 9EF583A6201DBC813C2F63C4; }; | |||
| C2A85091A28C907A4E1E1687 = { isa = PBXBuildFile; fileRef = 133F1E428260C5ADDF496DF9; }; | |||
| 83431B7234A78ECFB3C15F63 = { isa = PBXBuildFile; fileRef = 78D0DBC4798FF040FDB90F6D; }; | |||
| 209FCCC2155A1FCB7E11E20D = { isa = PBXBuildFile; fileRef = 269A454F1FF081DA67FFD578; }; | |||
| C93569F47B4AC1A8E37992ED = { isa = PBXBuildFile; fileRef = 9D7689451732AF8333402B3A; }; | |||
| 1B988E139004D8E2850EB656 = { isa = PBXBuildFile; fileRef = C187718F7B9EBA88584B43F3; }; | |||
| 6FC19EBA7A51423C3D22F77B = { isa = PBXBuildFile; fileRef = B483D960309FAFC193F9CDA2; }; | |||
| 3C5267E06A897B0DC0F7EA50 = { isa = PBXBuildFile; fileRef = 472F9A90F685220D730EBF6C; }; | |||
| 7E72CB84146E1B4B168356CA = { isa = PBXBuildFile; fileRef = 38F29C2049566C47993A6D92; }; | |||
| @@ -52,7 +72,9 @@ | |||
| 00376BD04FB81AF9455D45EB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputSource.cpp"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 003CA65912AC8048759478F9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0075C5208947159AF2802F3B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_AudioPluginEditorTemplate.cpp"; path = "../../Source/BinaryData/jucer_AudioPluginEditorTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 008C8B2C2328CFBB9375397D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComboBoxHandler.h"; path = "../../Source/ComponentEditor/components/jucer_ComboBoxHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 00EFEF8A403F4EC9E4D5B7D5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FillType.cpp"; path = "../../../../modules/juce_graphics/colour/juce_FillType.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0169ACAA0FAE70CCEEE4F650 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintElementPath.cpp"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementPath.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 025C33B85E0CCD3E238D4BDC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../../../modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 02C516CEFEE3FE48B492FDC9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Typeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_Typeface.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 02DDC84BAB18E091E2CE8CB3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileLogger.h"; path = "../../../../modules/juce_core/logging/juce_FileLogger.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -62,6 +84,7 @@ | |||
| 045B9C5D21C5C86FED140D81 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsHelpers.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0473C3BCB7A43F710B8EE36C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MACAddress.h"; path = "../../../../modules/juce_core/network/juce_MACAddress.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 04960EE443D073F4CB7121FB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemFactory.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 04C1267B2BD11A6ECCCA654C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentBooleanProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_ComponentBooleanProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 04F31392CA58A2A434CFF7FA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsPostScriptRenderer.cpp"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 04F670E070D31FB66C7DCAEB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LocalisedStrings.cpp"; path = "../../../../modules/juce_core/text/juce_LocalisedStrings.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 05076CDF1511A5F8A8E18F1D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExport_Make.h"; path = "../../Source/Project Saving/jucer_ProjectExport_Make.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -72,6 +95,7 @@ | |||
| 06411E446478986E7E65FE6B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ShapeButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ShapeButton.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 07EF1095F6D45A29AF2A6B6F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserListener.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0819B9CBFBA5F410C41C978A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilenameComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 084C0070BC67BC893B967EF1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ToggleButtonHandler.h"; path = "../../Source/ComponentEditor/components/jucer_ToggleButtonHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 08ADF7FC9BBE70F3C8186215 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentListener.h"; path = "../../../../modules/juce_gui_basics/components/juce_ComponentListener.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 08D19EE7C17DCED7E7BBEEE7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileInputStream.cpp"; path = "../../../../modules/juce_core/files/juce_FileInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0906A934A2797145A64FF423 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TooltipWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -91,14 +115,17 @@ | |||
| 0F2505BCD0232EB95D5199F2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../../../modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0F382FC6B16658EF02D2C4F0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageListener.cpp"; path = "../../../../modules/juce_events/messages/juce_MessageListener.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0FAA46FE4A661AC6F65896CE = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathIterator.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 0FF1C6905150EAAB1AE081A7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ButtonHandler.h"; path = "../../Source/ComponentEditor/components/jucer_ButtonHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1039ABBDCC86BDC9D2663017 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlElement.h"; path = "../../../../modules/juce_core/xml/juce_XmlElement.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1116222363E600327FC672A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageManager.h"; path = "../../../../modules/juce_events/messages/juce_MessageManager.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1125D1B2AE54AEF2EB3D51C0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerDocumentEditor.h"; path = "../../Source/ComponentEditor/ui/jucer_JucerDocumentEditor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 117B5BB797DEC16E103A08F0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInputSource.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 11C55B714FE5D7CAFC35A0C7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageEffectFilter.h"; path = "../../../../modules/juce_graphics/effects/juce_ImageEffectFilter.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1241F3A1FCDF100CD75D5E78 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DragAndDrop.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 125CD8A5E5B57840F5154ACD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Viewport.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1268E54178897254E9A8B94C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextLayout.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 129CDB26CC63D4BC2EB1F2CC = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PerformanceCounter.cpp"; path = "../../../../modules/juce_core/time/juce_PerformanceCounter.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 133F1E428260C5ADDF496DF9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentLayout.cpp"; path = "../../Source/ComponentEditor/jucer_ComponentLayout.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1353717582E55D6E4D074BA5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Files.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 138550CC958D2F029C01B4E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 139C8BAED6DCEE26652651B8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationBase.cpp"; path = "../../../../modules/juce_events/messages/juce_ApplicationBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -112,6 +139,7 @@ | |||
| 157290445D39269EA81887A3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_win32_HiddenMessageWindow.h"; path = "../../../../modules/juce_events/native/juce_win32_HiddenMessageWindow.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 16017456A45F74C692A3AE45 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SVGParser.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_SVGParser.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1614411A8699B82D1F7B0346 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 16203C6791259C9718A04C3A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintRoutinePanel.cpp"; path = "../../Source/ComponentEditor/ui/jucer_PaintRoutinePanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 168F5F32F673036DDAEF1D8D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Atomic.h"; path = "../../../../modules/juce_core/memory/juce_Atomic.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1729AEDC34001C31B8CC357C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_FileHelpers.cpp"; path = "../../Source/Utility/jucer_FileHelpers.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1772B02BAF54F29AD99DF42E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ZipFile.h"; path = "../../../../modules/juce_core/zip/juce_ZipFile.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -134,13 +162,17 @@ | |||
| 1B9552C3FEAFF2071C860987 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ColourSelector.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1BE0A20FB2284A4DDC3A359E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF8.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF8.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1BF5C3F5DC2285FBEF72B697 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTimer.h"; path = "../../../../modules/juce_events/timers/juce_MultiTimer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1C216FE9B7A5209C5CCF2517 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintElement.cpp"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1C666CA3AF0AB4CDCA1D983F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextLayout.h"; path = "../../../../modules/juce_graphics/fonts/juce_TextLayout.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1C76BBCD73ED21571035675F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1D3D6A19A60F0B03DE2F1C14 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementPath.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementPath.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1EC7A8EEAD8ADF43BF014C2C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1F28C0018228A0F749E5658E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileSearchPathListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1F36217CE7A5B1D63D41EA6C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CoreGraphicsContext.mm"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1F421199C40092BFEE0658C2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_RelativePath.h"; path = "../../Source/Utility/jucer_RelativePath.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1F7F2864FE54D79A0C42BE93 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Justification.h"; path = "../../../../modules/juce_graphics/placement/juce_Justification.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1F9BBDFA52513AD34D906D2A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_HyperlinkButtonHandler.h"; path = "../../Source/ComponentEditor/components/jucer_HyperlinkButtonHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 1FA92F8F2B26C6CEC8B1D737 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ButtonDocument.h"; path = "../../Source/ComponentEditor/documents/jucer_ButtonDocument.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 202591AAB1ABCFE458F33F7C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_DrawableButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 206D399250A42034706E5434 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 20FC504E8FB8D30E890A9837 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChoicePropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -170,9 +202,13 @@ | |||
| 25D76CD621FC2A211CF7BB52 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 25E306BB0D875CB0934C405C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PreferencesPanel.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 261EFE631AA08FB2651B78C7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringArray.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 263D9041F9B7D6A79DC38CD6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentLayoutEditor.h"; path = "../../Source/ComponentEditor/ui/jucer_ComponentLayoutEditor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 263F153E8A277E02A3754BBF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToolbarButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 269A454F1FF081DA67FFD578 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_JucerDocument.cpp"; path = "../../Source/ComponentEditor/jucer_JucerDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 26C4A38525D6A327C0102D18 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OldSchoolLookAndFeel.cpp"; path = "../../../../modules/juce_gui_extra/lookandfeel/juce_OldSchoolLookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 271A1D94B96A8B7C949FD8ED = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentMovementWatcher.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 27A2B025813B7E54E0862642 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementUndoableAction.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementUndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 295A9B126C98FE15F5A8B81E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FilePropertyComponent.h"; path = "../../Source/ComponentEditor/properties/jucer_FilePropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 2A060BB0D79BEC3CF644F553 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Clipboard.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_Clipboard.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 2A4B079CDB9C40EB912B6EEB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputSource.h"; path = "../../../../modules/juce_core/streams/juce_FileInputSource.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 2AADCE9D8BADF4DAC05CCA1E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RenderingHelpers.h"; path = "../../../../modules/juce_graphics/native/juce_RenderingHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -206,6 +242,7 @@ | |||
| 32D9A904B4186B64A61FA8CC = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TimeSliceThread.cpp"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 336D0A9B4D15CF866BCE3DFF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentDragger.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3419904525A3F1FF0CC50687 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBasedDocument.cpp"; path = "../../../../modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3514E78B58A08F4C98F54C5A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentLayoutPanel.h"; path = "../../Source/ComponentEditor/ui/jucer_ComponentLayoutPanel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 352DA3794CAAE2400AE8F2E0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../../../modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 35AF9D5F0603CF6CE2D355A1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 35BF11530EF0D771FD94ABDC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -218,6 +255,7 @@ | |||
| 38F29C2049566C47993A6D92 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_core.mm"; path = "../../../../modules/juce_core/juce_core.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3A2888667372BA896AACFBDB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TemporaryFile.h"; path = "../../../../modules/juce_core/files/juce_TemporaryFile.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3A55FEFC24C387D3B29444D5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Result.cpp"; path = "../../../../modules/juce_core/misc/juce_Result.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3A5B5DC92BE6D22CA15B9671 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SnapGridPainter.h"; path = "../../Source/ComponentEditor/ui/jucer_SnapGridPainter.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3AB1D4CECEADD4836ACEEAEE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Time.h"; path = "../../../../modules/juce_core/time/juce_Time.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3AB744A14A560E541723DC9A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Uuid.cpp"; path = "../../../../modules/juce_core/misc/juce_Uuid.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3B061AB9BFD8883A6AE8BCE5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicLibrary.h"; path = "../../../../modules/juce_core/threads/juce_DynamicLibrary.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -226,13 +264,18 @@ | |||
| 3CD57938B4C273D0AA6E6B8B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Path.h"; path = "../../../../modules/juce_graphics/geometry/juce_Path.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3D2B51C71E3676F283B778EA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DragAndDropContainer.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3DBB6D91397AE61D59C90510 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ConcertinaPanel.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3E03B7C7A19E63A724EB79F4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ButtonDocument.cpp"; path = "../../Source/ComponentEditor/documents/jucer_ButtonDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3F00C034B140193B3754969B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ImageResourceProperty.h"; path = "../../Source/ComponentEditor/paintelements/jucer_ImageResourceProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3F1501FE4867042830B25DD5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CustomTypeface.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3F222D26A164E7AD78A33B3D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToggleButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ToggleButton.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3F9D4C7F6E5779D4E4AE655D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentLayout.h"; path = "../../Source/ComponentEditor/jucer_ComponentLayout.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 3FAFD16944A6674164D23914 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_ASCII.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_ASCII.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 400E4C67ABCDDB1D49EBB85E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TabbedComponentHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TabbedComponentHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4076F14FE0016A4DA9087771 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 40A83A20ED109AAAE6D63AF4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableRectangle.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 41105E536155E394E54BDD35 = { isa = PBXFileReference; lastKnownFileType = file.xml; name = "colourscheme_dark.xml"; path = "../../Source/BinaryData/colourscheme_dark.xml"; sourceTree = "SOURCE_ROOT"; }; | |||
| 412B48D0F05D78A73064B36B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TopLevelWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 41CA95403E264AA7457A61F4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementRoundedRectangle.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementRoundedRectangle.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 422524EBD7DA6530970A7872 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadower.h"; path = "../../../../modules/juce_gui_basics/misc/juce_DropShadower.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 42B5C970B8DCD08A864F2208 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StretchableObjectResizer.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 430239E0574C157689D83206 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CodeDocument.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -262,16 +305,22 @@ | |||
| 4BAF0975F0958432B17D0D41 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ProjectTreeViewBase.cpp"; path = "../../Source/Project/jucer_ProjectTreeViewBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4BC9122A6E6496EAF716560E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ListBox.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4C150A1BF98D747EC218A602 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Component.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_Component.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4C2093BCD3528ACEDC7A2B33 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ImageButtonHandler.h"; path = "../../Source/ComponentEditor/components/jucer_ImageButtonHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4CA1C3E6585D7694AA9C309F = { isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = "SOURCE_ROOT"; }; | |||
| 4D6F99ED00A4D8683AF313B2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4D7F53313945ED27A7D16B80 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Result.h"; path = "../../../../modules/juce_core/misc/juce_Result.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4E191CDCE7565DB726CF7065 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentOverlayComponent.cpp"; path = "../../Source/ComponentEditor/ui/jucer_ComponentOverlayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4E259F36C28F1ACDAB4CC73F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModalComponentManager.h"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4E3AE065222C8C87691DF2DE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyListener.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4E5FFE3BE8774948082411F0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4E60769DE992CA7FC1A4A486 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintRoutineEditor.h"; path = "../../Source/ComponentEditor/ui/jucer_PaintRoutineEditor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4E8FE9B1B8C90FC28D56523B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementEllipse.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementEllipse.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4F5843D423E67797070115B3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Timer.cpp"; path = "../../../../modules/juce_events/timers/juce_Timer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 4F687965FBE86EAFDB3ACFEC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../JuceLibraryCode/BinaryData.h; sourceTree = "SOURCE_ROOT"; }; | |||
| 4F88933C6D2AB8A83EB14E16 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LinkedListPointer.h"; path = "../../../../modules/juce_core/containers/juce_LinkedListPointer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 50498FF6EA3901CBD58223B3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ObjectTypes.h"; path = "../../Source/ComponentEditor/jucer_ObjectTypes.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 50672C2FACA36416A9A86310 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_InterprocessConnectionServer.h"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnectionServer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5091B14CC87C6238CF044258 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ElementSiblingComponent.h"; path = "../../Source/ComponentEditor/paintelements/jucer_ElementSiblingComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 50DBEAC56E34B9909BA9C7AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../../../modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 50EF77E1AB95027E82157377 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 514848DA3E69A69AB0099570 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -289,6 +338,7 @@ | |||
| 53CC682B805DD49B6E434A95 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HeapBlock.h"; path = "../../../../modules/juce_core/memory/juce_HeapBlock.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 53DB14312FF9B861739F6747 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AppleRemote.h"; path = "../../../../modules/juce_gui_extra/misc/juce_AppleRemote.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 541BCBB19A86B7E793D397CC = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Thread.cpp"; path = "../../../../modules/juce_core/threads/juce_Thread.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5432B7B9B2CF2EAEC8B66D5C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_UtilityFunctions.h"; path = "../../Source/ComponentEditor/jucer_UtilityFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 54569C1C994F3A0255785EAA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 54747E887C1021F05F172B89 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 553725A0E3A391651ED1731E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FileHelpers.h"; path = "../../Source/Utility/jucer_FileHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -300,6 +350,7 @@ | |||
| 56E8C48ADDEBD48A49C885CB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SplashScreen.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_SplashScreen.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5708CF7899EA21D0B72CDC2A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BlowFish.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_BlowFish.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5745ECDAA4216EE2AF97E5AF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Button.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_Button.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 576D62C0C9C1BA4B7A514721 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PositionPropertyBase.h"; path = "../../Source/ComponentEditor/properties/jucer_PositionPropertyBase.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 578AA1C9D44D2E3AEA5D0278 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 57FD2D74F5DCFF42099CA738 = { isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_extra/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | |||
| 58139D8D454051C59E77609B = { isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = ../../Source/BinaryData/RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -315,6 +366,7 @@ | |||
| 5C82ACC4EE09A1DE1CCEC9A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Primes.cpp"; path = "../../../../modules/juce_cryptography/encryption/juce_Primes.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5CB6ACA0F14EDE47A4F7BCC2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleMessageComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5D5E0592B7C61D523CC40C50 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ValueTree.cpp"; path = "../../../../modules/juce_data_structures/values/juce_ValueTree.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5D9E7814B713670624F0028F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentTypeHandler.h"; path = "../../Source/ComponentEditor/components/jucer_ComponentTypeHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5DBA8C92675235B098946B18 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryOutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryOutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5E674E757BBB4EA2F62B12E9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeRectangle.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 5F04029BEEB2A503B29B13FB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AsyncUpdater.h"; path = "../../../../modules/juce_events/broadcasters/juce_AsyncUpdater.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -333,12 +385,16 @@ | |||
| 6367309B2092121B86FE3AA0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_posix_NamedPipe.cpp"; path = "../../../../modules/juce_core/native/juce_posix_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 63B72B34BC9AC448422EF1A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 63B74F9D9F43393F6427501C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WebBrowserComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_WebBrowserComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 641B57E5FAE6BEFDB6462921 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ResourceEditorPanel.h"; path = "../../Source/ComponentEditor/ui/jucer_ResourceEditorPanel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 64CF8D7D0C97323C1B4F16F2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 65C498761CE166072A202AA0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentTypeHandler.cpp"; path = "../../Source/ComponentEditor/components/jucer_ComponentTypeHandler.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 65F4749184C84C2FDBB4C305 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_AudioPluginFilterTemplate.cpp"; path = "../../Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 662C76394C5D1B56766FAFD9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentDocument.cpp"; path = "../../Source/ComponentEditor/documents/jucer_ComponentDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6658BF44509F89120F6C6F8C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileListComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6670AE915E331809563CA152 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_core.h"; path = "../../../../modules/juce_core/juce_core.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6678E9B3EEACAD47F438B264 = { isa = PBXFileReference; lastKnownFileType = file.nib; name = RecentFilesMenuTemplate.nib; path = RecentFilesMenuTemplate.nib; sourceTree = "SOURCE_ROOT"; }; | |||
| 66A67F1C25A59167AA729C9C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 66B49F08C5EC3E4974825FF8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintRoutine.h"; path = "../../Source/ComponentEditor/jucer_PaintRoutine.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6736FDF36413E6445C526C86 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadPool.cpp"; path = "../../../../modules/juce_core/threads/juce_ThreadPool.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 68351D69C94230D1DCDB8345 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_android_Threads.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 684D88D936EDF46A76EC0538 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -348,7 +404,9 @@ | |||
| 6944804CF7BBD230EDF98E3F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 69A5D13490A62DAE9A7D5A22 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_NewProjectWizard.cpp"; path = "../../Source/Project/jucer_NewProjectWizard.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6A04C2E34DB0C6515FFF160B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Application.cpp"; path = "../../../../modules/juce_gui_basics/application/juce_Application.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6A337C69A928E3CE79C55457 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentChoiceProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_ComponentChoiceProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6AA46ED6C6DDD5A7BC72F686 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../../../modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6AC88EFC247C225CC5C11A43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_BinaryResources.h"; path = "../../Source/ComponentEditor/jucer_BinaryResources.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6B693819BC8F0548179A74AA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6B8796ED91A82AB5A8EB922F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RecentlyOpenedFilesList.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 6B8E7B90EE615FA508709ADF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -378,14 +436,17 @@ | |||
| 7723BAE1917C8A0418F2D23B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 77B05CF7C9BB9778EC06C396 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPress.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyPress.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 784287AD783AB8DDF512956F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_GraphicsContext.cpp"; path = "../../../../modules/juce_graphics/native/juce_android_GraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 786BAF436828865F45314440 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElement.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElement.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 78B148C840109794FED89FAB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadPool.h"; path = "../../../../modules/juce_core/threads/juce_ThreadPool.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 78B2E510278C074CC7BEFD75 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Path.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_Path.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 78CA0E0F336229E2E2F111B0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SourceCodeEditor.h"; path = "../../Source/Code Editor/jucer_SourceCodeEditor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 78D0DBC4798FF040FDB90F6D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_GeneratedCode.cpp"; path = "../../Source/ComponentEditor/jucer_GeneratedCode.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 79339A92305BFB7034095C67 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Label.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 795AF1D634CA3E6FA899E0B0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CharacterFunctions.cpp"; path = "../../../../modules/juce_core/text/juce_CharacterFunctions.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 796AEF1400580E81AAF23CE7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageFileFormat.h"; path = "../../../../modules/juce_graphics/images/juce_ImageFileFormat.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 79B3DE19D706135161A727B0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDiff.h"; path = "../../../../modules/juce_core/text/juce_TextDiff.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 79F7CC3E9B848AAA3A5C682B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PathStrokeType.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_PathStrokeType.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 7A3E96D22F1C9EB4C739834F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PointComponent.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PointComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 7B824A2F1BBE334B140BD8AF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AttributedString.h"; path = "../../../../modules/juce_graphics/fonts/juce_AttributedString.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 7C02936574E000C436E3AD8E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../../../modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 7C48EA717C5B1136A39FF4FB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnection.cpp"; path = "../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -405,6 +466,7 @@ | |||
| 80131CEDAA488DC654996A55 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 808503667FBB423F81780796 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 8090981F07A76E465DAAADF4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ValueSourceHelpers.h"; path = "../../Source/Utility/jucer_ValueSourceHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 8138A55052E9FC27284B74DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FontPropertyComponent.h"; path = "../../Source/ComponentEditor/properties/jucer_FontPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 81A3ACDD205C8F9E424B51F6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_android_JNIHelpers.h"; path = "../../../../modules/juce_core/native/juce_android_JNIHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 81B74E2B42184AD339E89F0B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 820291543BF93243B718F0EE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerTreeViewBase.h"; path = "../../Source/Utility/jucer_JucerTreeViewBase.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -438,6 +500,7 @@ | |||
| 8D12E5100E73E3B7DAA10261 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_events.h"; path = "../../../../modules/juce_events/juce_events.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 8DDA82E1200B61D3B6C526E8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../../../modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 8E00CF4CE2305C5CE5B60E37 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TopLevelWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 8F30A53C7FE4BC65171FB3E2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerDocument.h"; path = "../../Source/ComponentEditor/jucer_JucerDocument.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 8FF39B6B0D9DEB5BBE388A6F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageListener.h"; path = "../../../../modules/juce_events/messages/juce_MessageListener.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9069981E414A631B036CC9AC = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_MainWindow.cpp"; path = "../../Source/Application/jucer_MainWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 90BD70D106A80947463BCB1A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_NamedValueSet.cpp"; path = "../../../../modules/juce_core/containers/juce_NamedValueSet.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -446,9 +509,12 @@ | |||
| 914ADDB50ED7365F08BA91F9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_CodeHelpers.h"; path = "../../Source/Utility/jucer_CodeHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 915ACCF56213FACAB42B427D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModifierKeys.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 920DA9E20EB14DD7D6139DD5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Colours.h"; path = "../../../../modules/juce_graphics/colour/juce_Colours.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 921752D9B004A15973DDF56F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_TestComponent.cpp"; path = "../../Source/ComponentEditor/ui/jucer_TestComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 922DB1DA01DAF63CE86B5E53 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectTreeViewBase.h"; path = "../../Source/Project/jucer_ProjectTreeViewBase.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 925CC15E1449AED03A1CE4F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_GraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 92F91DC29B64AD85B1F508BD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GenericComponentHandler.h"; path = "../../Source/ComponentEditor/components/jucer_GenericComponentHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 939B1B2421964EEF71768BC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OutputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_OutputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 93B419190CCE92ACAB1ED25B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ColouredElement.cpp"; path = "../../Source/ComponentEditor/paintelements/jucer_ColouredElement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 93BD6F4BB776E432A4006696 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Identifier.h"; path = "../../../../modules/juce_core/text/juce_Identifier.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 93D03B2BC76998A3BDA747E8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_AudioPluginModule.h"; path = "../../Source/Project/jucer_AudioPluginModule.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 93D165846B65A638F1C25C4C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectanglePlacement.h"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -457,16 +523,19 @@ | |||
| 9539EC08D70D4719A89A4A30 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_gui_extra.mm"; path = "../../../../modules/juce_gui_extra/juce_gui_extra.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| 953ECF85818382C60F49544B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AffineTransform.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_AffineTransform.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 95CAB4F09E05FDBAED45812E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiTouchMapper.h"; path = "../../../../modules/juce_gui_basics/native/juce_MultiTouchMapper.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 963E0740B7B4D59EF2D16740 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentTemplate.h"; path = "../../Source/BinaryData/jucer_ComponentTemplate.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9683B04CA3BD7F73E8236FE2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ContentCompTemplate.cpp"; path = "../../Source/BinaryData/jucer_ContentCompTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 96972221C7D4CB0FCD5C3E2B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModalComponentManager.cpp"; path = "../../../../modules/juce_gui_basics/components/juce_ModalComponentManager.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 96C105A8CFFC54B429A5B822 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DocumentWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DocumentWindow.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9718703E5D696761B85D25B8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileChooserDialogBox.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 971FD8FEAE9A521A6983B8C9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyMappingEditorComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 974B862C51DA9A16CBBB3A29 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExport_XCode.h"; path = "../../Source/Project Saving/jucer_ProjectExport_XCode.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 97E75A598791645465FEDCE1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_EditingPanelBase.h"; path = "../../Source/ComponentEditor/ui/jucer_EditingPanelBase.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 986707BA1F2C9F7343BD152F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Files.cpp"; path = "../../../../modules/juce_core/native/juce_android_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 988186E582883A70582A40E1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Random.cpp"; path = "../../../../modules/juce_core/maths/juce_Random.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 98A79B670CADD4E020130BAF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBuilder.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 98DC0221D9015F760E4613FE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UndoableAction.h"; path = "../../../../modules/juce_data_structures/undomanager/juce_UndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 98F42686D9DAC974F2514217 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_EditingPanelBase.cpp"; path = "../../Source/ComponentEditor/ui/jucer_EditingPanelBase.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 990F2A6080B28137CCE2D7B9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Singleton.h"; path = "../../../../modules/juce_core/memory/juce_Singleton.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 99557681178F79E2A803C65C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableShape.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 999BC36BBD71BD4117EFDFC4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BubbleComponent.h"; path = "../../../../modules/juce_gui_basics/misc/juce_BubbleComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -484,19 +553,26 @@ | |||
| 9BDE235186FA9648EEECB373 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9BFC2FD520814B736535DB8F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../../../modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9C04F9680F82BF279D528688 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectSaver.h"; path = "../../Source/Project Saving/jucer_ProjectSaver.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9C51394634F102DEBBE6C9EB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementText.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementText.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9C7FA58D223674C4C2AC6595 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_JucerDocumentEditor.cpp"; path = "../../Source/ComponentEditor/ui/jucer_JucerDocumentEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9C803826E5E3FDB1B37660D5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentDocument.h"; path = "../../Source/ComponentEditor/documents/jucer_ComponentDocument.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9C9402994B7971876006AEBB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActionBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9CA825B77B8DA7FD318FCF7C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileFilter.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileFilter.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9D69073057BE050870B38749 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9D7689451732AF8333402B3A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ObjectTypes.cpp"; path = "../../Source/ComponentEditor/jucer_ObjectTypes.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9DE1BC5241C70AF12B327932 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DropShadowEffect.h"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9E36C30D10A1EF9305E8D663 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PropertiesFile.h"; path = "../../../../modules/juce_data_structures/app_properties/juce_PropertiesFile.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9EE339FCA2CFDAE060CB8FE6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CallOutBox.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_CallOutBox.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9EE5D1C3DFDD31D9D8237541 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBoundsConstrainer.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9EF583A6201DBC813C2F63C4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_BinaryResources.cpp"; path = "../../Source/ComponentEditor/jucer_BinaryResources.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9F26333042DFB93B7DFEC870 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MACAddress.cpp"; path = "../../../../modules/juce_core/network/juce_MACAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9F41F3338BF00D0FC74C6390 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TestComponent.h"; path = "../../Source/ComponentEditor/ui/jucer_TestComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9F5483F3EEF0A1E0C71B95A5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| 9F7896DA332F9718CAB6B162 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ReferenceCountedObject.h"; path = "../../../../modules/juce_core/memory/juce_ReferenceCountedObject.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| A004A03A932CDECDED29F19C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../../../modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| A071CAC9920625A3707CF949 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StandardHeader.h"; path = "../../../../modules/juce_core/system/juce_StandardHeader.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| A091C05141DDDF64A0735D05 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WildcardFileFilter.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_WildcardFileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| A0951828C3BF47FA7E1E52F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ViewportHandler.h"; path = "../../Source/ComponentEditor/components/jucer_ViewportHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| A132B5A63CFEF32407ACA5D7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| A17913CCDA69951BC373F637 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../../../modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| A1B4DCE00B10BF7C59F0E603 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../../../modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -527,6 +603,7 @@ | |||
| A9F6985D38A1C25F0C75215B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| A9FA71357C5B2A46A75D9230 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConcertinaPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ConcertinaPanel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| AA2D4949BD61CE8B891731E4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableComposite.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| AA8EED79F095953D2B5923B8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentColourProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_ComponentColourProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| AAA445B64E54BBA12D5E1358 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_osx_ObjCHelpers.h"; path = "../../../../modules/juce_core/native/juce_osx_ObjCHelpers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| AAB313919EE298E25D2EAD19 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TemporaryFile.cpp"; path = "../../../../modules/juce_core/files/juce_TemporaryFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| AACB287C990F7A7C51DE3C5B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeListener.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeListener.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -547,7 +624,11 @@ | |||
| AFDCCE90EAB0DDCE50A5B89A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInputSource.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| AFEBD8423B07599B1DE175A3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ModulesPanel.h"; path = "../../Source/Project/jucer_ModulesPanel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| AFF72BA2B130F3F9AC029080 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_AudioPluginEditorTemplate.h"; path = "../../Source/BinaryData/jucer_AudioPluginEditorTemplate.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B00F60201606F195058BB575 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ColourPropertyComponent.h"; path = "../../Source/ComponentEditor/properties/jucer_ColourPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B01CBF496E7C88105DF4B52A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableShape.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableShape.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B06C7C053DB0660CDA8B5C2C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintRoutinePanel.h"; path = "../../Source/ComponentEditor/ui/jucer_PaintRoutinePanel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B15E33E7342F6EB4F95C9B1D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintRoutineEditor.cpp"; path = "../../Source/ComponentEditor/ui/jucer_PaintRoutineEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| B1963F0D8C0046E54FD9E023 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ColouredElement.h"; path = "../../Source/ComponentEditor/paintelements/jucer_ColouredElement.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B1B44E3A7614189E65CB9FBE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WaitableEvent.h"; path = "../../../../modules/juce_core/threads/juce_WaitableEvent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B1C57BEEEFD26639F1ADFC1C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponentPeer.mm"; path = "../../../../modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| B20A5F49C7E6342B71770D18 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -561,6 +642,7 @@ | |||
| B65C16AB5714B1FBD65AD824 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_EdgeTable.cpp"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| B6C40E843F7E8E7C4768B99E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GZIPDecompressorInputStream.cpp"; path = "../../../../modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| B6D03F8491E288FD4BC31445 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourSelector.h"; path = "../../../../modules/juce_gui_extra/misc/juce_ColourSelector.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B741170E45D74F30B7D5CDDF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentNameProperty.h"; path = "../../Source/ComponentEditor/components/jucer_ComponentNameProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B743DC50150100FFA2DE76AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Strings.mm"; path = "../../../../modules/juce_core/native/juce_mac_Strings.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| B79595279502C1A11A4E8C36 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Point.h"; path = "../../../../modules/juce_graphics/geometry/juce_Point.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| B7BE4498F5A592AAC43F0C93 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DeletedAtShutdown.h"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -578,6 +660,7 @@ | |||
| BBA6060656F685ED7FA52045 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TreeViewTypes.h"; path = "../../Source/Project/jucer_TreeViewTypes.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| BC17B02633EF1E31024051C2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_CodeDocument.cpp"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| BCAD13352CE76BA81629A6E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| BCCFDFB2C02C4AA436C0ECF8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SliderHandler.h"; path = "../../Source/ComponentEditor/components/jucer_SliderHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| BD7C18F07DE633B97B4478E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_PropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| BDBE6F06F82DF5C3BFF53B2B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Slider.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Slider.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| BDCE974230A7401C0E9D28BB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallOutBox.h"; path = "../../../../modules/juce_gui_basics/windows/juce_CallOutBox.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -590,6 +673,8 @@ | |||
| BF3CEF080FA013E2778DCE90 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_Project.h"; path = "../../Source/Project/jucer_Project.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| BF92CA3FD8F9A61AE358D151 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ActionBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| C061E0D3680889C69B1F0E95 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LowLevelGraphicsContext.h"; path = "../../../../modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| C094F3B6A65A79A6DF87C9C2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementGroup.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementGroup.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| C187718F7B9EBA88584B43F3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintRoutine.cpp"; path = "../../Source/ComponentEditor/jucer_PaintRoutine.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| C1FDD2DDB01AC8C4DECB2C10 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableImage.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| C2080119AEDFDE0D477756FA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ConfigPage.h"; path = "../../Source/Project/jucer_ConfigPage.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| C22E03FEBEB6921978C5612A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChangeBroadcaster.h"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -632,18 +717,21 @@ | |||
| CDCAF0EC777DA2884AEB2B59 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| CDDF5BDC75277F7B83A38885 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| CDF8F65F9079B2C14A740F0F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| CE1DFE4E3908943656E180AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| CF0615A1AF1A514A60322B50 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| CF21D9DB3AEC0A4DCAB36A99 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_Icons.cpp"; path = "../../Source/Utility/jucer_Icons.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| CF6C8BD0DA3D8CD4E99EBADA = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; | |||
| CF8011B3C67B609032974DA5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_NewCppFileTemplate.cpp"; path = "../../Source/BinaryData/jucer_NewCppFileTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D00F311BFC3C2625C457CB9B = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; | |||
| D041043D3B554B88F855C174 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D0D8B580D0689FFF4B9B823B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_StrokeType.h"; path = "../../Source/ComponentEditor/paintelements/jucer_StrokeType.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D0F1614CC861E8E0B59B7A06 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D10D51A0A2D63F38B4D86A60 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ResourceFile.cpp"; path = "../../Source/Project Saving/jucer_ResourceFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D141433D3FE81F20490DE928 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D1F9B0E9F5D54FE48BEB46EA = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; | |||
| D2F1CF252F7EC62B35A21CB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D2F80DA0946A5EE01FC016CA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D374DC78AAC02504576AA9B3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GroupComponentHandler.h"; path = "../../Source/ComponentEditor/components/jucer_GroupComponentHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D4444EC6342A2A7BC4F7BC46 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentTextProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_ComponentTextProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D4697A0232AECE5DAC5E332E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D4E56676E2EF83404EDCBA8C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextEditor.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D4F2D42C58F4D86E00E76F31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -653,14 +741,20 @@ | |||
| D5A6D00DEFDC650AF432A698 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Initialisation.h"; path = "../../../../modules/juce_gui_basics/application/juce_Initialisation.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D678882D133090214AF681BC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadLocalValue.h"; path = "../../../../modules/juce_core/threads/juce_ThreadLocalValue.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D75EAC16FAECCC51E3669193 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D7A7F1AA9F313B0CCAAA73A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D87FC8F6834E9DC9C8E88B94 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JustificationProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_JustificationProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D92A6E9404A30EED32DCE4ED = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_RelativePositionedRectangle.h"; path = "../../Source/ComponentEditor/ui/jucer_RelativePositionedRectangle.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D95D7B49EC6C6BDCB5A1B988 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| DA345D5B9DABD049F90DC96F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GeneratedCode.h"; path = "../../Source/ComponentEditor/jucer_GeneratedCode.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| DAF84A553D264705FA6EB6FF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TreeViewHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TreeViewHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| DB20268A566DABEAE3F2CBEE = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| DBE0CDE1B017190ABBFF557C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExport_CodeBlocks.h"; path = "../../Source/Project Saving/jucer_ProjectExport_CodeBlocks.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| DC5E7FF30B01118F6DAEC38F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../../../modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| DC922C6A65D260C18E888E49 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentTemplate.cpp"; path = "../../Source/BinaryData/jucer_ComponentTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| DD00494140C86144306A9356 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../../../modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| DE8DF5D263F40F65581CFDE4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChildProcess.cpp"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| DF725A596B7BCD7520CC0A9F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ResourceEditorPanel.cpp"; path = "../../Source/ComponentEditor/ui/jucer_ResourceEditorPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| DFC6364D81D9C60BD4CA9D12 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeTime.cpp"; path = "../../../../modules/juce_core/time/juce_RelativeTime.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E0F9CA57E44F7F7E7E217E47 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentUndoableAction.h"; path = "../../Source/ComponentEditor/components/jucer_ComponentUndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E2374E15D65425C4101237E2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_NewComponentTemplate.h"; path = "../../Source/BinaryData/jucer_NewComponentTemplate.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E2C1C995D554A3F0A363CE58 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Thread.h"; path = "../../../../modules/juce_core/threads/juce_Thread.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E2DBA3307837B64AFCCD8F8D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_File.cpp"; path = "../../../../modules/juce_core/files/juce_File.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -668,16 +762,18 @@ | |||
| E5D6C36496F5BC84D7213BE8 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; | |||
| E65A820D34BF39478B7C5925 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_DocumentEditorComponent.h"; path = "../../Source/Application/jucer_DocumentEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E6F5CEC32EDC917B054467EF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E720FBCD836FF3AA466C31B6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E7F7033084AC10FB77B0F77A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ConfigPage.cpp"; path = "../../Source/Project/jucer_ConfigPage.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E96597BBC6A98255B51B94DC = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; | |||
| 25F52316D256B4534BED16D1 = { isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Introjucer.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; | |||
| CF0615A1AF1A514A60322B50 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| CE1DFE4E3908943656E180AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D253F74B7F5734984E568CA7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D376B9B54EC944E766AFEC45 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D5057D7B18ABD5E810A6F830 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeface.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D6C91E2BF537F75A80F5C1DB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D780ED33573AED5AD383A036 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D782DA091AD3ECE158FC6A5F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D7A7F1AA9F313B0CCAAA73A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| D800DE818BEDBF4579D15B1D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| D926E13AB5AD647A7A00F486 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| D9342535EA61901A1AD816C6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -697,6 +793,7 @@ | |||
| E284B565DBD647DC0830D23B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E3FF16862AA1B2F943DC616C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E446FFE889CD490FDE3F0F2B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E4BB22E27C5AA4B666F265BD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TextButtonHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TextButtonHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E4E74B2BC3F3CB5A4F4DC55E = { isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../../../modules/juce_gui_basics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; | |||
| E530742870F07704E9616358 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E54D0994D31E20A0A05EBA2B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemTrayIconComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -704,7 +801,6 @@ | |||
| E642193A9990C48CFB6479A9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E654E3A3CD45A888C5F773DF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarModel.h"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E70CA21960A64CCB835725FF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ProjectType.cpp"; path = "../../Source/Project/jucer_ProjectType.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E720FBCD836FF3AA466C31B6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E73C7E17116F6085765622E3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Drawable.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| E7A4604F766ABC8BE26C94A1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeParallelogram.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| E7B6A0CBA0D27A095E83F5B7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -717,6 +813,7 @@ | |||
| E9B8C3CA480AE94BEA852EA9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| EA0D43AB5F47506D5CDA81BB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MultiDocumentPanel.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| EA73C136F52502AA11DB7E15 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MD5.cpp"; path = "../../../../modules/juce_cryptography/hashing/juce_MD5.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| EB71BA07D6F667E69721E577 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GradientPointComponent.h"; path = "../../Source/ComponentEditor/paintelements/jucer_GradientPointComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| EBF7B2DEDAEEB28C1873F580 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_URL.h"; path = "../../../../modules/juce_core/network/juce_URL.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| EC0AF83CFFFCCDE438BCAF25 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TargetPlatform.h"; path = "../../../../modules/juce_core/system/juce_TargetPlatform.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| EC4F3034A642D9E037570D4F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_UnitTest.h"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -726,12 +823,15 @@ | |||
| EE690110171E1648FF2118B8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_Application.h"; path = "../../Source/Application/jucer_Application.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| EE775C35756DC364728D4675 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| EE8504403714A7CE606B5F34 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Logger.h"; path = "../../../../modules/juce_core/logging/juce_Logger.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| EF30A74B566A461A171BBF83 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentLayoutEditor.cpp"; path = "../../Source/ComponentEditor/ui/jucer_ComponentLayoutEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| EFA8CF715611D845AB284500 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerComponentHandler.h"; path = "../../Source/ComponentEditor/components/jucer_JucerComponentHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F03E2BDD36E6F4F53AB767A8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_Headers.h"; path = "../../Source/jucer_Headers.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F07EA5078D6BB60B698F5E12 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_SystemStats.cpp"; path = "../../../../modules/juce_core/native/juce_android_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F08EB921DB62255A4B6DE85A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RectangleList.h"; path = "../../../../modules/juce_graphics/geometry/juce_RectangleList.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F100CFF192886B7699632A62 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Network.mm"; path = "../../../../modules/juce_core/native/juce_mac_Network.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
| F1163B7856FDABA413A88D90 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_NewFileWizard.cpp"; path = "../../Source/Project/jucer_NewFileWizard.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F1164F66F799CEA74174328A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Logger.cpp"; path = "../../../../modules/juce_core/logging/juce_Logger.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F18AE75F1831D13FF53A8CCC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementRectangle.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementRectangle.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F1974B6EDBA502BC36671D7C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ModifierKeys.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F1BEFCAF20EA392DE762B876 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_String.h"; path = "../../../../modules/juce_core/text/juce_String.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F2499004037A1C1D8FEE1FD6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableEdgeComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -739,11 +839,13 @@ | |||
| F2C7DE572E29A3D62EFB40F8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinate.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F406A0F41B2C7A512FDBC9E0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileLogger.cpp"; path = "../../../../modules/juce_core/logging/juce_FileLogger.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F40F5C63CA1098C21B96C80F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F59077841FC17DD07060A2A9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TextEditorHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TextEditorHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F591F5E5E162D4667AC26419 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JSON.cpp"; path = "../../../../modules/juce_core/json/juce_JSON.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F5C02C740A62090A9E9BD25B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F5C453F570A28FD5FA662C1E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileFilter.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileFilter.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F6938A1377A2609D6AEDC120 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeTime.h"; path = "../../../../modules/juce_core/time/juce_RelativeTime.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F6B1C18DDF8DFF1B3767F018 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ArrowButton.cpp"; path = "../../../../modules/juce_gui_basics/buttons/juce_ArrowButton.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F6D3F208B6EE2A50CE1F0A18 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerCommandIDs.h"; path = "../../Source/ComponentEditor/ui/jucer_JucerCommandIDs.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F6FF660331F6CBF9FFC85E88 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F71AF6D2DF3E652F8B51EBAB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ProjectExporter.cpp"; path = "../../Source/Project Saving/jucer_ProjectExporter.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F797071D88542C813CF7222A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_Module.cpp"; path = "../../Source/Project/jucer_Module.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| @@ -758,16 +860,20 @@ | |||
| F94ACCC426AB439B871699E3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_TreeViewTypes.cpp"; path = "../../Source/Project/jucer_TreeViewTypes.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| F994D79D564B5F8D06E6766E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| F9D77BAA08889D69E0C43F25 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SystemTrayIconComponent.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| FA04E39EE7E83D445AF9E406 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FillType.h"; path = "../../Source/ComponentEditor/paintelements/jucer_FillType.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FAC03FFD051FA5B34EE9BA15 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DeletedAtShutdown.cpp"; path = "../../../../modules/juce_events/messages/juce_DeletedAtShutdown.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| FACB4278128DD3C2E2F488DA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../../../modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| FB1B309BB58E2C3F8C8E78F6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlDocument.cpp"; path = "../../../../modules/juce_core/xml/juce_XmlDocument.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| FBBDD70D47163D341B2F0A8D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentOverlayComponent.h"; path = "../../Source/ComponentEditor/ui/jucer_ComponentOverlayComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FBC98F0857AE7FCBD70C7C5C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableImage.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableImage.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FDD33A6837774904810208D5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../../../modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FE283C418E7E545626881FF0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiDocumentPanel.h"; path = "../../../../modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FE90AF2B2BC1106C0D4056BD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PNGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_PNGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| FF04AE9E4F2AAA29AC549461 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../../../modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
| FF10E9B389909FB45E229D5B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComboBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ComboBox.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FF11D6B512FDC5D887E06F66 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementImage.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementImage.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FF1F954094B14C1900C9495D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_posix_SharedCode.h"; path = "../../../../modules/juce_core/native/juce_posix_SharedCode.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| FF94FF5C4BEC605E56149EFC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_LabelHandler.h"; path = "../../Source/ComponentEditor/components/jucer_LabelHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
| ACBAFA7D92DD82AD44ABE68A = { isa = PBXGroup; children = ( | |||
| 441CFEA771BAA50E187342E9, | |||
| 223C4209F18A221EB183A056, | |||
| @@ -840,6 +946,101 @@ | |||
| FC22321797D433148500EDDA = { isa = PBXGroup; children = ( | |||
| 2E680E2C65684A4272AE079A, | |||
| 78CA0E0F336229E2E2F111B0 ); name = "Code Editor"; sourceTree = "<group>"; }; | |||
| DA3DF56D3295CCD84DA4E882 = { isa = PBXGroup; children = ( | |||
| 0FF1C6905150EAAB1AE081A7, | |||
| 008C8B2C2328CFBB9375397D, | |||
| B741170E45D74F30B7D5CDDF, | |||
| 65C498761CE166072A202AA0, | |||
| 5D9E7814B713670624F0028F, | |||
| E0F9CA57E44F7F7E7E217E47, | |||
| 92F91DC29B64AD85B1F508BD, | |||
| D374DC78AAC02504576AA9B3, | |||
| 1F9BBDFA52513AD34D906D2A, | |||
| 4C2093BCD3528ACEDC7A2B33, | |||
| EFA8CF715611D845AB284500, | |||
| FF94FF5C4BEC605E56149EFC, | |||
| BCCFDFB2C02C4AA436C0ECF8, | |||
| 400E4C67ABCDDB1D49EBB85E, | |||
| E4BB22E27C5AA4B666F265BD, | |||
| F59077841FC17DD07060A2A9, | |||
| 084C0070BC67BC893B967EF1, | |||
| DAF84A553D264705FA6EB6FF, | |||
| A0951828C3BF47FA7E1E52F8 ); name = components; sourceTree = "<group>"; }; | |||
| 2BA1ACF18E7E078C7171B162 = { isa = PBXGroup; children = ( | |||
| 3E03B7C7A19E63A724EB79F4, | |||
| 1FA92F8F2B26C6CEC8B1D737, | |||
| 662C76394C5D1B56766FAFD9, | |||
| 9C803826E5E3FDB1B37660D5 ); name = documents; sourceTree = "<group>"; }; | |||
| B3DB7CF28491BD6FFAAC716A = { isa = PBXGroup; children = ( | |||
| 93B419190CCE92ACAB1ED25B, | |||
| B1963F0D8C0046E54FD9E023, | |||
| 5091B14CC87C6238CF044258, | |||
| FA04E39EE7E83D445AF9E406, | |||
| EB71BA07D6F667E69721E577, | |||
| 3F00C034B140193B3754969B, | |||
| 1C216FE9B7A5209C5CCF2517, | |||
| 786BAF436828865F45314440, | |||
| 4E8FE9B1B8C90FC28D56523B, | |||
| C094F3B6A65A79A6DF87C9C2, | |||
| FF11D6B512FDC5D887E06F66, | |||
| 0169ACAA0FAE70CCEEE4F650, | |||
| 1D3D6A19A60F0B03DE2F1C14, | |||
| F18AE75F1831D13FF53A8CCC, | |||
| 41CA95403E264AA7457A61F4, | |||
| 9C51394634F102DEBBE6C9EB, | |||
| 27A2B025813B7E54E0862642, | |||
| 7A3E96D22F1C9EB4C739834F, | |||
| D0D8B580D0689FFF4B9B823B ); name = paintelements; sourceTree = "<group>"; }; | |||
| AECCE15B651C9EBBD07B925F = { isa = PBXGroup; children = ( | |||
| B00F60201606F195058BB575, | |||
| 04C1267B2BD11A6ECCCA654C, | |||
| 6A337C69A928E3CE79C55457, | |||
| AA8EED79F095953D2B5923B8, | |||
| D4444EC6342A2A7BC4F7BC46, | |||
| 295A9B126C98FE15F5A8B81E, | |||
| 8138A55052E9FC27284B74DD, | |||
| D87FC8F6834E9DC9C8E88B94, | |||
| 576D62C0C9C1BA4B7A514721 ); name = properties; sourceTree = "<group>"; }; | |||
| 4FDE8BC3A59AA207C6CE77F8 = { isa = PBXGroup; children = ( | |||
| EF30A74B566A461A171BBF83, | |||
| 263D9041F9B7D6A79DC38CD6, | |||
| 3514E78B58A08F4C98F54C5A, | |||
| 4E191CDCE7565DB726CF7065, | |||
| FBBDD70D47163D341B2F0A8D, | |||
| 98F42686D9DAC974F2514217, | |||
| 97E75A598791645465FEDCE1, | |||
| F6D3F208B6EE2A50CE1F0A18, | |||
| 9C7FA58D223674C4C2AC6595, | |||
| 1125D1B2AE54AEF2EB3D51C0, | |||
| B15E33E7342F6EB4F95C9B1D, | |||
| 4E60769DE992CA7FC1A4A486, | |||
| 16203C6791259C9718A04C3A, | |||
| B06C7C053DB0660CDA8B5C2C, | |||
| D92A6E9404A30EED32DCE4ED, | |||
| DF725A596B7BCD7520CC0A9F, | |||
| 641B57E5FAE6BEFDB6462921, | |||
| 3A5B5DC92BE6D22CA15B9671, | |||
| 921752D9B004A15973DDF56F, | |||
| 9F41F3338BF00D0FC74C6390 ); name = ui; sourceTree = "<group>"; }; | |||
| 825956EA572E23B506C8236F = { isa = PBXGroup; children = ( | |||
| DA3DF56D3295CCD84DA4E882, | |||
| 2BA1ACF18E7E078C7171B162, | |||
| B3DB7CF28491BD6FFAAC716A, | |||
| AECCE15B651C9EBBD07B925F, | |||
| 4FDE8BC3A59AA207C6CE77F8, | |||
| 9EF583A6201DBC813C2F63C4, | |||
| 6AC88EFC247C225CC5C11A43, | |||
| 133F1E428260C5ADDF496DF9, | |||
| 3F9D4C7F6E5779D4E4AE655D, | |||
| 78D0DBC4798FF040FDB90F6D, | |||
| DA345D5B9DABD049F90DC96F, | |||
| 269A454F1FF081DA67FFD578, | |||
| 8F30A53C7FE4BC65171FB3E2, | |||
| 9D7689451732AF8333402B3A, | |||
| 50498FF6EA3901CBD58223B3, | |||
| C187718F7B9EBA88584B43F3, | |||
| 66B49F08C5EC3E4974825FF8, | |||
| 5432B7B9B2CF2EAEC8B66D5C ); name = ComponentEditor; sourceTree = "<group>"; }; | |||
| 88DFD62CB6545EE8CA5C485B = { isa = PBXGroup; children = ( | |||
| 5F4F4EAB042F2730F94A1CEA, | |||
| 301592EBAC0FFF6F5B268E99, | |||
| @@ -850,6 +1051,8 @@ | |||
| AFF72BA2B130F3F9AC029080, | |||
| 65F4749184C84C2FDBB4C305, | |||
| 03D3053EDE47FED1919C6674, | |||
| DC922C6A65D260C18E888E49, | |||
| 963E0740B7B4D59EF2D16740, | |||
| 9683B04CA3BD7F73E8236FE2, | |||
| 35E6EE1E98DD7050DDFECD9B, | |||
| 18D9EBA1DAE45EEF81FD5C8F, | |||
| @@ -867,6 +1070,7 @@ | |||
| E345840128627D533DF908AC, | |||
| D93DED1F5F1B0E49E10A6760, | |||
| FC22321797D433148500EDDA, | |||
| 825956EA572E23B506C8236F, | |||
| 88DFD62CB6545EE8CA5C485B ); name = "The Introjucer"; sourceTree = "<group>"; }; | |||
| ED7BB3F297250D7B43B2A536 = { isa = PBXGroup; children = ( | |||
| 795AF1D634CA3E6FA899E0B0, | |||
| @@ -1754,6 +1958,26 @@ | |||
| C9F11BA62D6D092A300363F7, | |||
| F6635694A01FFBF5EF0968DB, | |||
| FCE6F604C00039A32649CB69, | |||
| 9BF773500BA51A8B5C6C7348, | |||
| 57B1F32A372143B4D3B1C517, | |||
| 3DC282564876B1FC88AAA9B3, | |||
| C49E1D32A9DCE3D59BC48B1D, | |||
| E1268E019B434F6B5E9317DC, | |||
| CE91112DADB97C573C3C674D, | |||
| A70F0274076C0D44ED71C980, | |||
| BD1E0CBE74DDD2F303978E1F, | |||
| 8C1CC0E7A772D66635BA482F, | |||
| A69BF71FA90E5A66B6EB2E0F, | |||
| D68DE111AFBD82F0D44A3B69, | |||
| EC6A34EC9A9D454BF26AAD32, | |||
| 8AD28823205783E6F676F254, | |||
| 34716A3539FD288C09CBA38A, | |||
| 45A53AF13B0D663050632E8C, | |||
| C2A85091A28C907A4E1E1687, | |||
| 83431B7234A78ECFB3C15F63, | |||
| 209FCCC2155A1FCB7E11E20D, | |||
| C93569F47B4AC1A8E37992ED, | |||
| 1B988E139004D8E2850EB656, | |||
| 3C5267E06A897B0DC0F7EA50, | |||
| 7E72CB84146E1B4B168356CA, | |||
| 24AE6B973834AF7E0DE1F228, | |||
| @@ -204,6 +204,102 @@ | |||
| <File RelativePath="..\..\Source\Code Editor\jucer_SourceCodeEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\Code Editor\jucer_SourceCodeEditor.h"/> | |||
| </Filter> | |||
| <Filter Name="ComponentEditor"> | |||
| <Filter Name="components"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComboBoxHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentNameProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentUndoableAction.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_GenericComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_GroupComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_HyperlinkButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ImageButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_JucerComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_LabelHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_SliderHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TabbedComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TextButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TextEditorHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ToggleButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TreeViewHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ViewportHandler.h"/> | |||
| </Filter> | |||
| <Filter Name="documents"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.h"/> | |||
| </Filter> | |||
| <Filter Name="paintelements"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ElementSiblingComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_FillType.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_GradientPointComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ImageResourceProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementEllipse.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementGroup.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementImage.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRectangle.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRoundedRectangle.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementText.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementUndoableAction.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PointComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_StrokeType.h"/> | |||
| </Filter> | |||
| <Filter Name="properties"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ColourPropertyComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentBooleanProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentChoiceProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentColourProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentTextProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_FilePropertyComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_FontPropertyComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_JustificationProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_PositionPropertyBase.h"/> | |||
| </Filter> | |||
| <Filter Name="ui"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutPanel.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_JucerCommandIDs.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_RelativePositionedRectangle.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_SnapGridPainter.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_TestComponent.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_TestComponent.h"/> | |||
| </Filter> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_BinaryResources.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_BinaryResources.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ComponentLayout.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ComponentLayout.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_GeneratedCode.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_GeneratedCode.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_JucerDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_JucerDocument.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ObjectTypes.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ObjectTypes.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_PaintRoutine.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"/> | |||
| </Filter> | |||
| <Filter Name="BinaryData"> | |||
| <File RelativePath="..\..\Source\BinaryData\AudioPluginXCodeScript.txt"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| @@ -286,6 +382,26 @@ | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| </File> | |||
| <File RelativePath="..\..\Source\BinaryData\jucer_ComponentTemplate.cpp"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| <FileConfiguration Name="Release|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| </File> | |||
| <File RelativePath="..\..\Source\BinaryData\jucer_ComponentTemplate.h"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| <FileConfiguration Name="Release|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| </File> | |||
| <File RelativePath="..\..\Source\BinaryData\jucer_ContentCompTemplate.cpp"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| ExcludedFromBuild="true"> | |||
| @@ -7,7 +7,7 @@ | |||
| #include <windows.h> | |||
| VS_VERSION_INFO VERSIONINFO | |||
| FILEVERSION 3,0,0,0 | |||
| FILEVERSION 3,1,0,0 | |||
| BEGIN | |||
| BLOCK "StringFileInfo" | |||
| BEGIN | |||
| @@ -15,9 +15,9 @@ BEGIN | |||
| BEGIN | |||
| VALUE "CompanyName", "Raw Material Software Ltd.\0" | |||
| VALUE "FileDescription", "The Introjucer\0" | |||
| VALUE "FileVersion", "3.0.0\0" | |||
| VALUE "FileVersion", "3.1.0\0" | |||
| VALUE "ProductName", "The Introjucer\0" | |||
| VALUE "ProductVersion", "3.0.0\0" | |||
| VALUE "ProductVersion", "3.1.0\0" | |||
| END | |||
| END | |||
| @@ -204,6 +204,102 @@ | |||
| <File RelativePath="..\..\Source\Code Editor\jucer_SourceCodeEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\Code Editor\jucer_SourceCodeEditor.h"/> | |||
| </Filter> | |||
| <Filter Name="ComponentEditor"> | |||
| <Filter Name="components"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComboBoxHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentNameProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ComponentUndoableAction.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_GenericComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_GroupComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_HyperlinkButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ImageButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_JucerComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_LabelHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_SliderHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TabbedComponentHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TextButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TextEditorHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ToggleButtonHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_TreeViewHandler.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\components\jucer_ViewportHandler.h"/> | |||
| </Filter> | |||
| <Filter Name="documents"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.h"/> | |||
| </Filter> | |||
| <Filter Name="paintelements"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ElementSiblingComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_FillType.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_GradientPointComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_ImageResourceProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementEllipse.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementGroup.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementImage.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRectangle.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRoundedRectangle.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementText.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementUndoableAction.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_PointComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\paintelements\jucer_StrokeType.h"/> | |||
| </Filter> | |||
| <Filter Name="properties"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ColourPropertyComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentBooleanProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentChoiceProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentColourProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_ComponentTextProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_FilePropertyComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_FontPropertyComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_JustificationProperty.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\properties\jucer_PositionPropertyBase.h"/> | |||
| </Filter> | |||
| <Filter Name="ui"> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutPanel.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_JucerCommandIDs.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_RelativePositionedRectangle.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_SnapGridPainter.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_TestComponent.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\ui\jucer_TestComponent.h"/> | |||
| </Filter> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_BinaryResources.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_BinaryResources.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ComponentLayout.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ComponentLayout.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_GeneratedCode.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_GeneratedCode.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_JucerDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_JucerDocument.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ObjectTypes.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_ObjectTypes.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_PaintRoutine.h"/> | |||
| <File RelativePath="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"/> | |||
| </Filter> | |||
| <Filter Name="BinaryData"> | |||
| <File RelativePath="..\..\Source\BinaryData\AudioPluginXCodeScript.txt"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| @@ -286,6 +382,26 @@ | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| </File> | |||
| <File RelativePath="..\..\Source\BinaryData\jucer_ComponentTemplate.cpp"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| <FileConfiguration Name="Release|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| </File> | |||
| <File RelativePath="..\..\Source\BinaryData\jucer_ComponentTemplate.h"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| <FileConfiguration Name="Release|Win32" | |||
| ExcludedFromBuild="true"> | |||
| <Tool Name="VCCLCompilerTool"/> | |||
| </FileConfiguration> | |||
| </File> | |||
| <File RelativePath="..\..\Source\BinaryData\jucer_ContentCompTemplate.cpp"> | |||
| <FileConfiguration Name="Debug|Win32" | |||
| ExcludedFromBuild="true"> | |||
| @@ -7,7 +7,7 @@ | |||
| #include <windows.h> | |||
| VS_VERSION_INFO VERSIONINFO | |||
| FILEVERSION 3,0,0,0 | |||
| FILEVERSION 3,1,0,0 | |||
| BEGIN | |||
| BLOCK "StringFileInfo" | |||
| BEGIN | |||
| @@ -15,9 +15,9 @@ BEGIN | |||
| BEGIN | |||
| VALUE "CompanyName", "Raw Material Software Ltd.\0" | |||
| VALUE "FileDescription", "The Introjucer\0" | |||
| VALUE "FileVersion", "3.0.0\0" | |||
| VALUE "FileVersion", "3.1.0\0" | |||
| VALUE "ProductName", "The Introjucer\0" | |||
| VALUE "ProductVersion", "3.0.0\0" | |||
| VALUE "ProductVersion", "3.1.0\0" | |||
| END | |||
| END | |||
| @@ -152,12 +152,35 @@ | |||
| <ClCompile Include="..\..\Source\Utility\jucer_MiscUtilities.cpp"/> | |||
| <ClCompile Include="..\..\Source\Utility\jucer_StoredSettings.cpp"/> | |||
| <ClCompile Include="..\..\Source\Code Editor\jucer_SourceCodeEditor.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_TestComponent.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_BinaryResources.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_ComponentLayout.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_GeneratedCode.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_JucerDocument.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.cpp"/> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"/> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_AudioPluginEditorTemplate.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_AudioPluginFilterTemplate.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_ComponentTemplate.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_ContentCompTemplate.cpp"> | |||
| <ExcludedFromBuild>true</ExcludedFromBuild> | |||
| </ClCompile> | |||
| @@ -1023,8 +1046,73 @@ | |||
| <ClInclude Include="..\..\Source\Utility\jucer_StoredSettings.h"/> | |||
| <ClInclude Include="..\..\Source\Utility\jucer_ValueSourceHelpers.h"/> | |||
| <ClInclude Include="..\..\Source\Code Editor\jucer_SourceCodeEditor.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ButtonHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComboBoxHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComponentNameProperty.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComponentUndoableAction.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_GenericComponentHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_GroupComponentHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_HyperlinkButtonHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ImageButtonHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_JucerComponentHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_LabelHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_SliderHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TabbedComponentHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TextButtonHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TextEditorHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ToggleButtonHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TreeViewHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ViewportHandler.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_ElementSiblingComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_FillType.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_GradientPointComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_ImageResourceProperty.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementEllipse.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementGroup.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementImage.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRectangle.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRoundedRectangle.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementText.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementUndoableAction.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PointComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_StrokeType.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ColourPropertyComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentBooleanProperty.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentChoiceProperty.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentColourProperty.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentTextProperty.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_FilePropertyComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_FontPropertyComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_JustificationProperty.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_PositionPropertyBase.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutPanel.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_JucerCommandIDs.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_RelativePositionedRectangle.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_SnapGridPainter.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_TestComponent.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_BinaryResources.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_ComponentLayout.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_GeneratedCode.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_JucerDocument.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.h"/> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"/> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_AudioPluginEditorTemplate.h"/> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_AudioPluginFilterTemplate.h"/> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_ComponentTemplate.h"/> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_ContentCompTemplate.h"/> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_NewComponentTemplate.h"/> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_NewCppFileTemplate.h"/> | |||
| @@ -20,6 +20,24 @@ | |||
| <Filter Include="The Introjucer\Code Editor"> | |||
| <UniqueIdentifier>{D05B051C-4835-D6A6-3AF4-B61963EFC368}</UniqueIdentifier> | |||
| </Filter> | |||
| <Filter Include="The Introjucer\ComponentEditor"> | |||
| <UniqueIdentifier>{95DE2FA4-3654-5411-BB7B-2BDDDF07715E}</UniqueIdentifier> | |||
| </Filter> | |||
| <Filter Include="The Introjucer\ComponentEditor\components"> | |||
| <UniqueIdentifier>{073C6BA5-53F9-151C-4BB5-D5C403BF284F}</UniqueIdentifier> | |||
| </Filter> | |||
| <Filter Include="The Introjucer\ComponentEditor\documents"> | |||
| <UniqueIdentifier>{53C392DB-7131-B7AF-5A28-9009B03EF76E}</UniqueIdentifier> | |||
| </Filter> | |||
| <Filter Include="The Introjucer\ComponentEditor\paintelements"> | |||
| <UniqueIdentifier>{CFAABADC-489B-5592-206B-29BE85E556F8}</UniqueIdentifier> | |||
| </Filter> | |||
| <Filter Include="The Introjucer\ComponentEditor\properties"> | |||
| <UniqueIdentifier>{449928FA-2DA7-18CE-61BF-50930E8C94A1}</UniqueIdentifier> | |||
| </Filter> | |||
| <Filter Include="The Introjucer\ComponentEditor\ui"> | |||
| <UniqueIdentifier>{3CBBC95A-4009-C9C5-036C-B226EF4E113E}</UniqueIdentifier> | |||
| </Filter> | |||
| <Filter Include="The Introjucer\BinaryData"> | |||
| <UniqueIdentifier>{768EDA37-3A9B-E5C5-8D35-27FEF74CCBA0}</UniqueIdentifier> | |||
| </Filter> | |||
| @@ -304,12 +322,75 @@ | |||
| <ClCompile Include="..\..\Source\Code Editor\jucer_SourceCodeEditor.cpp"> | |||
| <Filter>The Introjucer\Code Editor</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\documents</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\documents</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\ui\jucer_TestComponent.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_BinaryResources.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_ComponentLayout.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_GeneratedCode.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_JucerDocument.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.cpp"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_AudioPluginEditorTemplate.cpp"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_AudioPluginFilterTemplate.cpp"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_ComponentTemplate.cpp"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\BinaryData\jucer_ContentCompTemplate.cpp"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClCompile> | |||
| @@ -1335,12 +1416,207 @@ | |||
| <ClInclude Include="..\..\Source\Code Editor\jucer_SourceCodeEditor.h"> | |||
| <Filter>The Introjucer\Code Editor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ButtonHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComboBoxHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComponentNameProperty.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComponentTypeHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ComponentUndoableAction.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_GenericComponentHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_GroupComponentHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_HyperlinkButtonHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ImageButtonHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_JucerComponentHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_LabelHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_SliderHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TabbedComponentHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TextButtonHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TextEditorHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ToggleButtonHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_TreeViewHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\components\jucer_ViewportHandler.h"> | |||
| <Filter>The Introjucer\ComponentEditor\components</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\documents\jucer_ButtonDocument.h"> | |||
| <Filter>The Introjucer\ComponentEditor\documents</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\documents\jucer_ComponentDocument.h"> | |||
| <Filter>The Introjucer\ComponentEditor\documents</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_ColouredElement.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_ElementSiblingComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_FillType.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_GradientPointComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_ImageResourceProperty.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElement.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementEllipse.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementGroup.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementImage.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementPath.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRectangle.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementRoundedRectangle.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementText.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PaintElementUndoableAction.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_PointComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\paintelements\jucer_StrokeType.h"> | |||
| <Filter>The Introjucer\ComponentEditor\paintelements</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ColourPropertyComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentBooleanProperty.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentChoiceProperty.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentColourProperty.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_ComponentTextProperty.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_FilePropertyComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_FontPropertyComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_JustificationProperty.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\properties\jucer_PositionPropertyBase.h"> | |||
| <Filter>The Introjucer\ComponentEditor\properties</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutEditor.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ComponentLayoutPanel.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ComponentOverlayComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_EditingPanelBase.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_JucerCommandIDs.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_JucerDocumentEditor.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutineEditor.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_PaintRoutinePanel.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_RelativePositionedRectangle.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_ResourceEditorPanel.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_SnapGridPainter.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\ui\jucer_TestComponent.h"> | |||
| <Filter>The Introjucer\ComponentEditor\ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_BinaryResources.h"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_ComponentLayout.h"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_GeneratedCode.h"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_JucerDocument.h"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_ObjectTypes.h"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_PaintRoutine.h"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\ComponentEditor\jucer_UtilityFunctions.h"> | |||
| <Filter>The Introjucer\ComponentEditor</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_AudioPluginEditorTemplate.h"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_AudioPluginFilterTemplate.h"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_ComponentTemplate.h"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\BinaryData\jucer_ContentCompTemplate.h"> | |||
| <Filter>The Introjucer\BinaryData</Filter> | |||
| </ClInclude> | |||
| @@ -7,7 +7,7 @@ | |||
| #include <windows.h> | |||
| VS_VERSION_INFO VERSIONINFO | |||
| FILEVERSION 3,0,0,0 | |||
| FILEVERSION 3,1,0,0 | |||
| BEGIN | |||
| BLOCK "StringFileInfo" | |||
| BEGIN | |||
| @@ -15,9 +15,9 @@ BEGIN | |||
| BEGIN | |||
| VALUE "CompanyName", "Raw Material Software Ltd.\0" | |||
| VALUE "FileDescription", "The Introjucer\0" | |||
| VALUE "FileVersion", "3.0.0\0" | |||
| VALUE "FileVersion", "3.1.0\0" | |||
| VALUE "ProductName", "The Introjucer\0" | |||
| VALUE "ProductVersion", "3.0.0\0" | |||
| VALUE "ProductVersion", "3.1.0\0" | |||
| END | |||
| END | |||
| @@ -1,7 +1,7 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <JUCERPROJECT id="M70qfTRRk" name="The Introjucer" projectType="guiapp" juceLinkage="amalg_multi" | |||
| juceFolder="../../juce" jucerVersion="3.0.0" version="3.0.0" | |||
| juceFolder="../../juce" jucerVersion="3.1.0" version="3.1.0" | |||
| buildVST="1" buildRTAS="0" buildAU="1" vstFolderMac="~/SDKs/vstsdk2.4" | |||
| vstFolderPC="c:\SDKs\vstsdk2.4" rtasFolderMac="~/SDKs/PT_80_SDK" | |||
| rtasFolderPC="c:\SDKs\PT_80_SDK" pluginName="The Introjucer" | |||
| @@ -204,6 +204,186 @@ | |||
| <FILE id="CygyGGA" name="jucer_SourceCodeEditor.h" compile="0" resource="0" | |||
| file="Source/Code Editor/jucer_SourceCodeEditor.h"/> | |||
| </GROUP> | |||
| <GROUP id="{2CEB6C89-822E-5334-4BA3-EBCA71F15B1D}" name="ComponentEditor"> | |||
| <GROUP id="{991D022D-772C-89CA-9279-97CBE57A95A1}" name="components"> | |||
| <FILE id="rITV4W" name="jucer_ButtonHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_ButtonHandler.h"/> | |||
| <FILE id="ETf5wP" name="jucer_ComboBoxHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_ComboBoxHandler.h"/> | |||
| <FILE id="VYwZMA" name="jucer_ComponentNameProperty.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_ComponentNameProperty.h"/> | |||
| <FILE id="HKreNg" name="jucer_ComponentTypeHandler.cpp" compile="1" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_ComponentTypeHandler.cpp"/> | |||
| <FILE id="qf7M8f" name="jucer_ComponentTypeHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_ComponentTypeHandler.h"/> | |||
| <FILE id="BNNvIv" name="jucer_ComponentUndoableAction.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_ComponentUndoableAction.h"/> | |||
| <FILE id="K8TvLo" name="jucer_GenericComponentHandler.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_GenericComponentHandler.h"/> | |||
| <FILE id="wZGCvQ" name="jucer_GroupComponentHandler.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_GroupComponentHandler.h"/> | |||
| <FILE id="PJxFrK" name="jucer_HyperlinkButtonHandler.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_HyperlinkButtonHandler.h"/> | |||
| <FILE id="YSwPme" name="jucer_ImageButtonHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_ImageButtonHandler.h"/> | |||
| <FILE id="LDl6E2" name="jucer_JucerComponentHandler.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_JucerComponentHandler.h"/> | |||
| <FILE id="KV8ITI" name="jucer_LabelHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_LabelHandler.h"/> | |||
| <FILE id="Ib9vrK" name="jucer_SliderHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_SliderHandler.h"/> | |||
| <FILE id="LE1P9T" name="jucer_TabbedComponentHandler.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/components/jucer_TabbedComponentHandler.h"/> | |||
| <FILE id="yNGaOZ" name="jucer_TextButtonHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_TextButtonHandler.h"/> | |||
| <FILE id="uCcFPZ" name="jucer_TextEditorHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_TextEditorHandler.h"/> | |||
| <FILE id="Vc0nqL" name="jucer_ToggleButtonHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_ToggleButtonHandler.h"/> | |||
| <FILE id="LxUfLS" name="jucer_TreeViewHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_TreeViewHandler.h"/> | |||
| <FILE id="UK7au4" name="jucer_ViewportHandler.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/components/jucer_ViewportHandler.h"/> | |||
| </GROUP> | |||
| <GROUP id="{4205F9F4-CA03-599A-8C9B-E26061861F6F}" name="documents"> | |||
| <FILE id="TYU1VV" name="jucer_ButtonDocument.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/documents/jucer_ButtonDocument.cpp"/> | |||
| <FILE id="X7tlEa" name="jucer_ButtonDocument.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/documents/jucer_ButtonDocument.h"/> | |||
| <FILE id="aKYUKO" name="jucer_ComponentDocument.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/documents/jucer_ComponentDocument.cpp"/> | |||
| <FILE id="QWjkNQ" name="jucer_ComponentDocument.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/documents/jucer_ComponentDocument.h"/> | |||
| </GROUP> | |||
| <GROUP id="{A0FB1797-F730-7BC3-D880-3BA303E7399E}" name="paintelements"> | |||
| <FILE id="inuiZP" name="jucer_ColouredElement.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_ColouredElement.cpp"/> | |||
| <FILE id="HPmBrY" name="jucer_ColouredElement.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_ColouredElement.h"/> | |||
| <FILE id="dJaub3" name="jucer_ElementSiblingComponent.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/paintelements/jucer_ElementSiblingComponent.h"/> | |||
| <FILE id="K7K9w1" name="jucer_FillType.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_FillType.h"/> | |||
| <FILE id="VwZZZW" name="jucer_GradientPointComponent.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/paintelements/jucer_GradientPointComponent.h"/> | |||
| <FILE id="bev2oi" name="jucer_ImageResourceProperty.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/paintelements/jucer_ImageResourceProperty.h"/> | |||
| <FILE id="clRcIu" name="jucer_PaintElement.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElement.cpp"/> | |||
| <FILE id="F4AEGr" name="jucer_PaintElement.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElement.h"/> | |||
| <FILE id="xU4ubN" name="jucer_PaintElementEllipse.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElementEllipse.h"/> | |||
| <FILE id="RcWpm8" name="jucer_PaintElementGroup.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElementGroup.h"/> | |||
| <FILE id="ft5MWO" name="jucer_PaintElementImage.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElementImage.h"/> | |||
| <FILE id="pnsBvh" name="jucer_PaintElementPath.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElementPath.cpp"/> | |||
| <FILE id="TBaAHE" name="jucer_PaintElementPath.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElementPath.h"/> | |||
| <FILE id="dd1jYM" name="jucer_PaintElementRectangle.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/paintelements/jucer_PaintElementRectangle.h"/> | |||
| <FILE id="PFMc79" name="jucer_PaintElementRoundedRectangle.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/paintelements/jucer_PaintElementRoundedRectangle.h"/> | |||
| <FILE id="YIfBIW" name="jucer_PaintElementText.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PaintElementText.h"/> | |||
| <FILE id="yKXEgv" name="jucer_PaintElementUndoableAction.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/paintelements/jucer_PaintElementUndoableAction.h"/> | |||
| <FILE id="M6U5Wv" name="jucer_PointComponent.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_PointComponent.h"/> | |||
| <FILE id="xT3Eb0" name="jucer_StrokeType.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/paintelements/jucer_StrokeType.h"/> | |||
| </GROUP> | |||
| <GROUP id="{721DE2A1-8F94-F2B8-6AD8-BC8B1A9E5705}" name="properties"> | |||
| <FILE id="NLsN0X" name="jucer_ColourPropertyComponent.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_ColourPropertyComponent.h"/> | |||
| <FILE id="DRH56I" name="jucer_ComponentBooleanProperty.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_ComponentBooleanProperty.h"/> | |||
| <FILE id="rfuwQh" name="jucer_ComponentChoiceProperty.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_ComponentChoiceProperty.h"/> | |||
| <FILE id="vEgZwf" name="jucer_ComponentColourProperty.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_ComponentColourProperty.h"/> | |||
| <FILE id="NA8Z1Q" name="jucer_ComponentTextProperty.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_ComponentTextProperty.h"/> | |||
| <FILE id="W8Rfzk" name="jucer_FilePropertyComponent.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_FilePropertyComponent.h"/> | |||
| <FILE id="ro0hFm" name="jucer_FontPropertyComponent.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_FontPropertyComponent.h"/> | |||
| <FILE id="bZrq82" name="jucer_JustificationProperty.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/properties/jucer_JustificationProperty.h"/> | |||
| <FILE id="qg4Jzu" name="jucer_PositionPropertyBase.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/properties/jucer_PositionPropertyBase.h"/> | |||
| </GROUP> | |||
| <GROUP id="{2E376C88-458D-B030-6A17-32378D83EA2C}" name="ui"> | |||
| <FILE id="yUp6KD" name="jucer_ComponentLayoutEditor.cpp" compile="1" | |||
| resource="0" file="Source/ComponentEditor/ui/jucer_ComponentLayoutEditor.cpp"/> | |||
| <FILE id="MSAX1Y" name="jucer_ComponentLayoutEditor.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/ui/jucer_ComponentLayoutEditor.h"/> | |||
| <FILE id="iKlcXq" name="jucer_ComponentLayoutPanel.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_ComponentLayoutPanel.h"/> | |||
| <FILE id="hJ1gT9" name="jucer_ComponentOverlayComponent.cpp" compile="1" | |||
| resource="0" file="Source/ComponentEditor/ui/jucer_ComponentOverlayComponent.cpp"/> | |||
| <FILE id="BFfCA3" name="jucer_ComponentOverlayComponent.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/ui/jucer_ComponentOverlayComponent.h"/> | |||
| <FILE id="jbijT3" name="jucer_EditingPanelBase.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_EditingPanelBase.cpp"/> | |||
| <FILE id="RNGdaa" name="jucer_EditingPanelBase.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_EditingPanelBase.h"/> | |||
| <FILE id="D5pfJg" name="jucer_JucerCommandIDs.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_JucerCommandIDs.h"/> | |||
| <FILE id="HsjExN" name="jucer_JucerDocumentEditor.cpp" compile="1" | |||
| resource="0" file="Source/ComponentEditor/ui/jucer_JucerDocumentEditor.cpp"/> | |||
| <FILE id="b2FF1t" name="jucer_JucerDocumentEditor.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_JucerDocumentEditor.h"/> | |||
| <FILE id="Re59Al" name="jucer_PaintRoutineEditor.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_PaintRoutineEditor.cpp"/> | |||
| <FILE id="mTow9T" name="jucer_PaintRoutineEditor.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_PaintRoutineEditor.h"/> | |||
| <FILE id="g1E8EJ" name="jucer_PaintRoutinePanel.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_PaintRoutinePanel.cpp"/> | |||
| <FILE id="wzRGI9" name="jucer_PaintRoutinePanel.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_PaintRoutinePanel.h"/> | |||
| <FILE id="ktQ4ng" name="jucer_RelativePositionedRectangle.h" compile="0" | |||
| resource="0" file="Source/ComponentEditor/ui/jucer_RelativePositionedRectangle.h"/> | |||
| <FILE id="CFe5dO" name="jucer_ResourceEditorPanel.cpp" compile="1" | |||
| resource="0" file="Source/ComponentEditor/ui/jucer_ResourceEditorPanel.cpp"/> | |||
| <FILE id="S8hsI2" name="jucer_ResourceEditorPanel.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_ResourceEditorPanel.h"/> | |||
| <FILE id="jwLtCu" name="jucer_SnapGridPainter.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_SnapGridPainter.h"/> | |||
| <FILE id="QqRZKi" name="jucer_TestComponent.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_TestComponent.cpp"/> | |||
| <FILE id="mIEmG7" name="jucer_TestComponent.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/ui/jucer_TestComponent.h"/> | |||
| </GROUP> | |||
| <FILE id="q9RAaZ" name="jucer_BinaryResources.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/jucer_BinaryResources.cpp"/> | |||
| <FILE id="sbNvpB" name="jucer_BinaryResources.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/jucer_BinaryResources.h"/> | |||
| <FILE id="smSHM5" name="jucer_ComponentLayout.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/jucer_ComponentLayout.cpp"/> | |||
| <FILE id="MNeOnz" name="jucer_ComponentLayout.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/jucer_ComponentLayout.h"/> | |||
| <FILE id="pxZtWJ" name="jucer_GeneratedCode.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/jucer_GeneratedCode.cpp"/> | |||
| <FILE id="uCwazM" name="jucer_GeneratedCode.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/jucer_GeneratedCode.h"/> | |||
| <FILE id="Ck53JI" name="jucer_JucerDocument.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/jucer_JucerDocument.cpp"/> | |||
| <FILE id="TMo2IM" name="jucer_JucerDocument.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/jucer_JucerDocument.h"/> | |||
| <FILE id="Cg97A0" name="jucer_ObjectTypes.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/jucer_ObjectTypes.cpp"/> | |||
| <FILE id="OXJG49" name="jucer_ObjectTypes.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/jucer_ObjectTypes.h"/> | |||
| <FILE id="sGXKcJ" name="jucer_PaintRoutine.cpp" compile="1" resource="0" | |||
| file="Source/ComponentEditor/jucer_PaintRoutine.cpp"/> | |||
| <FILE id="ctReDx" name="jucer_PaintRoutine.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/jucer_PaintRoutine.h"/> | |||
| <FILE id="DNlSpr" name="jucer_UtilityFunctions.h" compile="0" resource="0" | |||
| file="Source/ComponentEditor/jucer_UtilityFunctions.h"/> | |||
| </GROUP> | |||
| <GROUP id="KPIRFfz" name="BinaryData"> | |||
| <FILE id="RSJcrRl" name="AudioPluginXCodeScript.txt" compile="0" resource="1" | |||
| file="Source/BinaryData/AudioPluginXCodeScript.txt"/> | |||
| @@ -222,6 +402,10 @@ | |||
| resource="1" file="Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp"/> | |||
| <FILE id="pvgTmND" name="jucer_AudioPluginFilterTemplate.h" compile="0" | |||
| resource="1" file="Source/BinaryData/jucer_AudioPluginFilterTemplate.h"/> | |||
| <FILE id="gM9qyy" name="jucer_ComponentTemplate.cpp" compile="0" resource="1" | |||
| file="Source/BinaryData/jucer_ComponentTemplate.cpp"/> | |||
| <FILE id="TSDD99" name="jucer_ComponentTemplate.h" compile="0" resource="1" | |||
| file="Source/BinaryData/jucer_ComponentTemplate.h"/> | |||
| <FILE id="xl685P" name="jucer_ContentCompTemplate.cpp" compile="0" | |||
| resource="1" file="Source/BinaryData/jucer_ContentCompTemplate.cpp"/> | |||
| <FILE id="gFj8Jl" name="jucer_ContentCompTemplate.h" compile="0" resource="1" | |||
| @@ -492,6 +492,151 @@ static const unsigned char temp_62b91564[] = | |||
| const char* jucer_AudioPluginFilterTemplate_h = (const char*) temp_62b91564; | |||
| //================== jucer_ComponentTemplate.cpp ================== | |||
| static const unsigned char temp_8626361b[] = | |||
| "/*\r\n" | |||
| " ==============================================================================\r\n" | |||
| "\r\n" | |||
| " This is an automatically generated GUI class created by the Introjucer!\r\n" | |||
| "\r\n" | |||
| " Be careful when adding custom code to these files, as only the code within\r\n" | |||
| " the \"//[xyz]\" and \"//[/xyz]\" sections will be retained when the file is loaded\r\n" | |||
| " and re-saved.\r\n" | |||
| "\r\n" | |||
| " Created with Introjucer version: %%version%%\r\n" | |||
| "\r\n" | |||
| " ------------------------------------------------------------------------------\r\n" | |||
| "\r\n" | |||
| " The Introjucer is part of the JUCE library - \"Jules' Utility Class Extensions\"\r\n" | |||
| " Copyright 2004-13 by Raw Material Software Ltd.\r\n" | |||
| "\r\n" | |||
| " ==============================================================================\r\n" | |||
| "*/\r\n" | |||
| "\r\n" | |||
| "//[Headers] You can add your own extra header files here...\r\n" | |||
| "//[/Headers]\r\n" | |||
| "\r\n" | |||
| "%%includeFilesCPP%%\r\n" | |||
| "\r\n" | |||
| "//[MiscUserDefs] You can add your own user definitions and misc code here...\r\n" | |||
| "//[/MiscUserDefs]\r\n" | |||
| "\r\n" | |||
| "//==============================================================================\r\n" | |||
| "%%className%%::%%className%% (%%constructorParams%%)\r\n" | |||
| "%%initialisers%%{\r\n" | |||
| " %%constructor%%\r\n" | |||
| "\r\n" | |||
| " //[Constructor] You can add your own custom stuff here..\r\n" | |||
| " //[/Constructor]\r\n" | |||
| "}\r\n" | |||
| "\r\n" | |||
| "%%className%%::~%%className%%()\r\n" | |||
| "{\r\n" | |||
| " //[Destructor_pre]. You can add your own custom destruction code here..\r\n" | |||
| " //[/Destructor_pre]\r\n" | |||
| "\r\n" | |||
| " %%destructor%%\r\n" | |||
| "\r\n" | |||
| " //[Destructor]. You can add your own custom destruction code here..\r\n" | |||
| " //[/Destructor]\r\n" | |||
| "}\r\n" | |||
| "\r\n" | |||
| "//==============================================================================\r\n" | |||
| "%%methodDefinitions%%\r\n" | |||
| "\r\n" | |||
| "//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...\r\n" | |||
| "//[/MiscUserCode]\r\n" | |||
| "\r\n" | |||
| "\r\n" | |||
| "//==============================================================================\r\n" | |||
| "#if 0\r\n" | |||
| "/* -- Introjucer information section --\r\n" | |||
| "\r\n" | |||
| " This is where the Introjucer stores the metadata that describe this GUI layout, so \r\n" | |||
| " make changes in here at your peril!\r\n" | |||
| "\r\n" | |||
| "BEGIN_JUCER_METADATA\r\n" | |||
| "\r\n" | |||
| "%%metadata%%\r\n" | |||
| "END_JUCER_METADATA\r\n" | |||
| "*/\r\n" | |||
| "#endif\r\n" | |||
| "\r\n" | |||
| "%%staticMemberDefinitions%%\r\n" | |||
| "//[EndFile] You can add extra defines here...\r\n" | |||
| "//[/EndFile]\r\n"; | |||
| const char* jucer_ComponentTemplate_cpp = (const char*) temp_8626361b; | |||
| //================== jucer_ComponentTemplate.h ================== | |||
| static const unsigned char temp_363772e0[] = | |||
| "/*\r\n" | |||
| " ==============================================================================\r\n" | |||
| "\r\n" | |||
| " This is an automatically generated GUI class created by the Introjucer!\r\n" | |||
| "\r\n" | |||
| " Be careful when adding custom code to these files, as only the code within\r\n" | |||
| " the \"//[xyz]\" and \"//[/xyz]\" sections will be retained when the file is loaded\r\n" | |||
| " and re-saved.\r\n" | |||
| "\r\n" | |||
| " Created with Introjucer version: %%version%%\r\n" | |||
| "\r\n" | |||
| " ------------------------------------------------------------------------------\r\n" | |||
| "\r\n" | |||
| " The Introjucer is part of the JUCE library - \"Jules' Utility Class Extensions\"\r\n" | |||
| " Copyright 2004-13 by Raw Material Software Ltd.\r\n" | |||
| "\r\n" | |||
| " ==============================================================================\r\n" | |||
| "*/\r\n" | |||
| "\r\n" | |||
| "#ifndef %%headerGuard%%\r\n" | |||
| "#define %%headerGuard%%\r\n" | |||
| "\r\n" | |||
| "//[Headers] -- You can add your own extra header files here --\r\n" | |||
| "#include \"JuceHeader.h\"\r\n" | |||
| "//[/Headers]\r\n" | |||
| "\r\n" | |||
| "%%includeFilesH%%\r\n" | |||
| "\r\n" | |||
| "//==============================================================================\r\n" | |||
| "/**\r\n" | |||
| " //[Comments]\r\n" | |||
| " An auto-generated component, created by the Introjucer.\r\n" | |||
| "\r\n" | |||
| " Describe your class and how it works here!\r\n" | |||
| " //[/Comments]\r\n" | |||
| "*/\r\n" | |||
| "%%classDeclaration%%\r\n" | |||
| "{\r\n" | |||
| "public:\r\n" | |||
| " //==============================================================================\r\n" | |||
| " %%className%% (%%constructorParams%%);\r\n" | |||
| " ~%%className%%();\r\n" | |||
| "\r\n" | |||
| " //==============================================================================\r\n" | |||
| " //[UserMethods] -- You can add your own custom methods in this section.\r\n" | |||
| " //[/UserMethods]\r\n" | |||
| "\r\n" | |||
| " %%publicMemberDeclarations%%\r\n" | |||
| "\r\n" | |||
| "private:\r\n" | |||
| " //[UserVariables] -- You can add your own custom variables in this section.\r\n" | |||
| " //[/UserVariables]\r\n" | |||
| "\r\n" | |||
| " //==============================================================================\r\n" | |||
| " %%privateMemberDeclarations%%\r\n" | |||
| "\r\n" | |||
| " //==============================================================================\r\n" | |||
| " JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%className%%)\r\n" | |||
| "};\r\n" | |||
| "\r\n" | |||
| "//[EndFile] You can add extra defines here...\r\n" | |||
| "//[/EndFile]\r\n" | |||
| "\r\n" | |||
| "#endif // %%headerGuard%%\r\n"; | |||
| const char* jucer_ComponentTemplate_h = (const char*) temp_363772e0; | |||
| //================== jucer_ContentCompTemplate.cpp ================== | |||
| static const unsigned char temp_7e4c4c06[] = | |||
| "/*\r\n" | |||
| @@ -1025,6 +1170,8 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw | |||
| case 0x4d0721bf: numBytes = 799; return jucer_AudioPluginEditorTemplate_h; | |||
| case 0x51b49ac5: numBytes = 4638; return jucer_AudioPluginFilterTemplate_cpp; | |||
| case 0x488afa0a: numBytes = 2488; return jucer_AudioPluginFilterTemplate_h; | |||
| case 0xabad7041: numBytes = 2085; return jucer_ComponentTemplate_cpp; | |||
| case 0xfc72fe86: numBytes = 2158; return jucer_ComponentTemplate_h; | |||
| case 0x0b66646c: numBytes = 886; return jucer_ContentCompTemplate_cpp; | |||
| case 0x6fa10171: numBytes = 924; return jucer_ContentCompTemplate_h; | |||
| case 0x8905395b: numBytes = 470; return jucer_MainConsoleAppTemplate_cpp; | |||
| @@ -30,6 +30,12 @@ namespace BinaryData | |||
| extern const char* jucer_AudioPluginFilterTemplate_h; | |||
| const int jucer_AudioPluginFilterTemplate_hSize = 2488; | |||
| extern const char* jucer_ComponentTemplate_cpp; | |||
| const int jucer_ComponentTemplate_cppSize = 2085; | |||
| extern const char* jucer_ComponentTemplate_h; | |||
| const int jucer_ComponentTemplate_hSize = 2158; | |||
| extern const char* jucer_ContentCompTemplate_cpp; | |||
| const int jucer_ContentCompTemplate_cppSize = 886; | |||
| @@ -32,8 +32,8 @@ | |||
| namespace ProjectInfo | |||
| { | |||
| const char* const projectName = "The Introjucer"; | |||
| const char* const versionString = "3.0.0"; | |||
| const int versionNumber = 0x30000; | |||
| const char* const versionString = "3.1.0"; | |||
| const int versionNumber = 0x30100; | |||
| } | |||
| #endif // __APPHEADERFILE_M70QFTRRK__ | |||
| @@ -32,6 +32,8 @@ | |||
| #include "jucer_CommandLine.h" | |||
| #include "../Code Editor/jucer_SourceCodeEditor.h" | |||
| void createGUIEditorMenu (PopupMenu&); | |||
| void registerGUIEditorCommands(); | |||
| //============================================================================== | |||
| class IntrojucerApp : public JUCEApplication | |||
| @@ -39,7 +41,6 @@ class IntrojucerApp : public JUCEApplication | |||
| public: | |||
| //============================================================================== | |||
| IntrojucerApp() : isRunningCommandLine (false) {} | |||
| ~IntrojucerApp() {} | |||
| //============================================================================== | |||
| void initialise (const String& commandLine) | |||
| @@ -71,14 +72,7 @@ public: | |||
| icons = new Icons(); | |||
| commandManager = new ApplicationCommandManager(); | |||
| commandManager->registerAllCommandsForTarget (this); | |||
| { | |||
| CodeDocument doc; | |||
| CppCodeEditorComponent ed (File::nonexistent, doc); | |||
| commandManager->registerAllCommandsForTarget (&ed); | |||
| } | |||
| initCommandManager(); | |||
| menuModel = new MainMenuModel(); | |||
| @@ -145,15 +139,8 @@ public: | |||
| } | |||
| //============================================================================== | |||
| const String getApplicationName() | |||
| { | |||
| return "Introjucer"; | |||
| } | |||
| const String getApplicationVersion() | |||
| { | |||
| return ProjectInfo::versionString; | |||
| } | |||
| const String getApplicationName() { return "Introjucer"; } | |||
| const String getApplicationVersion() { return ProjectInfo::versionString; } | |||
| bool moreThanOneInstanceAllowed() | |||
| { | |||
| @@ -202,10 +189,10 @@ public: | |||
| } | |||
| else if (menuItemID >= activeDocumentsBaseID && menuItemID < activeDocumentsBaseID + 200) | |||
| { | |||
| OpenDocumentManager::Document* doc = getApp().openDocumentManager.getOpenDocument (menuItemID - activeDocumentsBaseID); | |||
| jassert (doc != nullptr); | |||
| getApp().mainWindowList.openDocument (doc, true); | |||
| if (OpenDocumentManager::Document* doc = getApp().openDocumentManager.getOpenDocument (menuItemID - activeDocumentsBaseID)) | |||
| getApp().mainWindowList.openDocument (doc, true); | |||
| else | |||
| jassertfalse; | |||
| } | |||
| else if (menuItemID >= colourSchemeBaseID && menuItemID < colourSchemeBaseID + 200) | |||
| { | |||
| @@ -223,7 +210,7 @@ public: | |||
| virtual StringArray getMenuNames() | |||
| { | |||
| const char* const names[] = { "File", "Edit", "View", "Window", "Tools", nullptr }; | |||
| const char* const names[] = { "File", "Edit", "View", "Window", "Jucer", "Tools", nullptr }; | |||
| return StringArray (names); | |||
| } | |||
| @@ -234,6 +221,7 @@ public: | |||
| else if (menuName == "View") createViewMenu (menu); | |||
| else if (menuName == "Window") createWindowMenu (menu); | |||
| else if (menuName == "Tools") createToolsMenu (menu); | |||
| else if (menuName == "Jucer") createGUIEditorMenu (menu); | |||
| else jassertfalse; // names have changed? | |||
| } | |||
| @@ -568,6 +556,20 @@ private: | |||
| JUCE_DECLARE_NON_COPYABLE (AsyncQuitRetrier) | |||
| }; | |||
| void initCommandManager() | |||
| { | |||
| commandManager = new ApplicationCommandManager(); | |||
| commandManager->registerAllCommandsForTarget (this); | |||
| { | |||
| CodeDocument doc; | |||
| CppCodeEditorComponent ed (File::nonexistent, doc); | |||
| commandManager->registerAllCommandsForTarget (&ed); | |||
| } | |||
| registerGUIEditorCommands(); | |||
| } | |||
| }; | |||
| @@ -70,7 +70,7 @@ public: | |||
| if (file.getFileExtension().isNotEmpty()) | |||
| return file.getFileExtension() + " file"; | |||
| jassertfalse | |||
| jassertfalse; | |||
| return "Unknown"; | |||
| } | |||
| @@ -84,10 +84,13 @@ private: | |||
| //============================================================================== | |||
| OpenDocumentManager::DocumentType* createGUIDocumentType(); | |||
| OpenDocumentManager::OpenDocumentManager() | |||
| { | |||
| registerType (new UnknownDocument::Type()); | |||
| registerType (new SourceCodeDocument::Type()); | |||
| registerType (createGUIDocumentType()); | |||
| } | |||
| OpenDocumentManager::~OpenDocumentManager() | |||
| @@ -195,10 +198,8 @@ bool OpenDocumentManager::closeDocument (int index, bool saveIfNeeded) | |||
| if (Document* doc = documents [index]) | |||
| { | |||
| if (saveIfNeeded) | |||
| { | |||
| if (saveIfNeededAndUserAgrees (doc) != FileBasedDocument::savedOk) | |||
| return false; | |||
| } | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| listeners.getUnchecked(i)->documentAboutToClose (doc); | |||
| @@ -0,0 +1,71 @@ | |||
| /* | |||
| ============================================================================== | |||
| This is an automatically generated GUI class created by the Introjucer! | |||
| Be careful when adding custom code to these files, as only the code within | |||
| the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded | |||
| and re-saved. | |||
| Created with Introjucer version: %%version%% | |||
| ------------------------------------------------------------------------------ | |||
| The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-13 by Raw Material Software Ltd. | |||
| ============================================================================== | |||
| */ | |||
| //[Headers] You can add your own extra header files here... | |||
| //[/Headers] | |||
| %%includeFilesCPP%% | |||
| //[MiscUserDefs] You can add your own user definitions and misc code here... | |||
| //[/MiscUserDefs] | |||
| //============================================================================== | |||
| %%className%%::%%className%% (%%constructorParams%%) | |||
| %%initialisers%%{ | |||
| %%constructor%% | |||
| //[Constructor] You can add your own custom stuff here.. | |||
| //[/Constructor] | |||
| } | |||
| %%className%%::~%%className%%() | |||
| { | |||
| //[Destructor_pre]. You can add your own custom destruction code here.. | |||
| //[/Destructor_pre] | |||
| %%destructor%% | |||
| //[Destructor]. You can add your own custom destruction code here.. | |||
| //[/Destructor] | |||
| } | |||
| //============================================================================== | |||
| %%methodDefinitions%% | |||
| //[MiscUserCode] You can add your own definitions of your custom methods or any other code here... | |||
| //[/MiscUserCode] | |||
| //============================================================================== | |||
| #if 0 | |||
| /* -- Introjucer information section -- | |||
| This is where the Introjucer stores the metadata that describe this GUI layout, so | |||
| make changes in here at your peril! | |||
| BEGIN_JUCER_METADATA | |||
| %%metadata%% | |||
| END_JUCER_METADATA | |||
| */ | |||
| #endif | |||
| %%staticMemberDefinitions%% | |||
| //[EndFile] You can add extra defines here... | |||
| //[/EndFile] | |||
| @@ -0,0 +1,64 @@ | |||
| /* | |||
| ============================================================================== | |||
| This is an automatically generated GUI class created by the Introjucer! | |||
| Be careful when adding custom code to these files, as only the code within | |||
| the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded | |||
| and re-saved. | |||
| Created with Introjucer version: %%version%% | |||
| ------------------------------------------------------------------------------ | |||
| The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-13 by Raw Material Software Ltd. | |||
| ============================================================================== | |||
| */ | |||
| #ifndef %%headerGuard%% | |||
| #define %%headerGuard%% | |||
| //[Headers] -- You can add your own extra header files here -- | |||
| #include "JuceHeader.h" | |||
| //[/Headers] | |||
| %%includeFilesH%% | |||
| //============================================================================== | |||
| /** | |||
| //[Comments] | |||
| An auto-generated component, created by the Introjucer. | |||
| Describe your class and how it works here! | |||
| //[/Comments] | |||
| */ | |||
| %%classDeclaration%% | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| %%className%% (%%constructorParams%%); | |||
| ~%%className%%(); | |||
| //============================================================================== | |||
| //[UserMethods] -- You can add your own custom methods in this section. | |||
| //[/UserMethods] | |||
| %%publicMemberDeclarations%% | |||
| private: | |||
| //[UserVariables] -- You can add your own custom variables in this section. | |||
| //[/UserVariables] | |||
| //============================================================================== | |||
| %%privateMemberDeclarations%% | |||
| //============================================================================== | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (%%className%%) | |||
| }; | |||
| //[EndFile] You can add extra defines here... | |||
| //[/EndFile] | |||
| #endif // %%headerGuard%% | |||
| @@ -0,0 +1,381 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class ButtonHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| ButtonHandler (const String& typeDescription_, | |||
| const String& className_, | |||
| const std::type_info& componentClass, | |||
| const int defaultWidth_, | |||
| const int defaultHeight_) | |||
| : ComponentTypeHandler (typeDescription_, className_, componentClass, | |||
| defaultWidth_, defaultHeight_) | |||
| {} | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| Button* const b = dynamic_cast <Button*> (component); | |||
| properties.add (new ButtonTextProperty (b, document)); | |||
| properties.add (new ButtonCallbackProperty (b, document)); | |||
| properties.add (new ButtonRadioGroupProperty (b, document)); | |||
| properties.add (new ButtonConnectedEdgeProperty ("connected left", Button::ConnectedOnLeft, b, document)); | |||
| properties.add (new ButtonConnectedEdgeProperty ("connected right", Button::ConnectedOnRight, b, document)); | |||
| properties.add (new ButtonConnectedEdgeProperty ("connected top", Button::ConnectedOnTop, b, document)); | |||
| properties.add (new ButtonConnectedEdgeProperty ("connected bottom", Button::ConnectedOnBottom, b, document)); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| Button* const b = dynamic_cast <Button*> (comp); | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("buttonText", b->getButtonText()); | |||
| e->setAttribute ("connectedEdges", b->getConnectedEdgeFlags()); | |||
| e->setAttribute ("needsCallback", needsButtonListener (b)); | |||
| e->setAttribute ("radioGroupId", b->getRadioGroupId()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| Button* const b = dynamic_cast <Button*> (comp); | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| b->setButtonText (xml.getStringAttribute ("buttonText", b->getButtonText())); | |||
| b->setConnectedEdges (xml.getIntAttribute ("connectedEdges", 0)); | |||
| setNeedsButtonListener (b, xml.getBoolAttribute ("needsCallback", true)); | |||
| b->setRadioGroupId (xml.getIntAttribute ("radioGroupId", 0)); | |||
| return true; | |||
| } | |||
| String getCreationParameters (Component* component) | |||
| { | |||
| return quotedString (component->getName()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| Button* const b = dynamic_cast <Button*> (component); | |||
| if (b->getButtonText() != b->getName()) | |||
| { | |||
| code.constructorCode | |||
| << memberVariableName << "->setButtonText (" | |||
| << quotedString (b->getButtonText()) << ");\n"; | |||
| } | |||
| if (b->getConnectedEdgeFlags() != 0) | |||
| { | |||
| StringArray flags; | |||
| if (b->isConnectedOnLeft()) | |||
| flags.add ("Button::ConnectedOnLeft"); | |||
| if (b->isConnectedOnRight()) | |||
| flags.add ("Button::ConnectedOnRight"); | |||
| if (b->isConnectedOnTop()) | |||
| flags.add ("Button::ConnectedOnTop"); | |||
| if (b->isConnectedOnBottom()) | |||
| flags.add ("Button::ConnectedOnBottom"); | |||
| String s; | |||
| s << memberVariableName << "->setConnectedEdges (" | |||
| << flags.joinIntoString (" | ") << ");\n"; | |||
| code.constructorCode += s; | |||
| } | |||
| if (b->getRadioGroupId() != 0) | |||
| code.constructorCode << memberVariableName << "->setRadioGroupId (" | |||
| << b->getRadioGroupId() << ");\n"; | |||
| if (needsButtonListener (component)) | |||
| code.constructorCode << memberVariableName << "->addListener (this);\n"; | |||
| } | |||
| void fillInGeneratedCode (Component* component, GeneratedCode& code) | |||
| { | |||
| ComponentTypeHandler::fillInGeneratedCode (component, code); | |||
| if (needsButtonListener (component)) | |||
| { | |||
| String& callback = code.getCallbackCode ("public ButtonListener", | |||
| "void", | |||
| "buttonClicked (Button* buttonThatWasClicked)", | |||
| true); | |||
| if (callback.isNotEmpty()) | |||
| callback << "else "; | |||
| const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component)); | |||
| const String userCodeComment ("UserButtonCode_" + memberVariableName); | |||
| callback | |||
| << "if (buttonThatWasClicked == " << memberVariableName | |||
| << ")\n{\n //[" << userCodeComment << "] -- add your button handler code here..\n //[/" << userCodeComment << "]\n}\n"; | |||
| } | |||
| } | |||
| static bool needsButtonListener (Component* button) | |||
| { | |||
| return button->getProperties().getWithDefault ("generateListenerCallback", true); | |||
| } | |||
| static void setNeedsButtonListener (Component* button, const bool shouldDoCallback) | |||
| { | |||
| button->getProperties().set ("generateListenerCallback", shouldDoCallback); | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class ButtonTextProperty : public ComponentTextProperty <Button> | |||
| { | |||
| public: | |||
| ButtonTextProperty (Button* button_, JucerDocument& doc) | |||
| : ComponentTextProperty <Button> ("text", 100, false, button_, doc) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ButtonTextChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change button text"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getButtonText(); | |||
| } | |||
| private: | |||
| class ButtonTextChangeAction : public ComponentUndoableAction <Button> | |||
| { | |||
| public: | |||
| ButtonTextChangeAction (Button* const comp, ComponentLayout& layout, const String& newName_) | |||
| : ComponentUndoableAction <Button> (comp, layout), | |||
| newName (newName_) | |||
| { | |||
| oldName = comp->getButtonText(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setButtonText (newName); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setButtonText (oldName); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newName, oldName; | |||
| }; | |||
| }; | |||
| class ButtonCallbackProperty : public ComponentBooleanProperty <Button> | |||
| { | |||
| public: | |||
| ButtonCallbackProperty (Button* button, JucerDocument& document) | |||
| : ComponentBooleanProperty <Button> ("callback", "Generate ButtonListener", "Generate ButtonListener", button, document) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new ButtonCallbackChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change button callback"); | |||
| } | |||
| bool getState() const { return needsButtonListener (component); } | |||
| private: | |||
| class ButtonCallbackChangeAction : public ComponentUndoableAction <Button> | |||
| { | |||
| public: | |||
| ButtonCallbackChangeAction (Button* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <Button> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = needsButtonListener (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| setNeedsButtonListener (getComponent(), newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| setNeedsButtonListener (getComponent(), oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| class ButtonRadioGroupProperty : public ComponentTextProperty <Button> | |||
| { | |||
| public: | |||
| ButtonRadioGroupProperty (Button* const button_, JucerDocument& doc) | |||
| : ComponentTextProperty <Button> ("radio group", 10, false, button_, doc) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ButtonRadioGroupChangeAction (component, *document.getComponentLayout(), newText.getIntValue()), | |||
| "Change radio group ID"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return String (component->getRadioGroupId()); | |||
| } | |||
| private: | |||
| class ButtonRadioGroupChangeAction : public ComponentUndoableAction <Button> | |||
| { | |||
| public: | |||
| ButtonRadioGroupChangeAction (Button* const comp, ComponentLayout& layout, const int newId_) | |||
| : ComponentUndoableAction <Button> (comp, layout), | |||
| newId (newId_) | |||
| { | |||
| oldId = comp->getRadioGroupId(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setRadioGroupId (newId); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setRadioGroupId (oldId); | |||
| changed(); | |||
| return true; | |||
| } | |||
| int newId, oldId; | |||
| }; | |||
| }; | |||
| class ButtonConnectedEdgeProperty : public ComponentBooleanProperty <Button> | |||
| { | |||
| public: | |||
| ButtonConnectedEdgeProperty (const String& name, const int flag_, | |||
| Button* button, JucerDocument& document) | |||
| : ComponentBooleanProperty <Button> (name, "Connected", "Connected", button, document), | |||
| flag (flag_) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new ButtonConnectedChangeAction (component, *document.getComponentLayout(), flag, newState), | |||
| "Change button connected edges"); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return (component->getConnectedEdgeFlags() & flag) != 0; | |||
| } | |||
| private: | |||
| const int flag; | |||
| class ButtonConnectedChangeAction : public ComponentUndoableAction <Button> | |||
| { | |||
| public: | |||
| ButtonConnectedChangeAction (Button* const comp, ComponentLayout& layout, const int flag_, const bool newState_) | |||
| : ComponentUndoableAction <Button> (comp, layout), | |||
| flag (flag_), | |||
| newState (newState_) | |||
| { | |||
| oldState = ((comp->getConnectedEdgeFlags() & flag) != 0); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| if (newState) | |||
| getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag); | |||
| else | |||
| getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| if (oldState) | |||
| getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag); | |||
| else | |||
| getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag); | |||
| changed(); | |||
| return true; | |||
| } | |||
| const int flag; | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,429 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class ComboBoxHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| ComboBoxHandler() | |||
| : ComponentTypeHandler ("Combo Box", "ComboBox", typeid (ComboBox), 150, 24) | |||
| {} | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new ComboBox ("new combo box"); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| ComboBox* const c = dynamic_cast <ComboBox*> (comp); | |||
| jassert (c != nullptr); | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("editable", c->isTextEditable()); | |||
| e->setAttribute ("layout", c->getJustificationType().getFlags()); | |||
| e->setAttribute ("items", c->getProperties() ["items"].toString()); | |||
| e->setAttribute ("textWhenNonSelected", c->getTextWhenNothingSelected()); | |||
| e->setAttribute ("textWhenNoItems", c->getTextWhenNoChoicesAvailable()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| ComboBox defaultBox (String::empty); | |||
| ComboBox* const c = dynamic_cast <ComboBox*> (comp); | |||
| jassert (c != nullptr); | |||
| c->setEditableText (xml.getBoolAttribute ("editable", defaultBox.isTextEditable())); | |||
| c->setJustificationType (Justification (xml.getIntAttribute ("layout", defaultBox.getJustificationType().getFlags()))); | |||
| c->getProperties().set ("items", xml.getStringAttribute ("items", String::empty)); | |||
| c->setTextWhenNothingSelected (xml.getStringAttribute ("textWhenNonSelected", defaultBox.getTextWhenNothingSelected())); | |||
| c->setTextWhenNoChoicesAvailable (xml.getStringAttribute ("textWhenNoItems", defaultBox.getTextWhenNoChoicesAvailable())); | |||
| updateItems (c); | |||
| return true; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| ComboBox* const c = dynamic_cast <ComboBox*> (component); | |||
| jassert (c != nullptr); | |||
| properties.add (new ComboItemsProperty (c, document)); | |||
| properties.add (new ComboEditableProperty (c, document)); | |||
| properties.add (new ComboJustificationProperty (c, document)); | |||
| properties.add (new ComboTextWhenNoneSelectedProperty (c, document)); | |||
| properties.add (new ComboTextWhenNoItemsProperty (c, document)); | |||
| } | |||
| String getCreationParameters (Component* component) | |||
| { | |||
| return quotedString (component->getName()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| ComboBox* const c = dynamic_cast <ComboBox*> (component); | |||
| jassert (c != nullptr); | |||
| String s; | |||
| s << memberVariableName << "->setEditableText (" << CodeHelpers::boolLiteral (c->isTextEditable()) << ");\n" | |||
| << memberVariableName << "->setJustificationType (" << CodeHelpers::justificationToCode (c->getJustificationType()) << ");\n" | |||
| << memberVariableName << "->setTextWhenNothingSelected (" << quotedString (c->getTextWhenNothingSelected()) << ");\n" | |||
| << memberVariableName << "->setTextWhenNoChoicesAvailable (" << quotedString (c->getTextWhenNoChoicesAvailable()) << ");\n"; | |||
| StringArray lines; | |||
| lines.addLines (c->getProperties() ["items"].toString()); | |||
| int itemId = 1; | |||
| for (int i = 0; i < lines.size(); ++i) | |||
| { | |||
| if (lines[i].trim().isEmpty()) | |||
| s << memberVariableName << "->addSeparator();\n"; | |||
| else | |||
| s << memberVariableName << "->addItem (" | |||
| << quotedString (lines[i]) << ", " << itemId++ << ");\n"; | |||
| } | |||
| if (needsCallback (component)) | |||
| s << memberVariableName << "->addListener (this);\n"; | |||
| s << '\n'; | |||
| code.constructorCode += s; | |||
| } | |||
| void fillInGeneratedCode (Component* component, GeneratedCode& code) | |||
| { | |||
| ComponentTypeHandler::fillInGeneratedCode (component, code); | |||
| if (needsCallback (component)) | |||
| { | |||
| String& callback = code.getCallbackCode ("public ComboBoxListener", | |||
| "void", | |||
| "comboBoxChanged (ComboBox* comboBoxThatHasChanged)", | |||
| true); | |||
| if (callback.trim().isNotEmpty()) | |||
| callback << "else "; | |||
| const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component)); | |||
| const String userCodeComment ("UserComboBoxCode_" + memberVariableName); | |||
| callback | |||
| << "if (comboBoxThatHasChanged == " << memberVariableName | |||
| << ")\n{\n //[" << userCodeComment << "] -- add your combo box handling code here..\n //[/" << userCodeComment << "]\n}\n"; | |||
| } | |||
| } | |||
| static void updateItems (ComboBox* c) | |||
| { | |||
| StringArray lines; | |||
| lines.addLines (c->getProperties() ["items"].toString()); | |||
| c->clear(); | |||
| int itemId = 1; | |||
| for (int i = 0; i < lines.size(); ++i) | |||
| { | |||
| if (lines[i].trim().isEmpty()) | |||
| c->addSeparator(); | |||
| else | |||
| c->addItem (lines[i], itemId++); | |||
| } | |||
| } | |||
| static bool needsCallback (Component*) | |||
| { | |||
| return true; // xxx should be configurable | |||
| } | |||
| private: | |||
| class ComboEditableProperty : public ComponentBooleanProperty <ComboBox> | |||
| { | |||
| public: | |||
| ComboEditableProperty (ComboBox* comp, JucerDocument& doc) | |||
| : ComponentBooleanProperty <ComboBox> ("editable", "Text is editable", "Text is editable", comp, doc) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new ComboEditableChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change combo box editability"); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return component->isTextEditable(); | |||
| } | |||
| private: | |||
| class ComboEditableChangeAction : public ComponentUndoableAction <ComboBox> | |||
| { | |||
| public: | |||
| ComboEditableChangeAction (ComboBox* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <ComboBox> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isTextEditable(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setEditableText (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setEditableText (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ComboJustificationProperty : public JustificationProperty | |||
| { | |||
| public: | |||
| ComboJustificationProperty (ComboBox* comp, JucerDocument& doc) | |||
| : JustificationProperty ("text layout", false), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| } | |||
| void setJustification (const Justification& newJustification) | |||
| { | |||
| document.perform (new ComboJustifyChangeAction (component, *document.getComponentLayout(), newJustification), | |||
| "Change combo box justification"); | |||
| } | |||
| const Justification getJustification() const { return component->getJustificationType(); } | |||
| private: | |||
| ComboBox* const component; | |||
| JucerDocument& document; | |||
| class ComboJustifyChangeAction : public ComponentUndoableAction <ComboBox> | |||
| { | |||
| public: | |||
| ComboJustifyChangeAction (ComboBox* const comp, ComponentLayout& layout, const Justification& newState_) | |||
| : ComponentUndoableAction <ComboBox> (comp, layout), | |||
| newState (newState_), | |||
| oldState (comp->getJustificationType()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setJustificationType (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setJustificationType (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| Justification newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ComboItemsProperty : public ComponentTextProperty <ComboBox> | |||
| { | |||
| public: | |||
| ComboItemsProperty (ComboBox* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <ComboBox> ("items", 10000, true, comp, doc) | |||
| {} | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ComboItemsChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change combo box items"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getProperties() ["items"]; | |||
| } | |||
| private: | |||
| class ComboItemsChangeAction : public ComponentUndoableAction <ComboBox> | |||
| { | |||
| public: | |||
| ComboItemsChangeAction (ComboBox* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <ComboBox> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getProperties() ["items"]; | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->getProperties().set ("items", newState); | |||
| ComboBoxHandler::updateItems (getComponent()); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->getProperties().set ("items", oldState); | |||
| ComboBoxHandler::updateItems (getComponent()); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ComboTextWhenNoneSelectedProperty : public ComponentTextProperty <ComboBox> | |||
| { | |||
| public: | |||
| ComboTextWhenNoneSelectedProperty (ComboBox* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <ComboBox> ("text when none selected", 200, false, comp, doc) | |||
| {} | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ComboNonSelTextChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change combo box text when nothing selected"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getTextWhenNothingSelected(); | |||
| } | |||
| private: | |||
| class ComboNonSelTextChangeAction : public ComponentUndoableAction <ComboBox> | |||
| { | |||
| public: | |||
| ComboNonSelTextChangeAction (ComboBox* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <ComboBox> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getTextWhenNothingSelected(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextWhenNothingSelected (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextWhenNothingSelected (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ComboTextWhenNoItemsProperty : public ComponentTextProperty <ComboBox> | |||
| { | |||
| public: | |||
| ComboTextWhenNoItemsProperty (ComboBox* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <ComboBox> ("text when no items", 200, false, comp, doc) | |||
| {} | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ComboNoItemTextChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change combo box 'no items' text"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getTextWhenNoChoicesAvailable(); | |||
| } | |||
| private: | |||
| class ComboNoItemTextChangeAction : public ComponentUndoableAction <ComboBox> | |||
| { | |||
| public: | |||
| ComboNoItemTextChangeAction (ComboBox* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <ComboBox> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getTextWhenNoChoicesAvailable(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextWhenNoChoicesAvailable (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextWhenNoChoicesAvailable (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,187 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTNAMEPROPERTY_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTNAMEPROPERTY_JUCEHEADER__ | |||
| #include "jucer_ComponentTypeHandler.h" | |||
| #include "jucer_ComponentUndoableAction.h" | |||
| #include "../properties/jucer_ComponentTextProperty.h" | |||
| //============================================================================== | |||
| class ComponentNameProperty : public ComponentTextProperty <Component> | |||
| { | |||
| public: | |||
| ComponentNameProperty (Component* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <Component> ("name", 40, false, comp, doc) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new CompNameChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change component name"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getName(); | |||
| } | |||
| private: | |||
| class CompNameChangeAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| CompNameChangeAction (Component* const comp, ComponentLayout& layout, const String& newName_) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| newName (newName_) | |||
| { | |||
| oldName = comp->getName(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setName (newName); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setName (oldName); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newName, oldName; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ComponentMemberNameProperty : public ComponentTextProperty <Component> | |||
| { | |||
| public: | |||
| ComponentMemberNameProperty (Component* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <Component> ("member name", 40, false, comp, doc) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new CompMemberNameChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change component member name"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return document.getComponentLayout()->getComponentMemberVariableName (component); | |||
| } | |||
| private: | |||
| class CompMemberNameChangeAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| CompMemberNameChangeAction (Component* const comp, ComponentLayout& layout, const String& newName_) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| newName (newName_) | |||
| { | |||
| oldName = layout.getComponentMemberVariableName (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| layout.setComponentMemberVariableName (getComponent(), newName); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| layout.setComponentMemberVariableName (getComponent(), oldName); | |||
| return true; | |||
| } | |||
| String newName, oldName; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ComponentVirtualClassProperty : public ComponentTextProperty <Component> | |||
| { | |||
| public: | |||
| ComponentVirtualClassProperty (Component* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <Component> ("virtual class", 40, false, comp, doc) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new CompVirtualClassChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change component virtual class name"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return document.getComponentLayout()->getComponentVirtualClassName (component); | |||
| } | |||
| private: | |||
| class CompVirtualClassChangeAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| CompVirtualClassChangeAction (Component* const comp, ComponentLayout& layout, const String& newName_) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| newName (newName_) | |||
| { | |||
| oldName = layout.getComponentVirtualClassName (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| layout.setComponentVirtualClassName (getComponent(), newName); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| layout.setComponentVirtualClassName (getComponent(), oldName); | |||
| return true; | |||
| } | |||
| String newName, oldName; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_COMPONENTNAMEPROPERTY_JUCEHEADER__ | |||
| @@ -0,0 +1,583 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "../../Application/jucer_Application.h" | |||
| #include "../jucer_ObjectTypes.h" | |||
| #include "../jucer_UtilityFunctions.h" | |||
| #include "../ui/jucer_JucerCommandIDs.h" | |||
| #include "../ui/jucer_ComponentOverlayComponent.h" | |||
| #include "jucer_ComponentNameProperty.h" | |||
| #include "../properties/jucer_PositionPropertyBase.h" | |||
| #include "../properties/jucer_ComponentColourProperty.h" | |||
| #include "../ui/jucer_TestComponent.h" | |||
| static String getTypeInfoName (const std::type_info& info) | |||
| { | |||
| #if JUCE_MSVC | |||
| return info.raw_name(); | |||
| #else | |||
| return info.name(); | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| ComponentTypeHandler::ComponentTypeHandler (const String& typeName_, | |||
| const String& className_, | |||
| const std::type_info& componentClass_, | |||
| const int defaultWidth_, | |||
| const int defaultHeight_) | |||
| : typeName (typeName_), | |||
| className (className_), | |||
| componentClassRawName (getTypeInfoName (componentClass_)), | |||
| defaultWidth (defaultWidth_), | |||
| defaultHeight (defaultHeight_) | |||
| { | |||
| } | |||
| Component* ComponentTypeHandler::createCopyOf (JucerDocument* document, Component& existing) | |||
| { | |||
| jassert (getHandlerFor (existing) == this); | |||
| Component* const newOne = createNewComponent (document); | |||
| ScopedPointer<XmlElement> xml (createXmlFor (&existing, document->getComponentLayout())); | |||
| if (xml != nullptr) | |||
| restoreFromXml (*xml, newOne, document->getComponentLayout()); | |||
| return newOne; | |||
| } | |||
| ComponentOverlayComponent* ComponentTypeHandler::createOverlayComponent (Component* child, ComponentLayout& layout) | |||
| { | |||
| return new ComponentOverlayComponent (child, layout); | |||
| } | |||
| void ComponentTypeHandler::showPopupMenu (Component*, ComponentLayout&) | |||
| { | |||
| PopupMenu m; | |||
| m.addCommandItem (commandManager, JucerCommandIDs::toFront); | |||
| m.addCommandItem (commandManager, JucerCommandIDs::toBack); | |||
| m.addSeparator(); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::cut); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::copy); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::paste); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::del); | |||
| m.show(); | |||
| } | |||
| JucerDocument* ComponentTypeHandler::findParentDocument (Component* component) | |||
| { | |||
| Component* p = component->getParentComponent(); | |||
| while (p != nullptr) | |||
| { | |||
| if (JucerDocumentEditor* const ed = dynamic_cast <JucerDocumentEditor*> (p)) | |||
| return ed->getDocument(); | |||
| if (TestComponent* const t = dynamic_cast <TestComponent*> (p)) | |||
| return t->getDocument(); | |||
| p = p->getParentComponent(); | |||
| } | |||
| return nullptr; | |||
| } | |||
| //============================================================================== | |||
| bool ComponentTypeHandler::canHandle (Component& component) const | |||
| { | |||
| return componentClassRawName == getTypeInfoName (typeid (component)); | |||
| } | |||
| ComponentTypeHandler* ComponentTypeHandler::getHandlerFor (Component& component) | |||
| { | |||
| for (int i = 0; i < ObjectTypes::numComponentTypes; ++i) | |||
| if (ObjectTypes::componentTypeHandlers[i]->canHandle (component)) | |||
| return ObjectTypes::componentTypeHandlers[i]; | |||
| jassertfalse; | |||
| return nullptr; | |||
| } | |||
| ComponentTypeHandler* ComponentTypeHandler::getHandlerForXmlTag (const String& tagName) | |||
| { | |||
| for (int i = 0; i < ObjectTypes::numComponentTypes; ++i) | |||
| if (ObjectTypes::componentTypeHandlers[i]->getXmlTagName().equalsIgnoreCase (tagName)) | |||
| return ObjectTypes::componentTypeHandlers[i]; | |||
| return nullptr; | |||
| } | |||
| XmlElement* ComponentTypeHandler::createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| XmlElement* e = new XmlElement (getXmlTagName()); | |||
| e->setAttribute ("name", comp->getName()); | |||
| e->setAttribute ("id", String::toHexString (getComponentId (comp))); | |||
| e->setAttribute ("memberName", comp->getProperties() ["memberName"].toString()); | |||
| e->setAttribute ("virtualName", comp->getProperties() ["virtualName"].toString()); | |||
| e->setAttribute ("explicitFocusOrder", comp->getExplicitFocusOrder()); | |||
| RelativePositionedRectangle pos (getComponentPosition (comp)); | |||
| pos.updateFromComponent (*comp, layout); | |||
| pos.applyToXml (*e); | |||
| SettableTooltipClient* const ttc = dynamic_cast <SettableTooltipClient*> (comp); | |||
| if (ttc != 0 && ttc->getTooltip().isNotEmpty()) | |||
| e->setAttribute ("tooltip", ttc->getTooltip()); | |||
| for (int i = 0; i < colours.size(); ++i) | |||
| { | |||
| if (comp->isColourSpecified (colours[i]->colourId)) | |||
| { | |||
| e->setAttribute (colours[i]->xmlTagName, | |||
| comp->findColour (colours[i]->colourId).toString()); | |||
| } | |||
| } | |||
| return e; | |||
| } | |||
| bool ComponentTypeHandler::restoreFromXml (const XmlElement& xml, | |||
| Component* comp, | |||
| const ComponentLayout* layout) | |||
| { | |||
| jassert (xml.hasTagName (getXmlTagName())); | |||
| if (! xml.hasTagName (getXmlTagName())) | |||
| return false; | |||
| comp->setName (xml.getStringAttribute ("name", comp->getName())); | |||
| setComponentId (comp, xml.getStringAttribute ("id").getHexValue64()); | |||
| comp->getProperties().set ("memberName", xml.getStringAttribute ("memberName")); | |||
| comp->getProperties().set ("virtualName", xml.getStringAttribute ("virtualName")); | |||
| comp->setExplicitFocusOrder (xml.getIntAttribute ("explicitFocusOrder")); | |||
| RelativePositionedRectangle currentPos (getComponentPosition (comp)); | |||
| currentPos.updateFromComponent (*comp, layout); | |||
| RelativePositionedRectangle rpr; | |||
| rpr.restoreFromXml (xml, currentPos); | |||
| jassert (layout != 0); | |||
| setComponentPosition (comp, rpr, layout); | |||
| SettableTooltipClient* const ttc = dynamic_cast <SettableTooltipClient*> (comp); | |||
| if (ttc != 0) | |||
| ttc->setTooltip (xml.getStringAttribute ("tooltip")); | |||
| for (int i = 0; i < colours.size(); ++i) | |||
| { | |||
| const String col (xml.getStringAttribute (colours[i]->xmlTagName, String::empty)); | |||
| if (col.isNotEmpty()) | |||
| { | |||
| comp->setColour (colours[i]->colourId, | |||
| Colour (col.getHexValue32())); | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| //============================================================================== | |||
| int64 ComponentTypeHandler::getComponentId (Component* comp) | |||
| { | |||
| if (comp == nullptr) | |||
| return 0; | |||
| int64 compId = comp->getProperties() ["jucerCompId"].toString().getHexValue64(); | |||
| if (compId == 0) | |||
| { | |||
| compId = Random::getSystemRandom().nextInt64(); | |||
| setComponentId (comp, compId); | |||
| } | |||
| return compId; | |||
| } | |||
| void ComponentTypeHandler::setComponentId (Component* comp, const int64 newID) | |||
| { | |||
| jassert (comp != nullptr); | |||
| if (newID != 0) | |||
| comp->getProperties().set ("jucerCompId", String::toHexString (newID)); | |||
| } | |||
| RelativePositionedRectangle ComponentTypeHandler::getComponentPosition (Component* comp) | |||
| { | |||
| RelativePositionedRectangle rp; | |||
| rp.rect = PositionedRectangle (comp->getProperties() ["pos"]); | |||
| rp.relativeToX = comp->getProperties() ["relativeToX"].toString().getHexValue64(); | |||
| rp.relativeToY = comp->getProperties() ["relativeToY"].toString().getHexValue64(); | |||
| rp.relativeToW = comp->getProperties() ["relativeToW"].toString().getHexValue64(); | |||
| rp.relativeToH = comp->getProperties() ["relativeToH"].toString().getHexValue64(); | |||
| return rp; | |||
| } | |||
| void ComponentTypeHandler::setComponentPosition (Component* comp, | |||
| const RelativePositionedRectangle& newPos, | |||
| const ComponentLayout* layout) | |||
| { | |||
| comp->getProperties().set ("pos", newPos.rect.toString()); | |||
| comp->getProperties().set ("relativeToX", String::toHexString (newPos.relativeToX)); | |||
| comp->getProperties().set ("relativeToY", String::toHexString (newPos.relativeToY)); | |||
| comp->getProperties().set ("relativeToW", String::toHexString (newPos.relativeToW)); | |||
| comp->getProperties().set ("relativeToH", String::toHexString (newPos.relativeToH)); | |||
| comp->setBounds (newPos.getRectangle (Rectangle<int> (0, 0, comp->getParentWidth(), comp->getParentHeight()), | |||
| layout)); | |||
| } | |||
| //============================================================================== | |||
| class TooltipProperty : public ComponentTextProperty <Component> | |||
| { | |||
| public: | |||
| TooltipProperty (Component* comp, JucerDocument& document) | |||
| : ComponentTextProperty <Component> ("tooltip", 1024, false, comp, document) | |||
| { | |||
| } | |||
| String getText() const | |||
| { | |||
| SettableTooltipClient* ttc = dynamic_cast <SettableTooltipClient*> (component); | |||
| return ttc->getTooltip(); | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new SetTooltipAction (component, *document.getComponentLayout(), newText), | |||
| "Change tooltip"); | |||
| } | |||
| private: | |||
| class SetTooltipAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| SetTooltipAction (Component* const comp, ComponentLayout& layout, const String& newValue_) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| newValue (newValue_) | |||
| { | |||
| SettableTooltipClient* ttc = dynamic_cast <SettableTooltipClient*> (comp); | |||
| jassert (ttc != nullptr); | |||
| oldValue = ttc->getTooltip(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| if (SettableTooltipClient* ttc = dynamic_cast <SettableTooltipClient*> (getComponent())) | |||
| { | |||
| ttc->setTooltip (newValue); | |||
| changed(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| if (SettableTooltipClient* ttc = dynamic_cast <SettableTooltipClient*> (getComponent())) | |||
| { | |||
| ttc->setTooltip (oldValue); | |||
| changed(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| String newValue, oldValue; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ComponentPositionProperty : public PositionPropertyBase | |||
| { | |||
| public: | |||
| ComponentPositionProperty (Component* comp, | |||
| JucerDocument& doc, | |||
| const String& name, | |||
| ComponentPositionDimension dimension_) | |||
| : PositionPropertyBase (comp, name, dimension_, | |||
| true, true, | |||
| doc.getComponentLayout()), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ComponentPositionProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setPosition (const RelativePositionedRectangle& newPos) | |||
| { | |||
| document.getComponentLayout()->setComponentPosition (component, newPos, true); | |||
| } | |||
| RelativePositionedRectangle getPosition() const | |||
| { | |||
| return ComponentTypeHandler::getComponentPosition (component); | |||
| } | |||
| private: | |||
| JucerDocument& document; | |||
| }; | |||
| //============================================================================== | |||
| class FocusOrderProperty : public ComponentTextProperty <Component> | |||
| { | |||
| public: | |||
| FocusOrderProperty (Component* comp, JucerDocument& document) | |||
| : ComponentTextProperty <Component> ("focus order", 8, false, comp, document) | |||
| { | |||
| } | |||
| String getText() const | |||
| { | |||
| return String (component->getExplicitFocusOrder()); | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new SetFocusOrderAction (component, *document.getComponentLayout(), jmax (0, newText.getIntValue())), | |||
| "Change focus order"); | |||
| } | |||
| private: | |||
| class SetFocusOrderAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| SetFocusOrderAction (Component* const comp, ComponentLayout& layout, const int newOrder_) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| newValue (newOrder_) | |||
| { | |||
| oldValue = comp->getExplicitFocusOrder(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setExplicitFocusOrder (newValue); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setExplicitFocusOrder (oldValue); | |||
| changed(); | |||
| return true; | |||
| } | |||
| int newValue, oldValue; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| void ComponentTypeHandler::getEditableProperties (Component* component, | |||
| JucerDocument& document, | |||
| Array <PropertyComponent*>& properties) | |||
| { | |||
| properties.add (new ComponentMemberNameProperty (component, document)); | |||
| properties.add (new ComponentNameProperty (component, document)); | |||
| properties.add (new ComponentVirtualClassProperty (component, document)); | |||
| properties.add (new ComponentPositionProperty (component, document, "x", ComponentPositionProperty::componentX)); | |||
| properties.add (new ComponentPositionProperty (component, document, "y", ComponentPositionProperty::componentY)); | |||
| properties.add (new ComponentPositionProperty (component, document, "width", ComponentPositionProperty::componentWidth)); | |||
| properties.add (new ComponentPositionProperty (component, document, "height", ComponentPositionProperty::componentHeight)); | |||
| if (dynamic_cast <SettableTooltipClient*> (component) != nullptr) | |||
| properties.add (new TooltipProperty (component, document)); | |||
| properties.add (new FocusOrderProperty (component, document)); | |||
| } | |||
| void ComponentTypeHandler::addPropertiesToPropertyPanel (Component* comp, | |||
| JucerDocument& document, | |||
| PropertyPanel& panel) | |||
| { | |||
| Array <PropertyComponent*> props; | |||
| getEditableProperties (comp, document, props); | |||
| panel.addSection (getClassName (comp), props); | |||
| } | |||
| void ComponentTypeHandler::registerEditableColour (int colourId, | |||
| const String& colourIdCode, | |||
| const String& colourName, const String& xmlTagName) | |||
| { | |||
| ComponentColourInfo* const c = new ComponentColourInfo(); | |||
| c->colourId = colourId; | |||
| c->colourIdCode = colourIdCode; | |||
| c->colourName = colourName; | |||
| c->xmlTagName = xmlTagName; | |||
| colours.add (c); | |||
| } | |||
| void ComponentTypeHandler::addColourProperties (Component* component, | |||
| JucerDocument& document, | |||
| Array <PropertyComponent*>& properties) | |||
| { | |||
| for (int i = 0; i < colours.size(); ++i) | |||
| properties.add (new ComponentColourIdProperty (component, document, | |||
| colours[i]->colourId, | |||
| colours[i]->colourName, | |||
| true)); | |||
| } | |||
| String ComponentTypeHandler::getColourIntialisationCode (Component* component, | |||
| const String& objectName) | |||
| { | |||
| String s; | |||
| for (int i = 0; i < colours.size(); ++i) | |||
| { | |||
| if (component->isColourSpecified (colours[i]->colourId)) | |||
| { | |||
| s << objectName << "->setColour (" | |||
| << colours[i]->colourIdCode | |||
| << ", " | |||
| << CodeHelpers::colourToCode (component->findColour (colours[i]->colourId)) | |||
| << ");\n"; | |||
| } | |||
| } | |||
| return s; | |||
| } | |||
| //============================================================================== | |||
| void ComponentTypeHandler::fillInGeneratedCode (Component* component, GeneratedCode& code) | |||
| { | |||
| const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component)); | |||
| fillInMemberVariableDeclarations (code, component, memberVariableName); | |||
| fillInCreationCode (code, component, memberVariableName); | |||
| fillInDeletionCode (code, component, memberVariableName); | |||
| fillInResizeCode (code, component, memberVariableName); | |||
| } | |||
| void ComponentTypeHandler::fillInMemberVariableDeclarations (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| const String virtualName (component->getProperties() ["virtualName"].toString()); | |||
| if (virtualName.isNotEmpty()) | |||
| code.privateMemberDeclarations | |||
| << CodeHelpers::makeValidIdentifier (virtualName, false, false, true); | |||
| else | |||
| code.privateMemberDeclarations | |||
| << getClassName (component); | |||
| code.privateMemberDeclarations | |||
| << "* " << memberVariableName << ";\n"; | |||
| code.initialisers.add (memberVariableName + " (0)"); | |||
| } | |||
| void ComponentTypeHandler::fillInResizeCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| const RelativePositionedRectangle pos (getComponentPosition (component)); | |||
| String x, y, w, h, r; | |||
| positionToCode (pos, code.document->getComponentLayout(), x, y, w, h); | |||
| r << memberVariableName << "->setBounds (" | |||
| << x << ", " << y << ", " << w << ", " << h << ");\n"; | |||
| if (pos.rect.isPositionAbsolute()) | |||
| code.constructorCode += r + "\n"; | |||
| else | |||
| code.getCallbackCode (String::empty, "void", "resized()", false) += r; | |||
| } | |||
| String ComponentTypeHandler::getCreationParameters (Component*) | |||
| { | |||
| return String::empty; | |||
| } | |||
| void ComponentTypeHandler::fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| String params (getCreationParameters (component)); | |||
| const String virtualName (component->getProperties() ["virtualName"].toString()); | |||
| String s; | |||
| s << "addAndMakeVisible (" << memberVariableName << " = new "; | |||
| if (virtualName.isNotEmpty()) | |||
| s << CodeHelpers::makeValidIdentifier (virtualName, false, false, true); | |||
| else | |||
| s << getClassName (component); | |||
| if (params.isEmpty()) | |||
| s << "());\n"; | |||
| else | |||
| { | |||
| StringArray lines; | |||
| lines.addLines (params); | |||
| params = lines.joinIntoString ("\n" + String::repeatedString (" ", s.length() + 2)); | |||
| s << " (" << params << "));\n"; | |||
| } | |||
| if (SettableTooltipClient* ttc = dynamic_cast <SettableTooltipClient*> (component)) | |||
| { | |||
| if (ttc->getTooltip().isNotEmpty()) | |||
| { | |||
| s << memberVariableName << "->setTooltip (" | |||
| << quotedString (ttc->getTooltip()) | |||
| << ");\n"; | |||
| } | |||
| } | |||
| if (component->getExplicitFocusOrder() > 0) | |||
| s << memberVariableName << "->setExplicitFocusOrder (" | |||
| << component->getExplicitFocusOrder() | |||
| << ");\n"; | |||
| code.constructorCode += s; | |||
| } | |||
| void ComponentTypeHandler::fillInDeletionCode (GeneratedCode& code, Component*, | |||
| const String& memberVariableName) | |||
| { | |||
| code.destructorCode | |||
| << "deleteAndZero (" << memberVariableName << ");\n"; | |||
| } | |||
| @@ -0,0 +1,145 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTTYPEHANDLER_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTTYPEHANDLER_JUCEHEADER__ | |||
| class ComponentOverlayComponent; | |||
| class ComponentLayout; | |||
| #include "../jucer_GeneratedCode.h" | |||
| #include "../ui/jucer_RelativePositionedRectangle.h" | |||
| //============================================================================== | |||
| /** | |||
| Base class for handlers that can understand the properties of all the component classes. | |||
| */ | |||
| class ComponentTypeHandler | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentTypeHandler (const String& typeDescription_, | |||
| const String& className_, | |||
| const std::type_info& componentClass, | |||
| const int defaultWidth_, | |||
| const int defaultHeight_); | |||
| virtual ~ComponentTypeHandler() {} | |||
| //============================================================================== | |||
| virtual bool canHandle (Component& component) const; | |||
| static ComponentTypeHandler* getHandlerFor (Component& component); | |||
| //============================================================================== | |||
| virtual String getXmlTagName() const noexcept { return className.toUpperCase(); } | |||
| static ComponentTypeHandler* getHandlerForXmlTag (const String& tagName); | |||
| virtual XmlElement* createXmlFor (Component* component, const ComponentLayout* layout); | |||
| virtual bool restoreFromXml (const XmlElement& xml, Component* component, const ComponentLayout* layout); | |||
| virtual void getEditableProperties (Component* component, | |||
| JucerDocument& document, | |||
| Array <PropertyComponent*>& properties); | |||
| virtual void addPropertiesToPropertyPanel (Component* component, | |||
| JucerDocument& document, | |||
| PropertyPanel& panel); | |||
| void registerEditableColour (int colourId, | |||
| const String& colourIdCode, | |||
| const String& colourName, | |||
| const String& xmlTagName); | |||
| #define registerColour(colourId, colourName, xmlTagName) \ | |||
| registerEditableColour (colourId, #colourId, colourName, xmlTagName) | |||
| void addColourProperties (Component* component, | |||
| JucerDocument& document, | |||
| Array <PropertyComponent*>& properties); | |||
| String getColourIntialisationCode (Component* component, | |||
| const String& objectName); | |||
| //============================================================================== | |||
| virtual Component* createNewComponent (JucerDocument*) = 0; | |||
| virtual Component* createCopyOf (JucerDocument*, Component& existing); | |||
| virtual ComponentOverlayComponent* createOverlayComponent (Component* child, ComponentLayout& layout); | |||
| virtual void showPopupMenu (Component* component, | |||
| ComponentLayout& layout); | |||
| //============================================================================== | |||
| // Code-generation methods: | |||
| virtual void fillInGeneratedCode (Component* component, GeneratedCode& code); | |||
| virtual void fillInMemberVariableDeclarations (GeneratedCode& code, Component* component, const String& memberVariableName); | |||
| virtual void fillInResizeCode (GeneratedCode& code, Component* component, const String& memberVariableName); | |||
| virtual void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName); | |||
| virtual String getCreationParameters (Component* component); | |||
| virtual void fillInDeletionCode (GeneratedCode& code, Component* component, const String& memberVariableName); | |||
| //============================================================================== | |||
| const String& getTypeName() const noexcept { return typeName; } | |||
| virtual String getClassName (Component*) const { return className; } | |||
| int getDefaultWidth() const noexcept { return defaultWidth; } | |||
| int getDefaultHeight() const noexcept { return defaultHeight; } | |||
| static int64 getComponentId (Component* comp); | |||
| static void setComponentId (Component* comp, const int64 newID); | |||
| static RelativePositionedRectangle getComponentPosition (Component* comp); | |||
| static void setComponentPosition (Component* comp, | |||
| const RelativePositionedRectangle& newPos, | |||
| const ComponentLayout* layout); | |||
| static JucerDocument* findParentDocument (Component* component); | |||
| protected: | |||
| //============================================================================== | |||
| const String typeName, className, virtualClass, componentClassRawName; | |||
| int defaultWidth, defaultHeight; | |||
| struct ComponentColourInfo | |||
| { | |||
| int colourId; | |||
| String colourIdCode, colourName, xmlTagName; | |||
| }; | |||
| OwnedArray <ComponentColourInfo> colours; | |||
| private: | |||
| ComponentTypeHandler (const ComponentTypeHandler&); | |||
| ComponentTypeHandler& operator= (const ComponentTypeHandler&); | |||
| }; | |||
| #endif // __JUCER_COMPONENTTYPEHANDLER_JUCEHEADER__ | |||
| @@ -0,0 +1,81 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTUNDOABLEACTION_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTUNDOABLEACTION_JUCEHEADER__ | |||
| #include "../ui/jucer_JucerDocumentEditor.h" | |||
| //============================================================================== | |||
| template <class ComponentType> | |||
| class ComponentUndoableAction : public UndoableAction | |||
| { | |||
| public: | |||
| ComponentUndoableAction (ComponentType* const comp, | |||
| ComponentLayout& layout_) | |||
| : layout (layout_), | |||
| componentIndex (layout_.indexOfComponent (comp)) | |||
| { | |||
| jassert (comp != nullptr); | |||
| jassert (componentIndex >= 0); | |||
| } | |||
| ComponentType* getComponent() const | |||
| { | |||
| ComponentType* const c = dynamic_cast <ComponentType*> (layout.getComponent (componentIndex)); | |||
| jassert (c != nullptr); | |||
| return c; | |||
| } | |||
| int getSizeInUnits() { return 2; } | |||
| protected: | |||
| ComponentLayout& layout; | |||
| const int componentIndex; | |||
| void changed() const | |||
| { | |||
| jassert (layout.getDocument() != nullptr); | |||
| layout.getDocument()->changed(); | |||
| } | |||
| void showCorrectTab() const | |||
| { | |||
| if (JucerDocumentEditor* const ed = JucerDocumentEditor::getActiveDocumentHolder()) | |||
| ed->showLayout(); | |||
| if (layout.getSelectedSet().getNumSelected() == 0) | |||
| if (ComponentType* const c = dynamic_cast <ComponentType*> (layout.getComponent (componentIndex))) | |||
| layout.getSelectedSet().selectOnly (getComponent()); | |||
| } | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentUndoableAction) | |||
| }; | |||
| #endif // __JUCER_COMPONENTUNDOABLEACTION_JUCEHEADER__ | |||
| @@ -0,0 +1,233 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class GenericComponent : public Component | |||
| { | |||
| public: | |||
| GenericComponent() | |||
| : Component ("new component"), | |||
| actualClassName ("Component") | |||
| { | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.fillAll (Colours::white.withAlpha (0.25f)); | |||
| g.setColour (Colours::black.withAlpha (0.5f)); | |||
| g.drawRect (getLocalBounds()); | |||
| g.drawLine (0.0f, 0.0f, (float) getWidth(), (float) getHeight()); | |||
| g.drawLine (0.0f, (float) getHeight(), (float) getWidth(), 0.0f); | |||
| g.setFont (14.0f); | |||
| g.drawText (actualClassName, 0, 0, getWidth(), getHeight() / 2, Justification::centred, true); | |||
| } | |||
| void setClassName (const String& newName) | |||
| { | |||
| if (actualClassName != newName) | |||
| { | |||
| actualClassName = newName; | |||
| repaint(); | |||
| } | |||
| } | |||
| void setParams (const String& newParams) | |||
| { | |||
| if (constructorParams != newParams) | |||
| { | |||
| constructorParams = newParams; | |||
| repaint(); | |||
| } | |||
| } | |||
| String actualClassName, constructorParams; | |||
| }; | |||
| //============================================================================== | |||
| class GenericComponentHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| GenericComponentHandler() | |||
| : ComponentTypeHandler ("Generic Component", "GenericComponent", typeid (GenericComponent), 150, 24) | |||
| {} | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new GenericComponent(); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("class", ((GenericComponent*) comp)->actualClassName); | |||
| e->setAttribute ("params", ((GenericComponent*) comp)->constructorParams); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| ((GenericComponent*) comp)->actualClassName = xml.getStringAttribute ("class", "Component"); | |||
| ((GenericComponent*) comp)->constructorParams = xml.getStringAttribute ("params", String::empty); | |||
| return true; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| properties.add (new GenericCompClassProperty (dynamic_cast <GenericComponent*> (component), document)); | |||
| properties.add (new GenericCompParamsProperty (dynamic_cast <GenericComponent*> (component), document)); | |||
| } | |||
| String getClassName (Component* comp) const | |||
| { | |||
| return ((GenericComponent*) comp)->actualClassName; | |||
| } | |||
| String getCreationParameters (Component* comp) | |||
| { | |||
| return ((GenericComponent*) comp)->constructorParams; | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| if (component->getName().isNotEmpty()) | |||
| code.constructorCode | |||
| << memberVariableName << "->setName (" | |||
| << quotedString (component->getName()) | |||
| << ");\n\n"; | |||
| else | |||
| code.constructorCode << "\n"; | |||
| } | |||
| private: | |||
| class GenericCompClassProperty : public ComponentTextProperty <GenericComponent> | |||
| { | |||
| public: | |||
| GenericCompClassProperty (GenericComponent* comp, JucerDocument& document) | |||
| : ComponentTextProperty <GenericComponent> ("class", 300, false, comp, document) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new GenericCompClassChangeAction (component, *document.getComponentLayout(), | |||
| CodeHelpers::makeValidIdentifier (newText, false, false, true)), | |||
| "Change generic component class"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->actualClassName; | |||
| } | |||
| private: | |||
| class GenericCompClassChangeAction : public ComponentUndoableAction <GenericComponent> | |||
| { | |||
| public: | |||
| GenericCompClassChangeAction (GenericComponent* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <GenericComponent> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->actualClassName; | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setClassName (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setClassName (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| class GenericCompParamsProperty : public ComponentTextProperty <GenericComponent> | |||
| { | |||
| public: | |||
| GenericCompParamsProperty (GenericComponent* comp, JucerDocument& document) | |||
| : ComponentTextProperty <GenericComponent> ("constructor params", 1024, true, comp, document) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new GenericCompParamsChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change generic component class"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->constructorParams; | |||
| } | |||
| private: | |||
| class GenericCompParamsChangeAction : public ComponentUndoableAction <GenericComponent> | |||
| { | |||
| public: | |||
| GenericCompParamsChangeAction (GenericComponent* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <GenericComponent> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->constructorParams; | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setParams (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setParams (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,227 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class GroupComponentHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| GroupComponentHandler() | |||
| : ComponentTypeHandler ("Group Box", "GroupComponent", typeid (GroupComponent), 200, 150) | |||
| { | |||
| registerColour (GroupComponent::outlineColourId, "outline", "outlinecol"); | |||
| registerColour (GroupComponent::textColourId, "text", "textcol"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new GroupComponent ("new group", "group"); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| GroupComponent* const g = (GroupComponent*) comp; | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("title", g->getText()); | |||
| GroupComponent defaultComp (String::empty, String::empty); | |||
| if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags()) | |||
| e->setAttribute ("textpos", g->getTextLabelPosition().getFlags()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| GroupComponent* const g = (GroupComponent*) comp; | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| g->setText (xml.getStringAttribute ("title", g->getText())); | |||
| g->setTextLabelPosition (Justification (xml.getIntAttribute ("textpos", g->getTextLabelPosition().getFlags()))); | |||
| return true; | |||
| } | |||
| String getCreationParameters (Component* component) | |||
| { | |||
| GroupComponent* g = dynamic_cast <GroupComponent*> (component); | |||
| return quotedString (component->getName()) | |||
| + ",\n" | |||
| + quotedString (g->getText()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| GroupComponent* const g = dynamic_cast <GroupComponent*> (component); | |||
| String s; | |||
| GroupComponent defaultComp (String::empty, String::empty); | |||
| if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags()) | |||
| { | |||
| s << memberVariableName << "->setTextLabelPosition (" | |||
| << CodeHelpers::justificationToCode (g->getTextLabelPosition()) | |||
| << ");\n"; | |||
| } | |||
| s << getColourIntialisationCode (component, memberVariableName) | |||
| << '\n'; | |||
| code.constructorCode += s; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| properties.add (new GroupTitleProperty ((GroupComponent*) component, document)); | |||
| properties.add (new GroupJustificationProperty ((GroupComponent*) component, document)); | |||
| addColourProperties (component, document, properties); | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class GroupTitleProperty : public ComponentTextProperty <GroupComponent> | |||
| { | |||
| public: | |||
| GroupTitleProperty (GroupComponent* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <GroupComponent> ("text", 200, false, comp, doc) | |||
| {} | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new GroupTitleChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change group title"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getText(); | |||
| } | |||
| private: | |||
| class GroupTitleChangeAction : public ComponentUndoableAction <GroupComponent> | |||
| { | |||
| public: | |||
| GroupTitleChangeAction (GroupComponent* const comp, ComponentLayout& layout, const String& newName_) | |||
| : ComponentUndoableAction <GroupComponent> (comp, layout), | |||
| newName (newName_) | |||
| { | |||
| oldName = comp->getText(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setText (newName); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setText (oldName); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newName, oldName; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class GroupJustificationProperty : public JustificationProperty, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| GroupJustificationProperty (GroupComponent* const group_, JucerDocument& doc) | |||
| : JustificationProperty ("layout", true), | |||
| group (group_), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~GroupJustificationProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setJustification (const Justification& newJustification) | |||
| { | |||
| document.perform (new GroupJustifyChangeAction (group, *document.getComponentLayout(), newJustification), | |||
| "Change text label position"); | |||
| } | |||
| const Justification getJustification() const | |||
| { | |||
| return group->getTextLabelPosition(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| GroupComponent* const group; | |||
| JucerDocument& document; | |||
| class GroupJustifyChangeAction : public ComponentUndoableAction <GroupComponent> | |||
| { | |||
| public: | |||
| GroupJustifyChangeAction (GroupComponent* const comp, ComponentLayout& layout, const Justification& newState_) | |||
| : ComponentUndoableAction <GroupComponent> (comp, layout), | |||
| newState (newState_), | |||
| oldState (comp->getTextLabelPosition()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextLabelPosition (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextLabelPosition (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| Justification newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,139 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class HyperlinkButtonHandler : public ButtonHandler | |||
| { | |||
| public: | |||
| HyperlinkButtonHandler() | |||
| : ButtonHandler ("Hyperlink Button", "HyperlinkButton", typeid (HyperlinkButton), 150, 24) | |||
| { | |||
| registerColour (HyperlinkButton::textColourId, "text", "textCol"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| HyperlinkButton* hb = new HyperlinkButton ("new hyperlink", URL ("http://www.rawmaterialsoftware.com/juce")); | |||
| setNeedsButtonListener (hb, false); | |||
| return hb; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| HyperlinkButton* const hb = (HyperlinkButton*) component; | |||
| ButtonHandler::getEditableProperties (component, document, properties); | |||
| properties.add (new HyperlinkURLProperty (hb, document)); | |||
| addColourProperties (component, document, properties); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| HyperlinkButton* const hb = (HyperlinkButton*) comp; | |||
| XmlElement* const e = ButtonHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("url", hb->getURL().toString (false)); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| HyperlinkButton* const hb = (HyperlinkButton*) comp; | |||
| if (! ButtonHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| hb->setURL (URL (xml.getStringAttribute ("url", hb->getURL().toString (false)))); | |||
| return true; | |||
| } | |||
| String getCreationParameters (Component* comp) | |||
| { | |||
| HyperlinkButton* const hb = dynamic_cast <HyperlinkButton*> (comp); | |||
| return quotedString (hb->getButtonText()) | |||
| + ",\nURL (" | |||
| + quotedString (hb->getURL().toString (false)) | |||
| + ")"; | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ButtonHandler::fillInCreationCode (code, component, memberVariableName); | |||
| code.constructorCode << getColourIntialisationCode (component, memberVariableName) | |||
| << '\n'; | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class HyperlinkURLProperty : public ComponentTextProperty <HyperlinkButton> | |||
| { | |||
| public: | |||
| HyperlinkURLProperty (HyperlinkButton* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <HyperlinkButton> ("URL", 512, false, comp, doc) | |||
| {} | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new HyperlinkURLChangeAction (component, *document.getComponentLayout(), URL (newText)), | |||
| "Change hyperlink URL"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getURL().toString (false); | |||
| } | |||
| private: | |||
| class HyperlinkURLChangeAction : public ComponentUndoableAction <HyperlinkButton> | |||
| { | |||
| public: | |||
| HyperlinkURLChangeAction (HyperlinkButton* const comp, ComponentLayout& layout, const URL& newState_) | |||
| : ComponentUndoableAction <HyperlinkButton> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getURL(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setURL (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setURL (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| URL newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,524 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class ImageButtonHandler : public ButtonHandler | |||
| { | |||
| public: | |||
| enum ImageRole | |||
| { | |||
| normalImage = 0, | |||
| overImage = 1, | |||
| downImage = 2 | |||
| }; | |||
| //============================================================================== | |||
| ImageButtonHandler() | |||
| : ButtonHandler ("Image Button", "ImageButton", typeid (ImageButton), 150, 24) | |||
| { | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new ImageButton ("new button"); | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ButtonHandler::getEditableProperties (component, document, properties); | |||
| addColourProperties (component, document, properties); | |||
| ImageButton* const ib = (ImageButton*) component; | |||
| ComponentLayout& layout = *document.getComponentLayout(); | |||
| properties.add (new ImageButtonProportionProperty (layout, ib)); | |||
| properties.add (new ImageButtonResourceProperty (layout, ib, normalImage, "normal image")); | |||
| properties.add (new ImageButtonOpacityProperty (layout, ib, "opacity", normalImage)); | |||
| properties.add (new ImageButtonColourProperty (layout, ib, "overlay col.", normalImage)); | |||
| properties.add (new ImageButtonResourceProperty (layout, ib, overImage, "over image")); | |||
| properties.add (new ImageButtonOpacityProperty (layout, ib, "opacity", overImage)); | |||
| properties.add (new ImageButtonColourProperty (layout, ib, "overlay col.", overImage)); | |||
| properties.add (new ImageButtonResourceProperty (layout, ib, downImage, "down image")); | |||
| properties.add (new ImageButtonOpacityProperty (layout, ib, "opacity", downImage)); | |||
| properties.add (new ImageButtonColourProperty (layout, ib, "overlay col.", downImage)); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| XmlElement* e = ButtonHandler::createXmlFor (comp, layout); | |||
| ImageButton* const ib = (ImageButton*) comp; | |||
| e->setAttribute ("keepProportions", doesImageKeepProportions (ib)); | |||
| e->setAttribute ("resourceNormal", getImageResource (ib, normalImage)); | |||
| e->setAttribute ("opacityNormal", getImageOpacity (ib, normalImage)); | |||
| e->setAttribute ("colourNormal", getImageColour (ib, normalImage).toString()); | |||
| e->setAttribute ("resourceOver", getImageResource (ib, overImage)); | |||
| e->setAttribute ("opacityOver", getImageOpacity (ib, overImage)); | |||
| e->setAttribute ("colourOver", getImageColour (ib, overImage).toString()); | |||
| e->setAttribute ("resourceDown", getImageResource (ib, downImage)); | |||
| e->setAttribute ("opacityDown", getImageOpacity (ib, downImage)); | |||
| e->setAttribute ("colourDown", getImageColour (ib, downImage).toString()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ButtonHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| ImageButton* const ib = (ImageButton*) comp; | |||
| ComponentLayout& l = const_cast <ComponentLayout&> (*layout); | |||
| setImageKeepProportions (l, ib, xml.getBoolAttribute ("keepProportions", true), false); | |||
| setImageResource (l, ib, normalImage, xml.getStringAttribute ("resourceNormal", String::empty), false); | |||
| setImageOpacity (l, ib, normalImage, (float) xml.getDoubleAttribute ("opacityNormal", 1.0f), false); | |||
| setImageColour (l, ib, normalImage, Colour::fromString (xml.getStringAttribute ("colourNormal", "0")), false); | |||
| setImageResource (l, ib, overImage, xml.getStringAttribute ("resourceOver", String::empty), false); | |||
| setImageOpacity (l, ib, overImage, (float) xml.getDoubleAttribute ("opacityOver", 1.0f), false); | |||
| setImageColour (l, ib, overImage, Colour::fromString (xml.getStringAttribute ("colourOver", "0")), false); | |||
| setImageResource (l, ib, downImage, xml.getStringAttribute ("resourceDown", String::empty), false); | |||
| setImageOpacity (l, ib, downImage, (float) xml.getDoubleAttribute ("opacityDown", 1.0f), false); | |||
| setImageColour (l, ib, downImage, Colour::fromString (xml.getStringAttribute ("colourDown", "0")), false); | |||
| return true; | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ButtonHandler::fillInCreationCode (code, component, memberVariableName); | |||
| ImageButton* const ib = dynamic_cast <ImageButton*> (component); | |||
| String s; | |||
| s << getColourIntialisationCode (component, memberVariableName) | |||
| << '\n'; | |||
| const String indent (String::repeatedString (" ", memberVariableName.length() + 13)); | |||
| s << memberVariableName << "->setImages (false, true, " | |||
| << CodeHelpers::boolLiteral (doesImageKeepProportions (ib)) << ",\n" | |||
| << indent | |||
| << getImageCreationCode (ib, normalImage) << ", " | |||
| << CodeHelpers::floatLiteral (getImageOpacity (ib, normalImage), 3) << ", " | |||
| << CodeHelpers::colourToCode (getImageColour (ib, normalImage)) << ",\n" | |||
| << indent | |||
| << getImageCreationCode (ib, overImage) << ", " | |||
| << CodeHelpers::floatLiteral (getImageOpacity (ib, overImage), 3) << ", " | |||
| << CodeHelpers::colourToCode (getImageColour (ib, overImage)) << ",\n" | |||
| << indent | |||
| << getImageCreationCode (ib, downImage) << ", " | |||
| << CodeHelpers::floatLiteral (getImageOpacity (ib, downImage), 3) << ", " | |||
| << CodeHelpers::colourToCode (getImageColour (ib, downImage)) | |||
| << ");\n"; | |||
| code.constructorCode += s; | |||
| } | |||
| static String getImageCreationCode (ImageButton* ib, const ImageRole role) | |||
| { | |||
| const String resName (getImageResource (ib, role)); | |||
| if (resName.isEmpty()) | |||
| return "Image()"; | |||
| return "ImageCache::getFromMemory (" + resName + ", " + resName + "Size)"; | |||
| } | |||
| //============================================================================== | |||
| class ImageButtonResourceProperty : public ImageResourceProperty <ImageButton> | |||
| { | |||
| public: | |||
| ImageButtonResourceProperty (ComponentLayout& layout_, ImageButton* const owner_, const ImageRole role_, const String& name) | |||
| : ImageResourceProperty <ImageButton> (*layout_.getDocument(), owner_, name, true), | |||
| role (role_), | |||
| layout (layout_) | |||
| { | |||
| } | |||
| void setResource (const String& newName) | |||
| { | |||
| setImageResource (layout, element, role, newName, true); | |||
| } | |||
| String getResource() const | |||
| { | |||
| return getImageResource (element, role); | |||
| } | |||
| private: | |||
| const ImageRole role; | |||
| ComponentLayout& layout; | |||
| }; | |||
| class SetImageResourceAction : public ComponentUndoableAction <ImageButton> | |||
| { | |||
| public: | |||
| SetImageResourceAction (ImageButton* const button, | |||
| ComponentLayout& layout_, | |||
| const ImageRole role_, | |||
| const String& newResource_) | |||
| : ComponentUndoableAction <ImageButton> (button, layout_), | |||
| newResource (newResource_), | |||
| role (role_), | |||
| layout (layout_) | |||
| { | |||
| oldResource = ImageButtonHandler::getImageResource (button, role_); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageResource (layout, getComponent(), role, newResource, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageResource (layout, getComponent(), role, oldResource, false); | |||
| return true; | |||
| } | |||
| private: | |||
| String newResource, oldResource; | |||
| const ImageRole role; | |||
| ComponentLayout& layout; | |||
| }; | |||
| //============================================================================== | |||
| static void setImageResource (ComponentLayout& layout, ImageButton* button, const ImageRole role, const String& newName, const bool undoable) | |||
| { | |||
| jassert (role < 3); | |||
| if (role < 3 && getImageResource (button, role) != newName) | |||
| { | |||
| if (undoable) | |||
| { | |||
| layout.getDocument()->perform (new SetImageResourceAction (button, layout, role, newName), | |||
| "Change image resource"); | |||
| } | |||
| else | |||
| { | |||
| button->getProperties().set ("resource" + String ((int) role), newName); | |||
| updateButtonImages (*layout.getDocument(), button); | |||
| layout.changed(); | |||
| } | |||
| } | |||
| } | |||
| static String getImageResource (ImageButton* button, const ImageRole role) | |||
| { | |||
| jassert (role < 3); | |||
| return button->getProperties() ["resource" + String ((int) role)].toString(); | |||
| } | |||
| //============================================================================== | |||
| class SetImageKeepsPropAction : public ComponentUndoableAction <ImageButton> | |||
| { | |||
| public: | |||
| SetImageKeepsPropAction (ImageButton* const button, | |||
| ComponentLayout& layout_, | |||
| const bool newState_) | |||
| : ComponentUndoableAction <ImageButton> (button, layout_), | |||
| newState (newState_), | |||
| layout (layout_) | |||
| { | |||
| oldState = ImageButtonHandler::doesImageKeepProportions (button); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageKeepProportions (layout, getComponent(), newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageKeepProportions (layout, getComponent(), oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| bool newState, oldState; | |||
| ComponentLayout& layout; | |||
| }; | |||
| static bool doesImageKeepProportions (ImageButton* button) | |||
| { | |||
| return button->getProperties().getWithDefault ("keepImageProp", true); | |||
| } | |||
| static void setImageKeepProportions (ComponentLayout& layout, ImageButton* button, const bool newState, const bool undoable) | |||
| { | |||
| if (undoable) | |||
| { | |||
| layout.perform (new SetImageKeepsPropAction (button, layout, newState), "change imagebutton proportion mode"); | |||
| } | |||
| else | |||
| { | |||
| button->getProperties().set ("keepImageProp", newState); | |||
| updateButtonImages (*layout.getDocument(), button); | |||
| layout.changed(); | |||
| } | |||
| } | |||
| class ImageButtonProportionProperty : public ComponentBooleanProperty <ImageButton> | |||
| { | |||
| public: | |||
| ImageButtonProportionProperty (ComponentLayout& layout_, ImageButton* const owner_) | |||
| : ComponentBooleanProperty <ImageButton> ("proportional", "maintain image proportions", "scale to fit", | |||
| owner_, *layout_.getDocument()), | |||
| layout (layout_) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| setImageKeepProportions (layout, component, newState, true); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return doesImageKeepProportions (component); | |||
| } | |||
| private: | |||
| ComponentLayout& layout; | |||
| }; | |||
| //============================================================================== | |||
| class SetImageOpacityAction : public ComponentUndoableAction <ImageButton> | |||
| { | |||
| public: | |||
| SetImageOpacityAction (ImageButton* const button, | |||
| ComponentLayout& layout_, | |||
| const ImageRole role_, | |||
| const float newState_) | |||
| : ComponentUndoableAction <ImageButton> (button, layout_), | |||
| role (role_), | |||
| newState (newState_), | |||
| layout (layout_) | |||
| { | |||
| oldState = ImageButtonHandler::getImageOpacity (button, role_); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageOpacity (layout, getComponent(), role, newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageOpacity (layout, getComponent(), role, oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| const ImageRole role; | |||
| float newState, oldState; | |||
| ComponentLayout& layout; | |||
| }; | |||
| static float getImageOpacity (ImageButton* button, const ImageRole role) | |||
| { | |||
| return (float) button->getProperties().getWithDefault ("imageOpacity" + String ((int) role), 1.0f); | |||
| } | |||
| static void setImageOpacity (ComponentLayout& layout, ImageButton* button, const ImageRole role, const float opacity, const bool undoable) | |||
| { | |||
| if (undoable) | |||
| { | |||
| layout.perform (new SetImageOpacityAction (button, layout, role, opacity), "change imagebutton opacity"); | |||
| } | |||
| else | |||
| { | |||
| button->getProperties().set ("imageOpacity" + String ((int) role), opacity); | |||
| updateButtonImages (*layout.getDocument(), button); | |||
| layout.changed(); | |||
| } | |||
| } | |||
| class ImageButtonOpacityProperty : public SliderPropertyComponent | |||
| { | |||
| public: | |||
| ImageButtonOpacityProperty (ComponentLayout& layout_, ImageButton* const owner_, | |||
| const String& name, const ImageRole role_) | |||
| : SliderPropertyComponent (name, 0.0, 1.0, 0.0), | |||
| owner (owner_), | |||
| layout (layout_), | |||
| role (role_) | |||
| { | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| setImageOpacity (layout, owner, role, (float) newValue, true); | |||
| } | |||
| double getValue() const | |||
| { | |||
| return getImageOpacity (owner, role); | |||
| } | |||
| private: | |||
| ImageButton* const owner; | |||
| ComponentLayout& layout; | |||
| const ImageRole role; | |||
| }; | |||
| //============================================================================== | |||
| class SetImageColourAction : public ComponentUndoableAction <ImageButton> | |||
| { | |||
| public: | |||
| SetImageColourAction (ImageButton* const button, | |||
| ComponentLayout& layout_, | |||
| const ImageRole role_, | |||
| const Colour& newState_) | |||
| : ComponentUndoableAction <ImageButton> (button, layout_), | |||
| role (role_), | |||
| newState (newState_), | |||
| layout (layout_) | |||
| { | |||
| oldState = ImageButtonHandler::getImageColour (button, role_); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageColour (layout, getComponent(), role, newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| ImageButtonHandler::setImageColour (layout, getComponent(), role, oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| const ImageRole role; | |||
| Colour newState, oldState; | |||
| ComponentLayout& layout; | |||
| }; | |||
| static Colour getImageColour (ImageButton* button, const ImageRole role) | |||
| { | |||
| return Colour::fromString (button->getProperties().getWithDefault ("imageColour" + String ((int) role), "0").toString()); | |||
| } | |||
| static void setImageColour (ComponentLayout& layout, ImageButton* button, const ImageRole role, const Colour& colour, const bool undoable) | |||
| { | |||
| if (undoable) | |||
| { | |||
| layout.perform (new SetImageColourAction (button, layout, role, colour), "change imagebutton colour"); | |||
| } | |||
| else | |||
| { | |||
| button->getProperties().set ("imageColour" + String ((int) role), colour.toString()); | |||
| updateButtonImages (*layout.getDocument(), button); | |||
| layout.changed(); | |||
| } | |||
| } | |||
| class ImageButtonColourProperty : public JucerColourPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| ImageButtonColourProperty (ComponentLayout& layout_, ImageButton* const owner_, | |||
| const String& name, const ImageRole role_) | |||
| : JucerColourPropertyComponent (name, false), | |||
| owner (owner_), | |||
| layout (layout_), | |||
| role (role_) | |||
| { | |||
| layout_.getDocument()->addChangeListener (this); | |||
| } | |||
| ~ImageButtonColourProperty() | |||
| { | |||
| layout.getDocument()->removeChangeListener (this); | |||
| } | |||
| void setColour (const Colour& newColour) | |||
| { | |||
| setImageColour (layout, owner, role, newColour, true); | |||
| } | |||
| Colour getColour() const | |||
| { | |||
| return getImageColour (owner, role); | |||
| } | |||
| void resetToDefault() {} | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| ImageButton* const owner; | |||
| ComponentLayout& layout; | |||
| const ImageRole role; | |||
| }; | |||
| //============================================================================== | |||
| static void updateButtonImages (JucerDocument& document, ImageButton* const ib) | |||
| { | |||
| Image norm = document.getResources().getImageFromCache (getImageResource (ib, normalImage)); | |||
| Image over = document.getResources().getImageFromCache (getImageResource (ib, overImage)); | |||
| Image down = document.getResources().getImageFromCache (getImageResource (ib, downImage)); | |||
| ib->setImages (false, true, doesImageKeepProportions (ib), | |||
| norm, | |||
| getImageOpacity (ib, normalImage), | |||
| getImageColour (ib, normalImage), | |||
| over, | |||
| getImageOpacity (ib, overImage), | |||
| getImageColour (ib, overImage), | |||
| down, | |||
| getImageOpacity (ib, downImage), | |||
| getImageColour (ib, downImage)); | |||
| } | |||
| }; | |||
| @@ -0,0 +1,277 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_JUCERCOMPONENTHANDLER_JUCEHEADER__ | |||
| #define __JUCER_JUCERCOMPONENTHANDLER_JUCEHEADER__ | |||
| #include "../ui/jucer_TestComponent.h" | |||
| #include "../properties/jucer_FilePropertyComponent.h" | |||
| #include "../properties/jucer_ComponentTextProperty.h" | |||
| #include "jucer_ComponentUndoableAction.h" | |||
| #include "../../Project/jucer_ProjectContentComponent.h" | |||
| //============================================================================== | |||
| class JucerComponentHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| JucerComponentHandler() | |||
| : ComponentTypeHandler ("Jucer Component", "xxx", | |||
| typeid (TestComponent), 300, 200) | |||
| {} | |||
| Component* createNewComponent (JucerDocument* doc) | |||
| { | |||
| return new TestComponent (doc, 0, false); | |||
| } | |||
| String getXmlTagName() const noexcept { return "JUCERCOMP"; } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| TestComponent* const tc = dynamic_cast <TestComponent*> (comp); | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("sourceFile", tc->getFilename()); | |||
| e->setAttribute ("constructorParams", tc->getConstructorParams()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| TestComponent* const tc = dynamic_cast <TestComponent*> (comp); | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| tc->setFilename (xml.getStringAttribute ("sourceFile", tc->getFilename())); | |||
| tc->setConstructorParams (xml.getStringAttribute ("constructorParams")); | |||
| return true; | |||
| } | |||
| String getClassName (Component* comp) const | |||
| { | |||
| TestComponent* const tc = dynamic_cast <TestComponent*> (comp); | |||
| String jucerCompClassName; | |||
| if (tc->getDocument() != 0) | |||
| jucerCompClassName = tc->getDocument()->getClassName(); | |||
| if (jucerCompClassName.isEmpty()) | |||
| jucerCompClassName = "Component"; | |||
| return jucerCompClassName; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| TestComponent* const tc = dynamic_cast <TestComponent*> (component); | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| properties.add (new JucerCompFileProperty (tc, document)); | |||
| properties.add (new ConstructorParamsProperty (tc, document)); | |||
| properties.add (new JucerCompOpenDocProperty (tc)); | |||
| } | |||
| String getCreationParameters (Component* component) | |||
| { | |||
| TestComponent* const tc = dynamic_cast <TestComponent*> (component); | |||
| return tc->getConstructorParams().trim(); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| TestComponent* const tc = dynamic_cast <TestComponent*> (component); | |||
| code.includeFilesH.add (tc->getFilename().replace (".cpp", ".h")); | |||
| } | |||
| //============================================================================== | |||
| class JucerCompFileChangeAction : public ComponentUndoableAction <TestComponent> | |||
| { | |||
| public: | |||
| JucerCompFileChangeAction (TestComponent* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <TestComponent> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getFilename(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setFilename (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setFilename (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| static void setJucerComponentFile (JucerDocument& document, TestComponent* comp, const String& newFilename) | |||
| { | |||
| jassert (comp != 0); | |||
| if (comp != 0) | |||
| document.perform (new JucerCompFileChangeAction (comp, *document.getComponentLayout(), newFilename), | |||
| "Change Jucer component file"); | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class JucerCompFileProperty : public FilePropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| JucerCompFileProperty (TestComponent* const comp, JucerDocument& doc) | |||
| : FilePropertyComponent ("Jucer file", false, true), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~JucerCompFileProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setFile (const File& newFile) | |||
| { | |||
| setJucerComponentFile (document, component, | |||
| newFile.getRelativePathFrom (document.getCppFile().getParentDirectory()) | |||
| .replaceCharacter ('\\', '/')); | |||
| } | |||
| File getFile() const | |||
| { | |||
| return component->findFile(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| TestComponent* const component; | |||
| JucerDocument& document; | |||
| }; | |||
| //============================================================================== | |||
| class JucerCompOpenDocProperty : public ButtonPropertyComponent | |||
| { | |||
| public: | |||
| JucerCompOpenDocProperty (TestComponent* const c) | |||
| : ButtonPropertyComponent ("edit", false), | |||
| component (c) | |||
| { | |||
| } | |||
| void buttonClicked() | |||
| { | |||
| if (ProjectContentComponent* const pcc = findParentComponentOfClass<ProjectContentComponent>()) | |||
| pcc->showEditorForFile (component->findFile(), true); | |||
| } | |||
| String getButtonText() const | |||
| { | |||
| return "Open file for editing"; | |||
| } | |||
| private: | |||
| TestComponent* const component; | |||
| }; | |||
| //============================================================================== | |||
| class ConstructorParamsProperty : public ComponentTextProperty <TestComponent> | |||
| { | |||
| public: | |||
| ConstructorParamsProperty (TestComponent* comp, JucerDocument& document) | |||
| : ComponentTextProperty <TestComponent> ("constructor params", 512, false, comp, document) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ConstructorParamChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change Viewport content constructor params"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getConstructorParams(); | |||
| } | |||
| private: | |||
| class ConstructorParamChangeAction : public ComponentUndoableAction <TestComponent> | |||
| { | |||
| public: | |||
| ConstructorParamChangeAction (TestComponent* const comp, ComponentLayout& layout, const String& newValue_) | |||
| : ComponentUndoableAction <TestComponent> (comp, layout), | |||
| newValue (newValue_) | |||
| { | |||
| oldValue = comp->getConstructorParams(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setConstructorParams (newValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setConstructorParams (oldValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| String newValue, oldValue; | |||
| }; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_JUCERCOMPONENTHANDLER_JUCEHEADER__ | |||
| @@ -0,0 +1,641 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class LabelHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| LabelHandler() | |||
| : ComponentTypeHandler ("Label", "Label", typeid (Label), 150, 24) | |||
| { | |||
| registerColour (Label::backgroundColourId, "background", "bkgCol"); | |||
| registerColour (Label::textColourId, "text", "textCol"); | |||
| registerColour (Label::outlineColourId, "outline", "outlineCol"); | |||
| registerColour (TextEditor::textColourId, "editor text", "edTextCol"); | |||
| registerColour (TextEditor::backgroundColourId, "editor bkg", "edBkgCol"); | |||
| registerColour (TextEditor::highlightColourId, "highlight", "hiliteCol"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new Label ("new label", "label text"); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| Label* const l = dynamic_cast <Label*> (comp); | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("labelText", l->getText()); | |||
| e->setAttribute ("editableSingleClick", l->isEditableOnSingleClick()); | |||
| e->setAttribute ("editableDoubleClick", l->isEditableOnDoubleClick()); | |||
| e->setAttribute ("focusDiscardsChanges", l->doesLossOfFocusDiscardChanges()); | |||
| e->setAttribute ("fontname", l->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()).toString()); | |||
| e->setAttribute ("fontsize", roundToInt (l->getFont().getHeight() * 100.0) / 100.0); | |||
| e->setAttribute ("bold", l->getFont().isBold()); | |||
| e->setAttribute ("italic", l->getFont().isItalic()); | |||
| e->setAttribute ("justification", l->getJustificationType().getFlags()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| Label* const l = dynamic_cast <Label*> (comp); | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| Label defaultLabel (String::empty, String::empty); | |||
| Font font; | |||
| font.setHeight ((float) xml.getDoubleAttribute ("fontsize", 15.0)); | |||
| font.setBold (xml.getBoolAttribute ("bold", false)); | |||
| font.setItalic (xml.getBoolAttribute ("italic", false)); | |||
| l->setFont (font); | |||
| l->getProperties().set ("typefaceName", xml.getStringAttribute ("fontname", FontPropertyComponent::getDefaultFont())); | |||
| updateLabelFont (l); | |||
| l->setJustificationType (Justification (xml.getIntAttribute ("justification", Justification::centred))); | |||
| l->setText (xml.getStringAttribute ("labelText", "Label Text"), false); | |||
| l->setEditable (xml.getBoolAttribute ("editableSingleClick", defaultLabel.isEditableOnSingleClick()), | |||
| xml.getBoolAttribute ("editableDoubleClick", defaultLabel.isEditableOnDoubleClick()), | |||
| xml.getBoolAttribute ("focusDiscardsChanges", defaultLabel.doesLossOfFocusDiscardChanges())); | |||
| return true; | |||
| } | |||
| static void updateLabelFont (Label* label) | |||
| { | |||
| Font f (label->getFont()); | |||
| f = FontPropertyComponent::applyNameToFont (label->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()), f); | |||
| label->setFont (f); | |||
| } | |||
| String getCreationParameters (Component* component) | |||
| { | |||
| Label* const l = dynamic_cast <Label*> (component); | |||
| return quotedString (component->getName()) | |||
| + ",\n" | |||
| + quotedString (l->getText()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| Label* const l = dynamic_cast <Label*> (component); | |||
| String s; | |||
| s << memberVariableName << "->setFont (" | |||
| << FontPropertyComponent::getCompleteFontCode (l->getFont(), l->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont())) | |||
| << ");\n" | |||
| << memberVariableName << "->setJustificationType (" | |||
| << CodeHelpers::justificationToCode (l->getJustificationType()) | |||
| << ");\n" | |||
| << memberVariableName << "->setEditable (" | |||
| << CodeHelpers::boolLiteral (l->isEditableOnSingleClick()) << ", " | |||
| << CodeHelpers::boolLiteral (l->isEditableOnDoubleClick()) << ", " | |||
| << CodeHelpers::boolLiteral (l->doesLossOfFocusDiscardChanges()) << ");\n" | |||
| << getColourIntialisationCode (component, memberVariableName); | |||
| if (needsCallback (component)) | |||
| s << memberVariableName << "->addListener (this);\n"; | |||
| s << '\n'; | |||
| code.constructorCode += s; | |||
| } | |||
| void fillInGeneratedCode (Component* component, GeneratedCode& code) | |||
| { | |||
| ComponentTypeHandler::fillInGeneratedCode (component, code); | |||
| if (needsCallback (component)) | |||
| { | |||
| String& callback = code.getCallbackCode ("public LabelListener", | |||
| "void", | |||
| "labelTextChanged (Label* labelThatHasChanged)", | |||
| true); | |||
| if (callback.trim().isNotEmpty()) | |||
| callback << "else "; | |||
| const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component)); | |||
| const String userCodeComment ("UserLabelCode_" + memberVariableName); | |||
| callback | |||
| << "if (labelThatHasChanged == " << memberVariableName | |||
| << ")\n{\n //[" << userCodeComment << "] -- add your label text handling code here..\n //[/" << userCodeComment << "]\n}\n"; | |||
| } | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| Label* const l = dynamic_cast <Label*> (component); | |||
| properties.add (new LabelTextProperty (l, document)); | |||
| properties.add (new LabelJustificationProperty (l, document)); | |||
| properties.add (new FontNameProperty (l, document)); | |||
| properties.add (new FontSizeProperty (l, document)); | |||
| properties.add (new FontStyleProperty (l, document)); | |||
| addColourProperties (component, document, properties); | |||
| properties.add (new LabelEditableProperty (l, document)); | |||
| if (l->isEditableOnDoubleClick() || l->isEditableOnSingleClick()) | |||
| properties.add (new LabelLossOfFocusProperty (l, document)); | |||
| } | |||
| static bool needsCallback (Component* label) | |||
| { | |||
| return ((Label*) label)->isEditableOnSingleClick() | |||
| || ((Label*) label)->isEditableOnDoubleClick(); // xxx should be configurable | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class LabelTextProperty : public ComponentTextProperty <Label> | |||
| { | |||
| public: | |||
| LabelTextProperty (Label* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <Label> ("text", 10000, true, comp, doc) | |||
| {} | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new LabelTextChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change Label text"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getText(); | |||
| } | |||
| private: | |||
| class LabelTextChangeAction : public ComponentUndoableAction <Label> | |||
| { | |||
| public: | |||
| LabelTextChangeAction (Label* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <Label> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getText(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setText (newState, false); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setText (oldState, false); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class LabelEditableProperty : public ComponentChoiceProperty <Label> | |||
| { | |||
| public: | |||
| LabelEditableProperty (Label* comp, JucerDocument& doc) | |||
| : ComponentChoiceProperty <Label> ("editing", comp, doc) | |||
| { | |||
| choices.add ("read-only"); | |||
| choices.add ("edit on single-click"); | |||
| choices.add ("edit on double-click"); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| document.perform (new LabelEditableChangeAction (component, *document.getComponentLayout(), newIndex), | |||
| "Change Label editability"); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| return component->isEditableOnSingleClick() | |||
| ? 1 | |||
| : (component->isEditableOnDoubleClick() ? 2 : 0); | |||
| } | |||
| private: | |||
| class LabelEditableChangeAction : public ComponentUndoableAction <Label> | |||
| { | |||
| public: | |||
| LabelEditableChangeAction (Label* const comp, ComponentLayout& layout, const int newState_) | |||
| : ComponentUndoableAction <Label> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isEditableOnSingleClick() | |||
| ? 1 | |||
| : (comp->isEditableOnDoubleClick() ? 2 : 0); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setEditable (newState == 1, newState >= 1, getComponent()->doesLossOfFocusDiscardChanges()); | |||
| changed(); | |||
| layout.getSelectedSet().changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setEditable (oldState == 1, oldState >= 1, getComponent()->doesLossOfFocusDiscardChanges()); | |||
| changed(); | |||
| layout.getSelectedSet().changed(); | |||
| return true; | |||
| } | |||
| int newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class LabelLossOfFocusProperty : public ComponentChoiceProperty <Label> | |||
| { | |||
| public: | |||
| LabelLossOfFocusProperty (Label* comp, JucerDocument& doc) | |||
| : ComponentChoiceProperty <Label> ("focus", comp, doc) | |||
| { | |||
| choices.add ("loss of focus discards changes"); | |||
| choices.add ("loss of focus commits changes"); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| document.perform (new LabelFocusLossChangeAction (component, *document.getComponentLayout(), newIndex == 0), | |||
| "Change Label focus behaviour"); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| return component->doesLossOfFocusDiscardChanges() ? 0 : 1; | |||
| } | |||
| private: | |||
| class LabelFocusLossChangeAction : public ComponentUndoableAction <Label> | |||
| { | |||
| public: | |||
| LabelFocusLossChangeAction (Label* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <Label> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->doesLossOfFocusDiscardChanges(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setEditable (getComponent()->isEditableOnSingleClick(), | |||
| getComponent()->isEditableOnDoubleClick(), | |||
| newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setEditable (getComponent()->isEditableOnSingleClick(), | |||
| getComponent()->isEditableOnDoubleClick(), | |||
| oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class LabelJustificationProperty : public JustificationProperty, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| LabelJustificationProperty (Label* const label_, JucerDocument& doc) | |||
| : JustificationProperty ("layout", false), | |||
| label (label_), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~LabelJustificationProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setJustification (const Justification& newJustification) | |||
| { | |||
| document.perform (new LabelJustifyChangeAction (label, *document.getComponentLayout(), newJustification), | |||
| "Change Label justification"); | |||
| } | |||
| const Justification getJustification() const | |||
| { | |||
| return label->getJustificationType(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| Label* const label; | |||
| JucerDocument& document; | |||
| class LabelJustifyChangeAction : public ComponentUndoableAction <Label> | |||
| { | |||
| public: | |||
| LabelJustifyChangeAction (Label* const comp, ComponentLayout& layout, const Justification& newState_) | |||
| : ComponentUndoableAction <Label> (comp, layout), | |||
| newState (newState_), | |||
| oldState (comp->getJustificationType()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setJustificationType (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setJustificationType (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| Justification newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class FontNameProperty : public FontPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| FontNameProperty (Label* const label_, JucerDocument& doc) | |||
| : FontPropertyComponent ("font"), | |||
| label (label_), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~FontNameProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setTypefaceName (const String& newFontName) | |||
| { | |||
| document.perform (new FontNameChangeAction (label, *document.getComponentLayout(), newFontName), | |||
| "Change Label typeface"); | |||
| } | |||
| String getTypefaceName() const | |||
| { | |||
| return label->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| Label* const label; | |||
| JucerDocument& document; | |||
| class FontNameChangeAction : public ComponentUndoableAction <Label> | |||
| { | |||
| public: | |||
| FontNameChangeAction (Label* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <Label> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->getProperties().set ("typefaceName", newState); | |||
| LabelHandler::updateLabelFont (getComponent()); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->getProperties().set ("typefaceName", oldState); | |||
| LabelHandler::updateLabelFont (getComponent()); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class FontSizeProperty : public SliderPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| FontSizeProperty (Label* const label_, JucerDocument& doc) | |||
| : SliderPropertyComponent ("size", 1.0, 250.0, 0.1, 0.3), | |||
| label (label_), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~FontSizeProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| document.getUndoManager().undoCurrentTransactionOnly(); | |||
| document.perform (new FontSizeChangeAction (label, *document.getComponentLayout(), (float) newValue), | |||
| "Change Label font size"); | |||
| } | |||
| double getValue() const | |||
| { | |||
| return label->getFont().getHeight(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| Label* const label; | |||
| JucerDocument& document; | |||
| class FontSizeChangeAction : public ComponentUndoableAction <Label> | |||
| { | |||
| public: | |||
| FontSizeChangeAction (Label* const comp, ComponentLayout& layout, const float newState_) | |||
| : ComponentUndoableAction <Label> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getFont().getHeight(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| Font f (getComponent()->getFont()); | |||
| f.setHeight ((float) newState); | |||
| getComponent()->setFont (f); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| Font f (getComponent()->getFont()); | |||
| f.setHeight ((float) oldState); | |||
| getComponent()->setFont (f); | |||
| changed(); | |||
| return true; | |||
| } | |||
| float newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class FontStyleProperty : public ChoicePropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| FontStyleProperty (Label* const label_, JucerDocument& doc) | |||
| : ChoicePropertyComponent ("style"), | |||
| label (label_), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| choices.add ("normal"); | |||
| choices.add ("bold"); | |||
| choices.add ("italic"); | |||
| choices.add ("bold + italic"); | |||
| } | |||
| ~FontStyleProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| Font f (label->getFont()); | |||
| f.setBold (newIndex == 1 || newIndex == 3); | |||
| f.setItalic (newIndex == 2 || newIndex == 3); | |||
| document.perform (new FontStyleChangeAction (label, *document.getComponentLayout(), f), | |||
| "Change Label font style"); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| if (label->getFont().isBold() && label->getFont().isItalic()) | |||
| return 3; | |||
| else if (label->getFont().isBold()) | |||
| return 1; | |||
| else if (label->getFont().isItalic()) | |||
| return 2; | |||
| return 0; | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| Label* const label; | |||
| JucerDocument& document; | |||
| class FontStyleChangeAction : public ComponentUndoableAction <Label> | |||
| { | |||
| public: | |||
| FontStyleChangeAction (Label* const comp, ComponentLayout& layout, const Font& newState_) | |||
| : ComponentUndoableAction <Label> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getFont(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setFont (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setFont (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| Font newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,683 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class SliderHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| SliderHandler() | |||
| : ComponentTypeHandler ("Slider", "Slider", typeid (Slider), 150, 24) | |||
| { | |||
| registerColour (Slider::backgroundColourId, "background", "bkgcol"); | |||
| registerColour (Slider::thumbColourId, "thumb", "thumbcol"); | |||
| registerColour (Slider::trackColourId, "track", "trackcol"); | |||
| registerColour (Slider::rotarySliderFillColourId, "rotary fill", "rotarysliderfill"); | |||
| registerColour (Slider::rotarySliderOutlineColourId, "rotary outln", "rotaryslideroutline"); | |||
| registerColour (Slider::textBoxTextColourId, "textbox text", "textboxtext"); | |||
| registerColour (Slider::textBoxBackgroundColourId, "textbox bkgd", "textboxbkgd"); | |||
| registerColour (Slider::textBoxHighlightColourId, "textbox highlt", "textboxhighlight"); | |||
| registerColour (Slider::textBoxOutlineColourId, "textbox outln", "textboxoutline"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new Slider ("new slider"); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| Slider* const s = dynamic_cast <Slider*> (comp); | |||
| e->setAttribute ("min", s->getMinimum()); | |||
| e->setAttribute ("max", s->getMaximum()); | |||
| e->setAttribute ("int", s->getInterval()); | |||
| e->setAttribute ("style", sliderStyleToString (s->getSliderStyle())); | |||
| e->setAttribute ("textBoxPos", textBoxPosToString (s->getTextBoxPosition())); | |||
| e->setAttribute ("textBoxEditable", s->isTextBoxEditable()); | |||
| e->setAttribute ("textBoxWidth", s->getTextBoxWidth()); | |||
| e->setAttribute ("textBoxHeight", s->getTextBoxHeight()); | |||
| e->setAttribute ("skewFactor", s->getSkewFactor()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| Slider* const s = dynamic_cast <Slider*> (comp); | |||
| s->setRange (xml.getDoubleAttribute ("min", 0.0), | |||
| xml.getDoubleAttribute ("max", 10.0), | |||
| xml.getDoubleAttribute ("int", 0.0)); | |||
| s->setSliderStyle (sliderStringToStyle (xml.getStringAttribute ("style", "LinearHorizontal"))); | |||
| s->setTextBoxStyle (stringToTextBoxPos (xml.getStringAttribute ("textBoxPos", "TextBoxLeft")), | |||
| ! xml.getBoolAttribute ("textBoxEditable", true), | |||
| xml.getIntAttribute ("textBoxWidth", 80), | |||
| xml.getIntAttribute ("textBoxHeight", 20)); | |||
| s->setSkewFactor (xml.getDoubleAttribute ("skewFactor", 1.0)); | |||
| return true; | |||
| } | |||
| String getCreationParameters (Component* component) | |||
| { | |||
| return quotedString (component->getName()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| Slider* const s = dynamic_cast <Slider*> (component); | |||
| String r; | |||
| r << memberVariableName << "->setRange (" | |||
| << s->getMinimum() << ", " << s->getMaximum() << ", " << s->getInterval() | |||
| << ");\n" | |||
| << memberVariableName << "->setSliderStyle (Slider::" | |||
| << sliderStyleToString (s->getSliderStyle()) << ");\n" | |||
| << memberVariableName << "->setTextBoxStyle (Slider::" | |||
| << textBoxPosToString (s->getTextBoxPosition()) | |||
| << ", " << CodeHelpers::boolLiteral (! s->isTextBoxEditable()) | |||
| << ", " << s->getTextBoxWidth() << ", " << s->getTextBoxHeight() << ");\n" | |||
| << getColourIntialisationCode (component, memberVariableName); | |||
| if (needsCallback (component)) | |||
| r << memberVariableName << "->addListener (this);\n"; | |||
| if (s->getSkewFactor() != 1.0) | |||
| r << memberVariableName << "->setSkewFactor (" << s->getSkewFactor() << ");\n"; | |||
| r << '\n'; | |||
| code.constructorCode += r; | |||
| } | |||
| void fillInGeneratedCode (Component* component, GeneratedCode& code) | |||
| { | |||
| ComponentTypeHandler::fillInGeneratedCode (component, code); | |||
| if (needsCallback (component)) | |||
| { | |||
| String& callback = code.getCallbackCode ("public SliderListener", | |||
| "void", | |||
| "sliderValueChanged (Slider* sliderThatWasMoved)", | |||
| true); | |||
| if (callback.isNotEmpty()) | |||
| callback << "else "; | |||
| const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component)); | |||
| const String userCodeComment ("UserSliderCode_" + memberVariableName); | |||
| callback | |||
| << "if (sliderThatWasMoved == " << memberVariableName | |||
| << ")\n{\n //[" << userCodeComment << "] -- add your slider handling code here..\n //[/" << userCodeComment << "]\n}\n"; | |||
| } | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| Slider* s = dynamic_cast <Slider*> (component); | |||
| jassert (s != 0); | |||
| properties.add (new SliderRangeProperty (s, document, "minimum", 0)); | |||
| properties.add (new SliderRangeProperty (s, document, "maximum", 1)); | |||
| properties.add (new SliderRangeProperty (s, document, "interval", 2)); | |||
| properties.add (new SliderTypeProperty (s, document)); | |||
| properties.add (new SliderTextboxProperty (s, document)); | |||
| properties.add (new SliderTextboxEditableProperty (s, document)); | |||
| properties.add (new SliderTextboxSizeProperty (s, document, true)); | |||
| properties.add (new SliderTextboxSizeProperty (s, document, false)); | |||
| properties.add (new SliderSkewProperty (s, document)); | |||
| addColourProperties (component, document, properties); | |||
| } | |||
| static bool needsCallback (Component*) | |||
| { | |||
| return true; //xxx should be a property | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class SliderTypeProperty : public ComponentChoiceProperty <Slider> | |||
| { | |||
| public: | |||
| SliderTypeProperty (Slider* slider, JucerDocument& document) | |||
| : ComponentChoiceProperty <Slider> ("type", slider, document) | |||
| { | |||
| choices.add ("Linear Horizontal"); | |||
| choices.add ("Linear Vertical"); | |||
| choices.add ("Linear Bar"); | |||
| choices.add ("Rotary"); | |||
| choices.add ("Rotary HorizontalDrag"); | |||
| choices.add ("Rotary VerticalDrag"); | |||
| choices.add ("Rotary HorizontalVerticalDrag"); | |||
| choices.add ("Inc/Dec Buttons"); | |||
| choices.add ("Two Value Horizontal"); | |||
| choices.add ("Two Value Vertical"); | |||
| choices.add ("Three Value Horizontal"); | |||
| choices.add ("Three Value Vertical"); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| const Slider::SliderStyle types[] = { Slider::LinearHorizontal, | |||
| Slider::LinearVertical, | |||
| Slider::LinearBar, | |||
| Slider::Rotary, | |||
| Slider::RotaryHorizontalDrag, | |||
| Slider::RotaryVerticalDrag, | |||
| Slider::RotaryHorizontalVerticalDrag, | |||
| Slider::IncDecButtons, | |||
| Slider::TwoValueHorizontal, | |||
| Slider::TwoValueVertical, | |||
| Slider::ThreeValueHorizontal, | |||
| Slider::ThreeValueVertical }; | |||
| if (newIndex >= 0 && newIndex < numElementsInArray (types)) | |||
| { | |||
| document.perform (new SliderTypeChangeAction (component, *document.getComponentLayout(), types [newIndex]), | |||
| "Change Slider style"); | |||
| } | |||
| } | |||
| int getIndex() const | |||
| { | |||
| const Slider::SliderStyle types[] = { Slider::LinearHorizontal, | |||
| Slider::LinearVertical, | |||
| Slider::LinearBar, | |||
| Slider::Rotary, | |||
| Slider::RotaryHorizontalDrag, | |||
| Slider::RotaryVerticalDrag, | |||
| Slider::RotaryHorizontalVerticalDrag, | |||
| Slider::IncDecButtons, | |||
| Slider::TwoValueHorizontal, | |||
| Slider::TwoValueVertical, | |||
| Slider::ThreeValueHorizontal, | |||
| Slider::ThreeValueVertical }; | |||
| for (int i = 0; i < numElementsInArray (types); ++i) | |||
| if (types [i] == dynamic_cast <Slider*> (component)->getSliderStyle()) | |||
| return i; | |||
| return -1; | |||
| } | |||
| private: | |||
| class SliderTypeChangeAction : public ComponentUndoableAction <Slider> | |||
| { | |||
| public: | |||
| SliderTypeChangeAction (Slider* const comp, ComponentLayout& layout, const Slider::SliderStyle newState_) | |||
| : ComponentUndoableAction <Slider> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getSliderStyle(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setSliderStyle (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setSliderStyle (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| Slider::SliderStyle newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class SliderTextboxProperty : public ComponentChoiceProperty <Slider> | |||
| { | |||
| public: | |||
| SliderTextboxProperty (Slider* slider, JucerDocument& document) | |||
| : ComponentChoiceProperty <Slider> ("text position", slider, document) | |||
| { | |||
| choices.add ("No text box"); | |||
| choices.add ("Text box on left"); | |||
| choices.add ("Text box on right"); | |||
| choices.add ("Text box above"); | |||
| choices.add ("Text box below"); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| const Slider::TextEntryBoxPosition types[] = { Slider::NoTextBox, | |||
| Slider::TextBoxLeft, | |||
| Slider::TextBoxRight, | |||
| Slider::TextBoxAbove, | |||
| Slider::TextBoxBelow }; | |||
| if (newIndex >= 0 && newIndex < numElementsInArray (types)) | |||
| { | |||
| document.perform (new SliderTextBoxChangeAction (component, *document.getComponentLayout(), types [newIndex]), | |||
| "Change Slider textbox"); | |||
| } | |||
| } | |||
| int getIndex() const | |||
| { | |||
| const Slider::TextEntryBoxPosition types[] = { Slider::NoTextBox, | |||
| Slider::TextBoxLeft, | |||
| Slider::TextBoxRight, | |||
| Slider::TextBoxAbove, | |||
| Slider::TextBoxBelow }; | |||
| for (int i = 0; i < numElementsInArray (types); ++i) | |||
| if (types [i] == component->getTextBoxPosition()) | |||
| return i; | |||
| return -1; | |||
| } | |||
| private: | |||
| class SliderTextBoxChangeAction : public ComponentUndoableAction <Slider> | |||
| { | |||
| public: | |||
| SliderTextBoxChangeAction (Slider* const comp, ComponentLayout& layout, const Slider::TextEntryBoxPosition newState_) | |||
| : ComponentUndoableAction <Slider> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getTextBoxPosition(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextBoxStyle (newState, | |||
| ! getComponent()->isTextBoxEditable(), | |||
| getComponent()->getTextBoxWidth(), | |||
| getComponent()->getTextBoxHeight()); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextBoxStyle (oldState, | |||
| ! getComponent()->isTextBoxEditable(), | |||
| getComponent()->getTextBoxWidth(), | |||
| getComponent()->getTextBoxHeight()); | |||
| changed(); | |||
| return true; | |||
| } | |||
| Slider::TextEntryBoxPosition newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class SliderTextboxEditableProperty : public ComponentBooleanProperty <Slider> | |||
| { | |||
| public: | |||
| SliderTextboxEditableProperty (Slider* slider, JucerDocument& document) | |||
| : ComponentBooleanProperty <Slider> ("text box mode", "Editable", "Editable", slider, document) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new SliderEditableChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change Slider editability"); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return component->isTextBoxEditable(); | |||
| } | |||
| private: | |||
| class SliderEditableChangeAction : public ComponentUndoableAction <Slider> | |||
| { | |||
| public: | |||
| SliderEditableChangeAction (Slider* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <Slider> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isTextBoxEditable(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextBoxIsEditable (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setTextBoxIsEditable (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class SliderTextboxSizeProperty : public ComponentTextProperty <Slider> | |||
| { | |||
| public: | |||
| SliderTextboxSizeProperty (Slider* slider, JucerDocument& document, const bool isWidth_) | |||
| : ComponentTextProperty <Slider> (isWidth_ ? "text box width" : "text box height", | |||
| 12, false, slider, document), | |||
| isWidth (isWidth_) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new SliderBoxSizeChangeAction (component, *document.getComponentLayout(), isWidth, newText.getIntValue()), | |||
| "Change Slider textbox size"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return String (isWidth ? component->getTextBoxWidth() | |||
| : component->getTextBoxHeight()); | |||
| } | |||
| private: | |||
| const bool isWidth; | |||
| class SliderBoxSizeChangeAction : public ComponentUndoableAction <Slider> | |||
| { | |||
| public: | |||
| SliderBoxSizeChangeAction (Slider* const comp, ComponentLayout& layout, const bool isWidth_, int newSize_) | |||
| : ComponentUndoableAction <Slider> (comp, layout), | |||
| isWidth (isWidth_), | |||
| newSize (newSize_) | |||
| { | |||
| oldSize = isWidth ? comp->getTextBoxWidth() | |||
| : comp->getTextBoxHeight(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| Slider& c = *getComponent(); | |||
| if (isWidth) | |||
| c.setTextBoxStyle (c.getTextBoxPosition(), | |||
| ! c.isTextBoxEditable(), | |||
| newSize, | |||
| c.getTextBoxHeight()); | |||
| else | |||
| c.setTextBoxStyle (c.getTextBoxPosition(), | |||
| ! c.isTextBoxEditable(), | |||
| c.getTextBoxWidth(), | |||
| newSize); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| Slider& c = *getComponent(); | |||
| if (isWidth) | |||
| c.setTextBoxStyle (c.getTextBoxPosition(), | |||
| ! c.isTextBoxEditable(), | |||
| oldSize, | |||
| c.getTextBoxHeight()); | |||
| else | |||
| c.setTextBoxStyle (c.getTextBoxPosition(), | |||
| ! c.isTextBoxEditable(), | |||
| c.getTextBoxWidth(), | |||
| oldSize); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool isWidth; | |||
| int newSize, oldSize; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class SliderRangeProperty : public ComponentTextProperty <Slider> | |||
| { | |||
| public: | |||
| SliderRangeProperty (Slider* slider, JucerDocument& document, | |||
| const String& name, const int rangeParam_) | |||
| : ComponentTextProperty <Slider> (name, 15, false, slider, document), | |||
| rangeParam (rangeParam_) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| double state [3]; | |||
| state [0] = component->getMinimum(); | |||
| state [1] = component->getMaximum(); | |||
| state [2] = component->getInterval(); | |||
| state [rangeParam] = newText.getDoubleValue(); | |||
| document.perform (new SliderRangeChangeAction (component, *document.getComponentLayout(), state), | |||
| "Change Slider range"); | |||
| } | |||
| String getText() const | |||
| { | |||
| Slider* s = dynamic_cast <Slider*> (component); | |||
| jassert (s != nullptr); | |||
| switch (rangeParam) | |||
| { | |||
| case 0: return String (s->getMinimum()); | |||
| case 1: return String (s->getMaximum()); | |||
| case 2: return String (s->getInterval()); | |||
| default: jassertfalse; break; | |||
| } | |||
| return String::empty; | |||
| } | |||
| private: | |||
| const int rangeParam; | |||
| class SliderRangeChangeAction : public ComponentUndoableAction <Slider> | |||
| { | |||
| public: | |||
| SliderRangeChangeAction (Slider* const comp, ComponentLayout& layout, const double newState_[3]) | |||
| : ComponentUndoableAction <Slider> (comp, layout) | |||
| { | |||
| newState [0] = newState_ [0]; | |||
| newState [1] = newState_ [1]; | |||
| newState [2] = newState_ [2]; | |||
| oldState [0] = comp->getMinimum(); | |||
| oldState [1] = comp->getMaximum(); | |||
| oldState [2] = comp->getInterval(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setRange (newState[0], newState[1], newState[2]); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setRange (oldState[0], oldState[1], oldState[2]); | |||
| changed(); | |||
| return true; | |||
| } | |||
| double newState[3], oldState[3]; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class SliderSkewProperty : public ComponentTextProperty <Slider> | |||
| { | |||
| public: | |||
| SliderSkewProperty (Slider* slider, JucerDocument& document) | |||
| : ComponentTextProperty <Slider> ("skew factor", 12, false, slider, document) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| const double skew = jlimit (0.001, 1000.0, newText.getDoubleValue()); | |||
| document.perform (new SliderSkewChangeAction (component, *document.getComponentLayout(), skew), | |||
| "Change Slider skew"); | |||
| } | |||
| String getText() const | |||
| { | |||
| Slider* s = dynamic_cast <Slider*> (component); | |||
| jassert (s != 0); | |||
| return String (s->getSkewFactor()); | |||
| } | |||
| private: | |||
| class SliderSkewChangeAction : public ComponentUndoableAction <Slider> | |||
| { | |||
| public: | |||
| SliderSkewChangeAction (Slider* const comp, ComponentLayout& layout, const double newValue_) | |||
| : ComponentUndoableAction <Slider> (comp, layout) | |||
| { | |||
| newValue = newValue_; | |||
| oldValue = comp->getSkewFactor(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setSkewFactor (newValue); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setSkewFactor (oldValue); | |||
| changed(); | |||
| return true; | |||
| } | |||
| double newValue, oldValue; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| static String sliderStyleToString (Slider::SliderStyle style) | |||
| { | |||
| switch (style) | |||
| { | |||
| case Slider::LinearHorizontal: return "LinearHorizontal"; | |||
| case Slider::LinearVertical: return "LinearVertical"; | |||
| case Slider::LinearBar: return "LinearBar"; | |||
| case Slider::Rotary: return "Rotary"; | |||
| case Slider::RotaryHorizontalDrag: return "RotaryHorizontalDrag"; | |||
| case Slider::RotaryVerticalDrag: return "RotaryVerticalDrag"; | |||
| case Slider::RotaryHorizontalVerticalDrag: return "RotaryHorizontalVerticalDrag"; | |||
| case Slider::IncDecButtons: return "IncDecButtons"; | |||
| case Slider::TwoValueHorizontal: return "TwoValueHorizontal"; | |||
| case Slider::TwoValueVertical: return "TwoValueVertical"; | |||
| case Slider::ThreeValueHorizontal: return "ThreeValueHorizontal"; | |||
| case Slider::ThreeValueVertical: return "ThreeValueVertical"; | |||
| default: jassertfalse; break; | |||
| } | |||
| return String::empty; | |||
| } | |||
| static Slider::SliderStyle sliderStringToStyle (const String& s) | |||
| { | |||
| if (s == "LinearHorizontal") return Slider::LinearHorizontal; | |||
| if (s == "LinearVertical") return Slider::LinearVertical; | |||
| if (s == "LinearBar") return Slider::LinearBar; | |||
| if (s == "Rotary") return Slider::Rotary; | |||
| if (s == "RotaryHorizontalDrag") return Slider::RotaryHorizontalDrag; | |||
| if (s == "RotaryVerticalDrag") return Slider::RotaryVerticalDrag; | |||
| if (s == "RotaryHorizontalVerticalDrag") return Slider::RotaryHorizontalVerticalDrag; | |||
| if (s == "IncDecButtons") return Slider::IncDecButtons; | |||
| if (s.startsWithIgnoreCase ("TwoValueHoriz")) return Slider::TwoValueHorizontal; | |||
| if (s.startsWithIgnoreCase ("TwoValueVert")) return Slider::TwoValueVertical; | |||
| if (s.startsWithIgnoreCase ("ThreeValueHoriz")) return Slider::ThreeValueHorizontal; | |||
| if (s.startsWithIgnoreCase ("ThreeValueVert")) return Slider::ThreeValueVertical; | |||
| jassertfalse; | |||
| return Slider::LinearHorizontal; | |||
| } | |||
| static String textBoxPosToString (const Slider::TextEntryBoxPosition pos) | |||
| { | |||
| switch (pos) | |||
| { | |||
| case Slider::NoTextBox: return "NoTextBox"; | |||
| case Slider::TextBoxLeft: return "TextBoxLeft"; | |||
| case Slider::TextBoxRight: return "TextBoxRight"; | |||
| case Slider::TextBoxAbove: return "TextBoxAbove"; | |||
| case Slider::TextBoxBelow: return "TextBoxBelow"; | |||
| default: jassertfalse; break; | |||
| } | |||
| return String::empty; | |||
| } | |||
| static Slider::TextEntryBoxPosition stringToTextBoxPos (const String& s) | |||
| { | |||
| if (s == "NoTextBox") return Slider::NoTextBox; | |||
| if (s == "TextBoxLeft") return Slider::TextBoxLeft; | |||
| if (s == "TextBoxRight") return Slider::TextBoxRight; | |||
| if (s == "TextBoxAbove") return Slider::TextBoxAbove; | |||
| if (s == "TextBoxBelow") return Slider::TextBoxBelow; | |||
| jassertfalse; | |||
| return Slider::TextBoxLeft; | |||
| } | |||
| }; | |||
| @@ -0,0 +1,84 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class TextButtonHandler : public ButtonHandler | |||
| { | |||
| public: | |||
| TextButtonHandler() | |||
| : ButtonHandler ("Text Button", "TextButton", typeid (TextButton), 150, 24) | |||
| { | |||
| registerColour (TextButton::buttonColourId, "background (normal)", "bgColOff"); | |||
| registerColour (TextButton::buttonOnColourId, "background (on)", "bgColOn"); | |||
| registerColour (TextButton::textColourOnId, "text colour (normal)", "textCol"); | |||
| registerColour (TextButton::textColourOffId, "text colour (on)", "textColOn"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new TextButton ("new button", String::empty); | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ButtonHandler::getEditableProperties (component, document, properties); | |||
| addColourProperties (component, document, properties); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| XmlElement* e = ButtonHandler::createXmlFor (comp, layout); | |||
| //TextButton* tb = (TextButton*) comp; | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ButtonHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| //TextButton* tb = (TextButton*) comp; | |||
| return true; | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ButtonHandler::fillInCreationCode (code, component, memberVariableName); | |||
| //TextButton* const tb = dynamic_cast <TextButton*> (component); | |||
| //TextButton defaultButton (String::empty); | |||
| String s; | |||
| s << getColourIntialisationCode (component, memberVariableName) | |||
| << '\n'; | |||
| code.constructorCode += s; | |||
| } | |||
| }; | |||
| @@ -0,0 +1,426 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class TextEditorHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| TextEditorHandler() | |||
| : ComponentTypeHandler ("Text Editor", "TextEditor", typeid (TextEditor), 150, 24) | |||
| { | |||
| registerColour (TextEditor::textColourId, "text", "textcol"); | |||
| registerColour (TextEditor::backgroundColourId, "background", "bkgcol"); | |||
| registerColour (TextEditor::highlightColourId, "highlight", "hilitecol"); | |||
| registerColour (TextEditor::outlineColourId, "outline", "outlinecol"); | |||
| registerColour (TextEditor::shadowColourId, "shadow", "shadowcol"); | |||
| registerColour (CaretComponent::caretColourId, "caret", "caretcol"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new TextEditor ("new text editor"); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| TextEditor* te = (TextEditor*) comp; | |||
| e->setAttribute ("initialText", comp->getProperties() ["initialText"].toString()); | |||
| e->setAttribute ("multiline", te->isMultiLine()); | |||
| e->setAttribute ("retKeyStartsLine", te->getReturnKeyStartsNewLine()); | |||
| e->setAttribute ("readonly", te->isReadOnly()); | |||
| e->setAttribute ("scrollbars", te->areScrollbarsShown()); | |||
| e->setAttribute ("caret", te->isCaretVisible()); | |||
| e->setAttribute ("popupmenu", te->isPopupMenuEnabled()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| TextEditor* te = (TextEditor*) comp; | |||
| TextEditor defaultEditor; | |||
| te->setMultiLine (xml.getBoolAttribute ("multiline", defaultEditor.isMultiLine())); | |||
| te->setReturnKeyStartsNewLine (xml.getBoolAttribute ("retKeyStartsLine", defaultEditor.getReturnKeyStartsNewLine())); | |||
| te->setReadOnly (xml.getBoolAttribute ("readonly", defaultEditor.isReadOnly())); | |||
| te->setScrollbarsShown (xml.getBoolAttribute ("scrollbars", defaultEditor.areScrollbarsShown())); | |||
| te->setCaretVisible (xml.getBoolAttribute ("caret", defaultEditor.isCaretVisible())); | |||
| te->setPopupMenuEnabled (xml.getBoolAttribute ("popupmenu", defaultEditor.isPopupMenuEnabled())); | |||
| const String initialText (xml.getStringAttribute ("initialText")); | |||
| te->setText (initialText, false); | |||
| te->getProperties().set ("initialText", initialText); | |||
| return true; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| TextEditor* const t = dynamic_cast <TextEditor*> (component); | |||
| jassert (t != nullptr); | |||
| properties.add (new TextEditorInitialTextProperty (t, document)); | |||
| properties.add (new TextEditorMultiLineProperty (t, document)); | |||
| properties.add (new TextEditorReadOnlyProperty (t, document)); | |||
| properties.add (new TextEditorScrollbarsProperty (t, document)); | |||
| properties.add (new TextEditorCaretProperty (t, document)); | |||
| properties.add (new TextEditorPopupMenuProperty (t, document)); | |||
| addColourProperties (t, document, properties); | |||
| } | |||
| String getCreationParameters (Component* component) | |||
| { | |||
| return quotedString (component->getName()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| TextEditor* const te = dynamic_cast <TextEditor*> (component); | |||
| jassert (te != 0); | |||
| String s; | |||
| s << memberVariableName << "->setMultiLine (" << CodeHelpers::boolLiteral (te->isMultiLine()) << ");\n" | |||
| << memberVariableName << "->setReturnKeyStartsNewLine (" << CodeHelpers::boolLiteral (te->getReturnKeyStartsNewLine()) << ");\n" | |||
| << memberVariableName << "->setReadOnly (" << CodeHelpers::boolLiteral (te->isReadOnly()) << ");\n" | |||
| << memberVariableName << "->setScrollbarsShown (" << CodeHelpers::boolLiteral (te->areScrollbarsShown()) << ");\n" | |||
| << memberVariableName << "->setCaretVisible (" << CodeHelpers::boolLiteral (te->isCaretVisible()) << ");\n" | |||
| << memberVariableName << "->setPopupMenuEnabled (" << CodeHelpers::boolLiteral (te->isPopupMenuEnabled()) << ");\n" | |||
| << getColourIntialisationCode (component, memberVariableName) | |||
| << memberVariableName << "->setText (" << quotedString (te->getProperties() ["initialText"].toString()) << ");\n\n"; | |||
| code.constructorCode += s; | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class TextEditorMultiLineProperty : public ComponentChoiceProperty <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorMultiLineProperty (TextEditor* comp, JucerDocument& doc) | |||
| : ComponentChoiceProperty <TextEditor> ("mode", comp, doc) | |||
| { | |||
| choices.add ("single line"); | |||
| choices.add ("multi-line, return key starts new line"); | |||
| choices.add ("multi-line, return key disabled"); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| document.perform (new TextEditorMultilineChangeAction (component, *document.getComponentLayout(), newIndex), | |||
| "Change TextEditor multiline mode"); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| return component->isMultiLine() ? (component->getReturnKeyStartsNewLine() ? 1 : 2) : 0; | |||
| } | |||
| private: | |||
| class TextEditorMultilineChangeAction : public ComponentUndoableAction <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorMultilineChangeAction (TextEditor* const comp, ComponentLayout& layout, const int newState_) | |||
| : ComponentUndoableAction <TextEditor> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isMultiLine() ? (comp->getReturnKeyStartsNewLine() ? 1 : 2) : 0; | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setMultiLine (newState > 0); | |||
| getComponent()->setReturnKeyStartsNewLine (newState == 1); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setMultiLine (oldState > 0); | |||
| getComponent()->setReturnKeyStartsNewLine (oldState == 1); | |||
| changed(); | |||
| return true; | |||
| } | |||
| int newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class TextEditorReadOnlyProperty : public ComponentBooleanProperty <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorReadOnlyProperty (TextEditor* comp, JucerDocument& doc) | |||
| : ComponentBooleanProperty <TextEditor> ("editable", "Editable", "Editable", comp, doc) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new TextEditorReadonlyChangeAction (component, *document.getComponentLayout(), ! newState), | |||
| "Change TextEditor read-only mode"); | |||
| } | |||
| bool getState() const { return ! component->isReadOnly(); } | |||
| private: | |||
| class TextEditorReadonlyChangeAction : public ComponentUndoableAction <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorReadonlyChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <TextEditor> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isReadOnly(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setReadOnly (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setReadOnly (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class TextEditorScrollbarsProperty : public ComponentBooleanProperty <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorScrollbarsProperty (TextEditor* comp, JucerDocument& doc) | |||
| : ComponentBooleanProperty <TextEditor> ("scrollbars", "Scrollbars enabled", "Scrollbars enabled", comp, doc) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new TextEditorScrollbarChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change TextEditor scrollbars"); | |||
| } | |||
| bool getState() const { return component->areScrollbarsShown(); } | |||
| private: | |||
| class TextEditorScrollbarChangeAction : public ComponentUndoableAction <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorScrollbarChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <TextEditor> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->areScrollbarsShown(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setScrollbarsShown (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setScrollbarsShown (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class TextEditorCaretProperty : public ComponentBooleanProperty <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorCaretProperty (TextEditor* comp, JucerDocument& doc) | |||
| : ComponentBooleanProperty <TextEditor> ("caret", "Caret visible", "Caret visible", comp, doc) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new TextEditorCaretChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change TextEditor caret"); | |||
| } | |||
| bool getState() const { return component->isCaretVisible(); } | |||
| private: | |||
| class TextEditorCaretChangeAction : public ComponentUndoableAction <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorCaretChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <TextEditor> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isCaretVisible(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setCaretVisible (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setCaretVisible (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class TextEditorPopupMenuProperty : public ComponentBooleanProperty <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorPopupMenuProperty (TextEditor* comp, JucerDocument& doc) | |||
| : ComponentBooleanProperty <TextEditor> ("popup menu", "Popup menu enabled", "Popup menu enabled", comp, doc) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new TextEditorPopupMenuChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change TextEditor popup menu"); | |||
| } | |||
| bool getState() const { return component->isPopupMenuEnabled(); } | |||
| private: | |||
| class TextEditorPopupMenuChangeAction : public ComponentUndoableAction <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorPopupMenuChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <TextEditor> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isPopupMenuEnabled(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setPopupMenuEnabled (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setPopupMenuEnabled (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class TextEditorInitialTextProperty : public ComponentTextProperty <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorInitialTextProperty (TextEditor* comp, JucerDocument& doc) | |||
| : ComponentTextProperty <TextEditor> ("initial text", 10000, true, comp, doc) | |||
| {} | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new TextEditorInitialTextChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change TextEditor initial text"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return component->getProperties() ["initialText"]; | |||
| } | |||
| private: | |||
| class TextEditorInitialTextChangeAction : public ComponentUndoableAction <TextEditor> | |||
| { | |||
| public: | |||
| TextEditorInitialTextChangeAction (TextEditor* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <TextEditor> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getProperties() ["initialText"]; | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setText (newState, false); | |||
| getComponent()->getProperties().set ("initialText", newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setText (oldState, false); | |||
| getComponent()->getProperties().set ("initialText", oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,138 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class ToggleButtonHandler : public ButtonHandler | |||
| { | |||
| public: | |||
| ToggleButtonHandler() | |||
| : ButtonHandler ("Toggle Button", "ToggleButton", typeid (ToggleButton), 150, 24) | |||
| { | |||
| registerColour (ToggleButton::textColourId, "text colour", "txtcol"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new ToggleButton ("new toggle button"); | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ButtonHandler::getEditableProperties (component, document, properties); | |||
| properties.add (new ToggleButtonStateProperty ((ToggleButton*) component, document)); | |||
| addColourProperties (component, document, properties); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| ToggleButton* tb = (ToggleButton*) comp; | |||
| XmlElement* e = ButtonHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("state", tb->getToggleState()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| ToggleButton* const tb = (ToggleButton*) comp; | |||
| if (! ButtonHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| tb->setToggleState (xml.getBoolAttribute ("state", false), false); | |||
| return true; | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| ButtonHandler::fillInCreationCode (code, component, memberVariableName); | |||
| ToggleButton* const tb = dynamic_cast <ToggleButton*> (component); | |||
| String s; | |||
| if (tb->getToggleState()) | |||
| s << memberVariableName << "->setToggleState (true, false);\n"; | |||
| s << getColourIntialisationCode (component, memberVariableName) | |||
| << '\n'; | |||
| code.constructorCode += s; | |||
| } | |||
| private: | |||
| class ToggleButtonStateProperty : public ComponentBooleanProperty <ToggleButton> | |||
| { | |||
| public: | |||
| ToggleButtonStateProperty (ToggleButton* button_, JucerDocument& doc) | |||
| : ComponentBooleanProperty <ToggleButton> ("initial state", "on", "off", button_, doc) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new ToggleStateChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change ToggleButton state"); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return component->getToggleState(); | |||
| } | |||
| private: | |||
| class ToggleStateChangeAction : public ComponentUndoableAction <ToggleButton> | |||
| { | |||
| public: | |||
| ToggleStateChangeAction (ToggleButton* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <ToggleButton> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getToggleState(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setToggleState (newState, false); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setToggleState (oldState, false); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,257 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class TreeViewHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| TreeViewHandler() | |||
| : ComponentTypeHandler ("TreeView", "TreeView", typeid (DemoTreeView), 150, 150) | |||
| { | |||
| registerColour (TreeView::backgroundColourId, "background", "backgroundColour"); | |||
| registerColour (TreeView::linesColourId, "lines", "linecol"); | |||
| } | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| return new DemoTreeView(); | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| TreeView* const t = dynamic_cast <TreeView*> (comp); | |||
| XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("rootVisible", t->isRootItemVisible()); | |||
| e->setAttribute ("openByDefault", t->areItemsOpenByDefault()); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| TreeView defaultTreeView; | |||
| TreeView* const t = dynamic_cast <TreeView*> (comp); | |||
| t->setRootItemVisible (xml.getBoolAttribute ("rootVisible", defaultTreeView.isRootItemVisible())); | |||
| t->setDefaultOpenness (xml.getBoolAttribute ("openByDefault", defaultTreeView.areItemsOpenByDefault())); | |||
| return true; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| TreeView* const t = dynamic_cast <TreeView*> (component); | |||
| properties.add (new TreeViewRootItemProperty (t, document)); | |||
| properties.add (new TreeViewRootOpennessProperty (t, document)); | |||
| addColourProperties (t, document, properties); | |||
| } | |||
| String getCreationParameters (Component* comp) | |||
| { | |||
| return quotedString (comp->getName()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| TreeView defaultTreeView; | |||
| TreeView* const t = dynamic_cast <TreeView*> (component); | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| if (defaultTreeView.isRootItemVisible() != t->isRootItemVisible()) | |||
| { | |||
| code.constructorCode | |||
| << memberVariableName << "->setRootItemVisible (" | |||
| << CodeHelpers::boolLiteral (t->isRootItemVisible()) << ");\n"; | |||
| } | |||
| if (defaultTreeView.areItemsOpenByDefault() != t->areItemsOpenByDefault()) | |||
| { | |||
| code.constructorCode | |||
| << memberVariableName << "->setDefaultOpenness (" | |||
| << CodeHelpers::boolLiteral (t->areItemsOpenByDefault()) << ");\n"; | |||
| } | |||
| code.constructorCode << getColourIntialisationCode (component, memberVariableName); | |||
| code.constructorCode << "\n"; | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class DemoTreeView : public TreeView | |||
| { | |||
| public: | |||
| DemoTreeView() | |||
| : TreeView ("new treeview") | |||
| { | |||
| setRootItem (new DemoTreeViewItem ("Demo root node", 4)); | |||
| } | |||
| ~DemoTreeView() | |||
| { | |||
| deleteRootItem(); | |||
| } | |||
| private: | |||
| class DemoTreeViewItem : public TreeViewItem | |||
| { | |||
| public: | |||
| DemoTreeViewItem (const String& name_, const int numItems) | |||
| : name (name_) | |||
| { | |||
| for (int i = 0; i < numItems; ++i) | |||
| addSubItem (new DemoTreeViewItem ("Demo sub-node " + String (i), numItems - 1)); | |||
| } | |||
| void paintItem (Graphics& g, int width, int height) | |||
| { | |||
| if (isSelected()) | |||
| g.fillAll (Colours::lightblue); | |||
| g.setColour (Colours::black); | |||
| g.setFont (height * 0.7f); | |||
| g.drawText (name, 4, 0, width - 4, height, Justification::centredLeft, true); | |||
| } | |||
| bool mightContainSubItems() | |||
| { | |||
| return true; | |||
| } | |||
| const String name; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class TreeViewRootItemProperty : public ComponentBooleanProperty <TreeView> | |||
| { | |||
| public: | |||
| TreeViewRootItemProperty (TreeView* comp, JucerDocument& document) | |||
| : ComponentBooleanProperty <TreeView> ("show root item", "Root item visible", "Root item visible", comp, document) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new TreeviewRootChangeAction (component, *document.getComponentLayout(), newState), | |||
| "Change TreeView root item"); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return component->isRootItemVisible(); | |||
| } | |||
| private: | |||
| class TreeviewRootChangeAction : public ComponentUndoableAction <TreeView> | |||
| { | |||
| public: | |||
| TreeviewRootChangeAction (TreeView* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <TreeView> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->isRootItemVisible(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setRootItemVisible (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setRootItemVisible (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class TreeViewRootOpennessProperty : public ComponentChoiceProperty <TreeView> | |||
| { | |||
| public: | |||
| TreeViewRootOpennessProperty (TreeView* comp, JucerDocument& document) | |||
| : ComponentChoiceProperty <TreeView> ("default openness", comp, document) | |||
| { | |||
| choices.add ("Items open by default"); | |||
| choices.add ("Items closed by default"); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| document.perform (new TreeviewOpennessChangeAction (component, *document.getComponentLayout(), newIndex == 0), | |||
| "Change TreeView openness"); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| return component->areItemsOpenByDefault() ? 0 : 1; | |||
| } | |||
| private: | |||
| class TreeviewOpennessChangeAction : public ComponentUndoableAction <TreeView> | |||
| { | |||
| public: | |||
| TreeviewOpennessChangeAction (TreeView* const comp, ComponentLayout& layout, const bool newState_) | |||
| : ComponentUndoableAction <TreeView> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->areItemsOpenByDefault(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setDefaultOpenness (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setDefaultOpenness (oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool newState, oldState; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,660 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| class ViewportHandler : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| ViewportHandler() | |||
| : ComponentTypeHandler ("Viewport", "Viewport", typeid (UpdatingViewport), 150, 150) | |||
| {} | |||
| Component* createNewComponent (JucerDocument*) | |||
| { | |||
| Viewport* const v = new UpdatingViewport ("new viewport"); | |||
| v->setViewedComponent (new ViewportDemoContentComp()); | |||
| return v; | |||
| } | |||
| XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) | |||
| { | |||
| Viewport* const v = dynamic_cast <Viewport*> (comp); | |||
| XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout); | |||
| e->setAttribute ("vscroll", v->isVerticalScrollBarShown()); | |||
| e->setAttribute ("hscroll", v->isHorizontalScrollBarShown()); | |||
| e->setAttribute ("scrollbarThickness", v->getScrollBarThickness()); | |||
| e->setAttribute ("contentType", getViewportContentType (v)); | |||
| e->setAttribute ("jucerFile", getViewportJucerComponentFile (v)); | |||
| e->setAttribute ("contentClass", getViewportGenericComponentClass (v)); | |||
| e->setAttribute ("constructorParams", getViewportConstructorParams (v)); | |||
| return e; | |||
| } | |||
| bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) | |||
| { | |||
| if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) | |||
| return false; | |||
| Viewport defaultViewport; | |||
| Viewport* const v = dynamic_cast <Viewport*> (comp); | |||
| v->setScrollBarsShown (xml.getBoolAttribute ("vscroll", defaultViewport.isVerticalScrollBarShown()), | |||
| xml.getBoolAttribute ("hscroll", defaultViewport.isHorizontalScrollBarShown())); | |||
| v->setScrollBarThickness (xml.getIntAttribute ("scrollbarThickness", defaultViewport.getScrollBarThickness())); | |||
| setViewportJucerComponentFile (v, xml.getStringAttribute ("jucerFile", String::empty)); | |||
| setViewportGenericComponentClass (v, xml.getStringAttribute ("contentClass")); | |||
| setViewportContentType (v, xml.getIntAttribute ("contentType", 0)); | |||
| setViewportConstructorParams (v, xml.getStringAttribute ("constructorParams")); | |||
| return true; | |||
| } | |||
| void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties) | |||
| { | |||
| ComponentTypeHandler::getEditableProperties (component, document, properties); | |||
| Viewport* const v = dynamic_cast <Viewport*> (component); | |||
| properties.add (new ViewportScrollbarShownProperty (v, document, true)); | |||
| properties.add (new ViewportScrollbarShownProperty (v, document, false)); | |||
| properties.add (new ViewportScrollbarSizeProperty (v, document)); | |||
| properties.add (new ViewportContentTypeProperty (v, document)); | |||
| if (getViewportContentType (v) == 1) | |||
| { | |||
| properties.add (new ViewportJucerFileProperty (v, document)); | |||
| properties.add (new ConstructorParamsProperty (v, document)); | |||
| } | |||
| else if (getViewportContentType (v) == 2) | |||
| { | |||
| properties.add (new ViewportContentClassProperty (v, document)); | |||
| properties.add (new ConstructorParamsProperty (v, document)); | |||
| } | |||
| } | |||
| String getCreationParameters (Component* comp) | |||
| { | |||
| return quotedString (comp->getName()); | |||
| } | |||
| void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) | |||
| { | |||
| Viewport defaultViewport; | |||
| Viewport* const v = dynamic_cast <Viewport*> (component); | |||
| ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); | |||
| if (defaultViewport.isVerticalScrollBarShown() != v->isVerticalScrollBarShown() | |||
| || defaultViewport.isHorizontalScrollBarShown() != v->isHorizontalScrollBarShown()) | |||
| { | |||
| code.constructorCode | |||
| << memberVariableName << "->setScrollBarsShown (" | |||
| << CodeHelpers::boolLiteral (v->isVerticalScrollBarShown()) << ", " | |||
| << CodeHelpers::boolLiteral (v->isHorizontalScrollBarShown()) << ");\n"; | |||
| } | |||
| if (defaultViewport.getScrollBarThickness() != v->getScrollBarThickness()) | |||
| { | |||
| code.constructorCode | |||
| << memberVariableName << "->setScrollBarThickness (" | |||
| << v->getScrollBarThickness() << ");\n"; | |||
| } | |||
| if (getViewportContentType (v) != 0) | |||
| { | |||
| String className (getViewportGenericComponentClass (v)); | |||
| if (getViewportContentType (v) == 1) | |||
| { | |||
| File file; | |||
| const String filename (getViewportJucerComponentFile (v)); | |||
| if (filename.isNotEmpty()) | |||
| file = code.document->getCppFile().getSiblingFile (filename); | |||
| ScopedPointer<JucerDocument> doc (JucerDocument::createForCppFile (nullptr, file)); | |||
| if (doc != nullptr) | |||
| { | |||
| code.includeFilesCPP.add (doc->getHeaderFile() | |||
| .getRelativePathFrom (code.document->getCppFile().getParentDirectory()) | |||
| .replaceCharacter ('\\', '/')); | |||
| className = doc->getClassName(); | |||
| } | |||
| else | |||
| { | |||
| className = String::empty; | |||
| } | |||
| } | |||
| if (className.isNotEmpty()) | |||
| { | |||
| code.constructorCode | |||
| << memberVariableName << "->setViewedComponent (new " | |||
| << className; | |||
| if (getViewportConstructorParams (v).trim().isNotEmpty()) | |||
| { | |||
| code.constructorCode << " (" << getViewportConstructorParams (v).trim() << "));\n"; | |||
| } | |||
| else | |||
| { | |||
| code.constructorCode << "());\n"; | |||
| } | |||
| } | |||
| } | |||
| code.constructorCode << "\n"; | |||
| } | |||
| static void updateViewportContentComp (Viewport* vp) | |||
| { | |||
| if (getViewportContentType (vp) == 1) | |||
| { | |||
| JucerDocument* doc = findParentDocument (vp); | |||
| TestComponent* tc = new TestComponent (doc, 0, false); | |||
| tc->setFilename (getViewportJucerComponentFile (vp)); | |||
| tc->setToInitialSize(); | |||
| vp->setViewedComponent (tc); | |||
| } | |||
| else | |||
| { | |||
| vp->setViewedComponent (new ViewportDemoContentComp()); | |||
| } | |||
| } | |||
| static int getViewportContentType (Viewport* vp) | |||
| { | |||
| return vp->getProperties() ["contentType"]; | |||
| } | |||
| static void setViewportContentType (Viewport* vp, int newValue) | |||
| { | |||
| if (newValue != getViewportContentType (vp)) | |||
| { | |||
| vp->getProperties().set ("contentType", newValue); | |||
| updateViewportContentComp (vp); | |||
| } | |||
| } | |||
| static String getViewportJucerComponentFile (Viewport* vp) | |||
| { | |||
| return vp->getProperties() ["jucerFile"].toString(); | |||
| } | |||
| static void setViewportJucerComponentFile (Viewport* vp, const String& file) | |||
| { | |||
| if (file != getViewportJucerComponentFile (vp)) | |||
| { | |||
| vp->getProperties().set ("jucerFile", file); | |||
| updateViewportContentComp (vp); | |||
| } | |||
| } | |||
| static String getViewportGenericComponentClass (Viewport* vp) | |||
| { | |||
| return vp->getProperties() ["contentClass"].toString(); | |||
| } | |||
| static void setViewportGenericComponentClass (Viewport* vp, const String& className) | |||
| { | |||
| if (className != getViewportGenericComponentClass (vp)) | |||
| { | |||
| vp->getProperties().set ("contentClass", className); | |||
| updateViewportContentComp (vp); | |||
| } | |||
| } | |||
| static String getViewportConstructorParams (Viewport* vp) | |||
| { | |||
| return vp->getProperties() ["constructorParams"].toString(); | |||
| } | |||
| static void setViewportConstructorParams (Viewport* vp, const String& newParams) | |||
| { | |||
| if (newParams != getViewportConstructorParams (vp)) | |||
| { | |||
| vp->getProperties().set ("constructorParams", newParams); | |||
| updateViewportContentComp (vp); | |||
| } | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class UpdatingViewport : public Viewport | |||
| { | |||
| public: | |||
| UpdatingViewport (const String& name) | |||
| : Viewport (name) | |||
| { | |||
| } | |||
| void parentHierarchyChanged() | |||
| { | |||
| Viewport::parentHierarchyChanged(); | |||
| updateViewportContentComp (this); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| class ViewportDemoContentComp : public Component | |||
| { | |||
| public: | |||
| ViewportDemoContentComp() | |||
| { | |||
| setSize (2048, 2048); | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.fillCheckerBoard (getLocalBounds(), 50, 50, | |||
| Colours::lightgrey.withAlpha (0.5f), | |||
| Colours::darkgrey.withAlpha (0.5f)); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| class ViewportScrollbarShownProperty : public ComponentBooleanProperty <Viewport> | |||
| { | |||
| public: | |||
| ViewportScrollbarShownProperty (Viewport* comp, JucerDocument& document, const bool vertical_) | |||
| : ComponentBooleanProperty <Viewport> (vertical_ ? "V scrollbar" : "H scrollbar", | |||
| "enabled", "enabled", | |||
| comp, document), | |||
| vertical (vertical_) | |||
| { | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.perform (new ViewportScrollbarChangeAction (component, *document.getComponentLayout(), vertical, newState), | |||
| "Change Viewport scrollbar"); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return vertical ? component->isVerticalScrollBarShown() | |||
| : component->isHorizontalScrollBarShown(); | |||
| } | |||
| const bool vertical; | |||
| private: | |||
| class ViewportScrollbarChangeAction : public ComponentUndoableAction <Viewport> | |||
| { | |||
| public: | |||
| ViewportScrollbarChangeAction (Viewport* const comp, ComponentLayout& layout, const bool vertical_, const bool newState_) | |||
| : ComponentUndoableAction <Viewport> (comp, layout), | |||
| vertical (vertical_), | |||
| newState (newState_) | |||
| { | |||
| oldState = vertical ? comp->isVerticalScrollBarShown() | |||
| : comp->isHorizontalScrollBarShown(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| if (vertical) | |||
| getComponent()->setScrollBarsShown (newState, getComponent()->isHorizontalScrollBarShown()); | |||
| else | |||
| getComponent()->setScrollBarsShown (getComponent()->isVerticalScrollBarShown(), newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| if (vertical) | |||
| getComponent()->setScrollBarsShown (oldState, getComponent()->isHorizontalScrollBarShown()); | |||
| else | |||
| getComponent()->setScrollBarsShown (getComponent()->isVerticalScrollBarShown(), oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool vertical, newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ViewportScrollbarSizeProperty : public SliderPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| ViewportScrollbarSizeProperty (Viewport* comp, JucerDocument& doc) | |||
| : SliderPropertyComponent ("scrollbar size", 3.0, 30.0, 1.0, 1.0), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ViewportScrollbarSizeProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| document.getUndoManager().undoCurrentTransactionOnly(); | |||
| document.perform (new ViewportScrollbarSizeChangeAction (component, *document.getComponentLayout(), roundToInt (newValue)), | |||
| "Change Viewport scrollbar size"); | |||
| } | |||
| double getValue() const | |||
| { | |||
| return component->getScrollBarThickness(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| Viewport* component; | |||
| JucerDocument& document; | |||
| private: | |||
| class ViewportScrollbarSizeChangeAction : public ComponentUndoableAction <Viewport> | |||
| { | |||
| public: | |||
| ViewportScrollbarSizeChangeAction (Viewport* const comp, ComponentLayout& layout, const int newState_) | |||
| : ComponentUndoableAction <Viewport> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = comp->getScrollBarThickness(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setScrollBarThickness (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getComponent()->setScrollBarThickness (newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| int newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ViewportContentTypeProperty : public ComponentChoiceProperty <Viewport> | |||
| { | |||
| public: | |||
| ViewportContentTypeProperty (Viewport* comp, JucerDocument& document) | |||
| : ComponentChoiceProperty <Viewport> ("content", comp, document) | |||
| { | |||
| choices.add ("No content component"); | |||
| choices.add ("Jucer content component"); | |||
| choices.add ("Named content component"); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| document.perform (new ViewportContentTypeChangeAction (component, *document.getComponentLayout(), newIndex), | |||
| "Change Viewport content type"); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| return getViewportContentType (component); | |||
| } | |||
| private: | |||
| class ViewportContentTypeChangeAction : public ComponentUndoableAction <Viewport> | |||
| { | |||
| public: | |||
| ViewportContentTypeChangeAction (Viewport* const comp, ComponentLayout& layout, const int newValue_) | |||
| : ComponentUndoableAction <Viewport> (comp, layout), | |||
| newValue (newValue_) | |||
| { | |||
| oldValue = getViewportContentType (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportContentType (getComponent(), newValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportContentType (getComponent(), oldValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| int newValue, oldValue; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ViewportJucerFileProperty : public FilePropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| ViewportJucerFileProperty (Viewport* const comp, JucerDocument& doc) | |||
| : FilePropertyComponent ("Jucer file", false, true), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ViewportJucerFileProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setFile (const File& newFile) | |||
| { | |||
| document.perform (new JucerCompFileChangeAction (component, *document.getComponentLayout(), | |||
| newFile.getRelativePathFrom (document.getCppFile().getParentDirectory()) | |||
| .replaceCharacter ('\\', '/')), | |||
| "Change Jucer component file"); | |||
| } | |||
| File getFile() const | |||
| { | |||
| const String filename (getViewportJucerComponentFile (component)); | |||
| if (filename.isEmpty()) | |||
| return File::nonexistent; | |||
| return document.getCppFile().getSiblingFile (filename); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| Viewport* const component; | |||
| JucerDocument& document; | |||
| class JucerCompFileChangeAction : public ComponentUndoableAction <Viewport> | |||
| { | |||
| public: | |||
| JucerCompFileChangeAction (Viewport* const comp, ComponentLayout& layout, const String& newState_) | |||
| : ComponentUndoableAction <Viewport> (comp, layout), | |||
| newState (newState_) | |||
| { | |||
| oldState = getViewportJucerComponentFile (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportJucerComponentFile (getComponent(), newState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportJucerComponentFile (getComponent(), oldState); | |||
| changed(); | |||
| return true; | |||
| } | |||
| String newState, oldState; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ViewportContentClassProperty : public ComponentTextProperty <Viewport> | |||
| { | |||
| public: | |||
| ViewportContentClassProperty (Viewport* comp, JucerDocument& document) | |||
| : ComponentTextProperty <Viewport> ("content class", 256, false, comp, document) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ViewportClassNameChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change Viewport content class"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return getViewportGenericComponentClass (component); | |||
| } | |||
| private: | |||
| class ViewportClassNameChangeAction : public ComponentUndoableAction <Viewport> | |||
| { | |||
| public: | |||
| ViewportClassNameChangeAction (Viewport* const comp, ComponentLayout& layout, const String& newValue_) | |||
| : ComponentUndoableAction <Viewport> (comp, layout), | |||
| newValue (newValue_) | |||
| { | |||
| oldValue = getViewportGenericComponentClass (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportGenericComponentClass (getComponent(), newValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportGenericComponentClass (getComponent(), oldValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| String newValue, oldValue; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| class ConstructorParamsProperty : public ComponentTextProperty <Viewport> | |||
| { | |||
| public: | |||
| ConstructorParamsProperty (Viewport* comp, JucerDocument& document) | |||
| : ComponentTextProperty <Viewport> ("constructor params", 512, false, comp, document) | |||
| { | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| document.perform (new ConstructorParamChangeAction (component, *document.getComponentLayout(), newText), | |||
| "Change Viewport content constructor params"); | |||
| } | |||
| String getText() const | |||
| { | |||
| return getViewportConstructorParams (component); | |||
| } | |||
| private: | |||
| class ConstructorParamChangeAction : public ComponentUndoableAction <Viewport> | |||
| { | |||
| public: | |||
| ConstructorParamChangeAction (Viewport* const comp, ComponentLayout& layout, const String& newValue_) | |||
| : ComponentUndoableAction <Viewport> (comp, layout), | |||
| newValue (newValue_) | |||
| { | |||
| oldValue = getViewportConstructorParams (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportConstructorParams (getComponent(), newValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| setViewportConstructorParams (getComponent(), oldValue); | |||
| changed(); | |||
| layout.getDocument()->refreshAllPropertyComps(); | |||
| return true; | |||
| } | |||
| String newValue, oldValue; | |||
| }; | |||
| }; | |||
| }; | |||
| @@ -0,0 +1,414 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_ButtonDocument.h" | |||
| #include "../jucer_UtilityFunctions.h" | |||
| //============================================================================== | |||
| static const int normalOff = 0; | |||
| static const int overOff = 1; | |||
| static const int downOff = 2; | |||
| static const int normalOn = 3; | |||
| static const int overOn = 4; | |||
| static const int downOn = 5; | |||
| static const int background = 6; | |||
| //============================================================================== | |||
| ButtonDocument::ButtonDocument (SourceCodeDocument* c) | |||
| : JucerDocument (c) | |||
| { | |||
| paintStatesEnabled [normalOff] = true; | |||
| paintStatesEnabled [overOff] = true; | |||
| paintStatesEnabled [downOff] = true; | |||
| paintStatesEnabled [normalOn] = false; | |||
| paintStatesEnabled [overOn] = false; | |||
| paintStatesEnabled [downOn] = false; | |||
| paintStatesEnabled [background] = false; | |||
| parentClasses = "public Button"; | |||
| for (int i = 7; --i >= 0;) | |||
| { | |||
| paintRoutines[i] = new PaintRoutine(); | |||
| paintRoutines[i]->setDocument (this); | |||
| paintRoutines[i]->setBackgroundColour (Colours::transparentBlack); | |||
| } | |||
| } | |||
| ButtonDocument::~ButtonDocument() | |||
| { | |||
| } | |||
| static const char* const stateNames[] = | |||
| { | |||
| "normal", "over", "down", | |||
| "normal on", "over on", "down on", | |||
| "common background" | |||
| }; | |||
| int stateNameToIndex (const String& name) | |||
| { | |||
| for (int i = 7; --i >= 0;) | |||
| if (name.equalsIgnoreCase (stateNames[i])) | |||
| return i; | |||
| jassertfalse; | |||
| return normalOff; | |||
| } | |||
| int ButtonDocument::getNumPaintRoutines() const | |||
| { | |||
| int n = 0; | |||
| for (int i = 7; --i >= 0;) | |||
| if (paintStatesEnabled [i]) | |||
| ++n; | |||
| return n; | |||
| } | |||
| StringArray ButtonDocument::getPaintRoutineNames() const | |||
| { | |||
| StringArray s; | |||
| for (int i = 0; i < 7; ++i) | |||
| if (paintStatesEnabled [i]) | |||
| s.add (stateNames [i]); | |||
| return s; | |||
| } | |||
| PaintRoutine* ButtonDocument::getPaintRoutine (const int index) const | |||
| { | |||
| int n = 0; | |||
| for (int i = 0; i < 7; ++i) | |||
| { | |||
| if (paintStatesEnabled [i]) | |||
| { | |||
| if (index == n) | |||
| return paintRoutines [i]; | |||
| else | |||
| ++n; | |||
| } | |||
| } | |||
| jassertfalse; | |||
| return 0; | |||
| } | |||
| void ButtonDocument::setStatePaintRoutineEnabled (const int index, bool b) | |||
| { | |||
| jassert (index > 0 && index < 7); | |||
| if (paintStatesEnabled [index] != b) | |||
| { | |||
| paintStatesEnabled [index] = b; | |||
| changed(); | |||
| } | |||
| } | |||
| bool ButtonDocument::isStatePaintRoutineEnabled (const int index) const | |||
| { | |||
| return paintStatesEnabled [index]; | |||
| } | |||
| int ButtonDocument::chooseBestEnabledPaintRoutine (int paintRoutineWanted) const | |||
| { | |||
| switch (paintRoutineWanted) | |||
| { | |||
| case normalOff: return normalOff; | |||
| case overOff: return paintStatesEnabled [overOff] ? overOff : normalOff; | |||
| case downOff: return paintStatesEnabled [downOff] ? downOff : chooseBestEnabledPaintRoutine (overOff); | |||
| case normalOn: return paintStatesEnabled [normalOn] ? normalOn : normalOff; | |||
| case overOn: return paintStatesEnabled [overOn] ? overOn : (paintStatesEnabled [normalOn] ? normalOn : chooseBestEnabledPaintRoutine (overOff)); | |||
| case downOn: return paintStatesEnabled [downOn] ? downOn : ((paintStatesEnabled [overOn] || paintStatesEnabled [normalOn]) | |||
| ? chooseBestEnabledPaintRoutine (overOn) | |||
| : chooseBestEnabledPaintRoutine (downOff)); | |||
| default: jassertfalse; break; | |||
| } | |||
| return normalOff; | |||
| } | |||
| //============================================================================== | |||
| String ButtonDocument::getTypeName() const | |||
| { | |||
| return "Button"; | |||
| } | |||
| JucerDocument* ButtonDocument::createCopy() | |||
| { | |||
| ButtonDocument* newOne = new ButtonDocument (cpp); | |||
| newOne->resources = resources; | |||
| ScopedPointer<XmlElement> xml (createXml()); | |||
| newOne->loadFromXml (*xml); | |||
| return newOne; | |||
| } | |||
| XmlElement* ButtonDocument::createXml() const | |||
| { | |||
| XmlElement* const doc = JucerDocument::createXml(); | |||
| for (int i = 0; i < 7; ++i) | |||
| { | |||
| XmlElement* e = paintRoutines [i]->createXml(); | |||
| e->setAttribute ("buttonState", stateNames [i]); | |||
| e->setAttribute ("enabled", paintStatesEnabled [i]); | |||
| doc->addChildElement (e); | |||
| } | |||
| return doc; | |||
| } | |||
| bool ButtonDocument::loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (JucerDocument::loadFromXml (xml)) | |||
| { | |||
| for (int i = 7; --i >= 0;) | |||
| paintStatesEnabled [i] = false; | |||
| forEachXmlChildElementWithTagName (xml, e, PaintRoutine::xmlTagName) | |||
| { | |||
| const int stateIndex = stateNameToIndex (e->getStringAttribute ("buttonState")); | |||
| paintRoutines [stateIndex]->loadFromXml (*e); | |||
| paintStatesEnabled [stateIndex] = e->getBoolAttribute ("enabled", stateIndex < normalOn); | |||
| } | |||
| changed(); | |||
| getUndoManager().clearUndoHistory(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| void ButtonDocument::getOptionalMethods (StringArray& baseClasses, | |||
| StringArray& returnValues, | |||
| StringArray& methods, | |||
| StringArray& initialContents) const | |||
| { | |||
| JucerDocument::getOptionalMethods (baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Button", "void", "clicked()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Button", "void", "buttonStateChanged()", "", baseClasses, returnValues, methods, initialContents); | |||
| } | |||
| //============================================================================== | |||
| class ButtonStatePaintEnabledProperty : public BooleanPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ButtonStatePaintEnabledProperty (const String& name, ButtonDocument& doc, const int stateMethod_) | |||
| : BooleanPropertyComponent (name, "enabled", "disabled"), | |||
| document (doc), | |||
| stateMethod (stateMethod_) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ButtonStatePaintEnabledProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void setState (bool newState) | |||
| { | |||
| document.setStatePaintRoutineEnabled (stateMethod, newState); | |||
| } | |||
| bool getState() const | |||
| { | |||
| return document.isStatePaintRoutineEnabled (stateMethod); | |||
| } | |||
| private: | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| ButtonDocument& document; | |||
| const int stateMethod; | |||
| }; | |||
| void ButtonDocument::addExtraClassProperties (PropertyPanel& panel) | |||
| { | |||
| Array <PropertyComponent*> props; | |||
| for (int i = 1; i < 7; ++i) | |||
| props.add (new ButtonStatePaintEnabledProperty (stateNames[i], *this, i)); | |||
| panel.addSection ("Button paint routines", props); | |||
| } | |||
| //============================================================================== | |||
| class ButtonTestComponent : public Button | |||
| { | |||
| public: | |||
| ButtonTestComponent (ButtonDocument* const doc, const bool fillBackground) | |||
| : Button (String::empty), | |||
| document (doc), | |||
| alwaysFillBackground (fillBackground) | |||
| { | |||
| setClickingTogglesState (true); | |||
| } | |||
| void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) | |||
| { | |||
| if (document->paintStatesEnabled [background]) | |||
| { | |||
| document->paintRoutines [background]->fillWithBackground (g, alwaysFillBackground); | |||
| document->paintRoutines [background]->drawElements (g, getLocalBounds()); | |||
| } | |||
| const int stateIndex | |||
| = getToggleState() | |||
| ? (isButtonDown ? document->chooseBestEnabledPaintRoutine (downOn) | |||
| : (isMouseOverButton ? document->chooseBestEnabledPaintRoutine (overOn) | |||
| : document->chooseBestEnabledPaintRoutine (normalOn))) | |||
| : (isButtonDown ? document->chooseBestEnabledPaintRoutine (downOff) | |||
| : (isMouseOverButton ? document->chooseBestEnabledPaintRoutine (overOff) | |||
| : normalOff)); | |||
| document->paintRoutines [stateIndex]->fillWithBackground (g, ! document->paintStatesEnabled [background]); | |||
| document->paintRoutines [stateIndex]->drawElements (g, getLocalBounds()); | |||
| } | |||
| private: | |||
| ButtonDocument* const document; | |||
| const bool alwaysFillBackground; | |||
| }; | |||
| Component* ButtonDocument::createTestComponent (const bool alwaysFillBackground) | |||
| { | |||
| return new ButtonTestComponent (this, alwaysFillBackground); | |||
| } | |||
| //============================================================================== | |||
| void ButtonDocument::fillInGeneratedCode (GeneratedCode& code) const | |||
| { | |||
| JucerDocument::fillInGeneratedCode (code); | |||
| code.parentClassInitialiser = "Button (" + quotedString (code.componentName) + ")"; | |||
| code.removeCallback ("void", "paint (Graphics& g)"); | |||
| } | |||
| void ButtonDocument::fillInPaintCode (GeneratedCode& code) const | |||
| { | |||
| jassert (paintStatesEnabled [normalOff]); | |||
| String paintCode [7]; | |||
| for (int i = 0; i < 7; ++i) | |||
| if (paintStatesEnabled [i]) | |||
| paintRoutines[i]->fillInGeneratedCode (code, paintCode [i]); | |||
| String& s = code.getCallbackCode ("public Button", | |||
| "void", | |||
| "paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)", | |||
| false); | |||
| int numPaintRoutines = getNumPaintRoutines(); | |||
| if (paintStatesEnabled [background]) | |||
| { | |||
| s << paintCode [background] << "\n"; | |||
| --numPaintRoutines; | |||
| } | |||
| if (numPaintRoutines == 1) | |||
| { | |||
| s << paintCode [normalOff]; | |||
| } | |||
| else if (numPaintRoutines == downOff && (paintStatesEnabled [overOff] || paintStatesEnabled [downOff] || paintStatesEnabled [normalOn])) | |||
| { | |||
| if (paintStatesEnabled [normalOn]) | |||
| { | |||
| s << "if (getToggleState())\n{\n " | |||
| << CodeHelpers::indent (paintCode [normalOn], 4, false).trimEnd(); | |||
| } | |||
| else if (paintStatesEnabled [overOff]) | |||
| { | |||
| s << "if (isButtonDown || isMouseOverButton)\n{\n " | |||
| << CodeHelpers::indent (paintCode [overOff], 4, false).trimEnd(); | |||
| } | |||
| else | |||
| { | |||
| s << "if (isButtonDown)\n{\n " | |||
| << CodeHelpers::indent (paintCode [downOff], 4, false).trimEnd(); | |||
| } | |||
| s << "\n}\nelse\n{\n " | |||
| << CodeHelpers::indent (paintCode [normalOff], 4, false).trimEnd() | |||
| << "\n}\n"; | |||
| } | |||
| else if (numPaintRoutines == normalOn && paintStatesEnabled [overOff] && paintStatesEnabled [downOff]) | |||
| { | |||
| s << "if (isButtonDown)\n{\n " | |||
| << CodeHelpers::indent (paintCode [downOff], 4, false).trimEnd() | |||
| << "\n}\nelse if (isMouseOverButton)\n{\n " | |||
| << CodeHelpers::indent (paintCode [overOff], 4, false).trimEnd() | |||
| << "\n}\nelse\n{\n " | |||
| << CodeHelpers::indent (paintCode [normalOff], 4, false).trimEnd() | |||
| << "\n}\n"; | |||
| } | |||
| else | |||
| { | |||
| if (paintStatesEnabled [normalOn] || paintStatesEnabled [overOn] || paintStatesEnabled [downOn]) | |||
| { | |||
| s << "switch (getToggleState() ? (isButtonDown ? " | |||
| << chooseBestEnabledPaintRoutine (downOn) << " : (isMouseOverButton ? " | |||
| << chooseBestEnabledPaintRoutine (overOn) << " : " | |||
| << chooseBestEnabledPaintRoutine (normalOn) << "))\n : (isButtonDown ? " | |||
| << chooseBestEnabledPaintRoutine (downOff) << " : (isMouseOverButton ? " | |||
| << chooseBestEnabledPaintRoutine (overOff) << " : 0)))\n{\n"; | |||
| } | |||
| else | |||
| { | |||
| s << "switch (isButtonDown ? " << chooseBestEnabledPaintRoutine (downOff) | |||
| << " : (isMouseOverButton ? " << chooseBestEnabledPaintRoutine (overOff) | |||
| << " : 0))\n{\n"; | |||
| } | |||
| for (int i = 0; i < 6; ++i) | |||
| { | |||
| if (paintStatesEnabled [i]) | |||
| { | |||
| s << "case " << i << ":\n {\n " | |||
| << CodeHelpers::indent (paintCode [i], 8, false).trimEnd() | |||
| << "\n break;\n }\n\n"; | |||
| } | |||
| } | |||
| s << "default:\n break;\n}\n"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,76 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_BUTTONDOCUMENT_JUCEHEADER__ | |||
| #define __JUCER_BUTTONDOCUMENT_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| //============================================================================== | |||
| class ButtonDocument : public JucerDocument | |||
| { | |||
| public: | |||
| ButtonDocument (SourceCodeDocument* cpp); | |||
| ~ButtonDocument(); | |||
| //============================================================================== | |||
| String getTypeName() const; | |||
| JucerDocument* createCopy(); | |||
| Component* createTestComponent (const bool alwaysFillBackground); | |||
| int getNumPaintRoutines() const; | |||
| StringArray getPaintRoutineNames() const; | |||
| PaintRoutine* getPaintRoutine (const int index) const; | |||
| void setStatePaintRoutineEnabled (const int index, bool b); | |||
| bool isStatePaintRoutineEnabled (const int index) const; | |||
| int chooseBestEnabledPaintRoutine (int paintRoutineWanted) const; | |||
| ComponentLayout* getComponentLayout() const { return 0; } | |||
| void addExtraClassProperties (PropertyPanel&); | |||
| //============================================================================== | |||
| XmlElement* createXml() const; | |||
| bool loadFromXml (const XmlElement& xml); | |||
| void fillInGeneratedCode (GeneratedCode& code) const; | |||
| void fillInPaintCode (GeneratedCode& code) const; | |||
| void getOptionalMethods (StringArray& baseClasses, | |||
| StringArray& returnValues, | |||
| StringArray& methods, | |||
| StringArray& initialContents) const; | |||
| //============================================================================== | |||
| ScopedPointer<PaintRoutine> paintRoutines[7]; | |||
| bool paintStatesEnabled [7]; | |||
| }; | |||
| #endif // __JUCER_BUTTONDOCUMENT_JUCEHEADER__ | |||
| @@ -0,0 +1,167 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| ComponentDocument::ComponentDocument (SourceCodeDocument* c) | |||
| : JucerDocument (c) | |||
| { | |||
| components = new ComponentLayout(); | |||
| components->setDocument (this); | |||
| backgroundGraphics = new PaintRoutine(); | |||
| backgroundGraphics->setDocument (this); | |||
| } | |||
| ComponentDocument::~ComponentDocument() | |||
| { | |||
| } | |||
| //============================================================================== | |||
| String ComponentDocument::getTypeName() const | |||
| { | |||
| return "Component"; | |||
| } | |||
| JucerDocument* ComponentDocument::createCopy() | |||
| { | |||
| ComponentDocument* newOne = new ComponentDocument (cpp); | |||
| newOne->resources = resources; | |||
| ScopedPointer<XmlElement> xml (createXml()); | |||
| newOne->loadFromXml (*xml); | |||
| return newOne; | |||
| } | |||
| XmlElement* ComponentDocument::createXml() const | |||
| { | |||
| XmlElement* const doc = JucerDocument::createXml(); | |||
| doc->addChildElement (backgroundGraphics->createXml()); | |||
| components->addToXml (*doc); | |||
| return doc; | |||
| } | |||
| bool ComponentDocument::loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (JucerDocument::loadFromXml (xml)) | |||
| { | |||
| components->clearComponents(); | |||
| forEachXmlChildElement (xml, e) | |||
| { | |||
| if (e->hasTagName (PaintRoutine::xmlTagName)) | |||
| backgroundGraphics->loadFromXml (*e); | |||
| else | |||
| components->addComponentFromXml (*e, false); | |||
| } | |||
| changed(); | |||
| getUndoManager().clearUndoHistory(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| class NormalTestComponent : public Component | |||
| { | |||
| public: | |||
| NormalTestComponent (ComponentDocument* const doc, const bool fillBackground) | |||
| : document (doc), | |||
| alwaysFillBackground (fillBackground) | |||
| { | |||
| ComponentLayout* const layout = document->getComponentLayout(); | |||
| for (int i = 0; i < layout->getNumComponents(); ++i) | |||
| addAndMakeVisible (layout->getComponent (i)); | |||
| } | |||
| ~NormalTestComponent() | |||
| { | |||
| for (int i = getNumChildComponents(); --i >= 0;) | |||
| removeChildComponent (i); | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| document->getPaintRoutine (0)->fillWithBackground (g, alwaysFillBackground); | |||
| document->getPaintRoutine (0)->drawElements (g, getLocalBounds()); | |||
| } | |||
| void resized() | |||
| { | |||
| if (! getBounds().isEmpty()) | |||
| { | |||
| int numTimesToTry = 10; | |||
| while (--numTimesToTry >= 0) | |||
| { | |||
| bool anyCompsMoved = false; | |||
| for (int i = 0; i < getNumChildComponents(); ++i) | |||
| { | |||
| Component* comp = getChildComponent (i); | |||
| if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp)) | |||
| { | |||
| const Rectangle<int> newBounds (type->getComponentPosition (comp) | |||
| .getRectangle (getLocalBounds(), | |||
| document->getComponentLayout())); | |||
| anyCompsMoved = anyCompsMoved || (comp->getBounds() != newBounds); | |||
| comp->setBounds (newBounds); | |||
| } | |||
| } | |||
| // repeat this loop until they've all stopped shuffling (might require a few | |||
| // loops for all the relative positioned comps to settle down) | |||
| if (! anyCompsMoved) | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| private: | |||
| ComponentDocument* const document; | |||
| const bool alwaysFillBackground; | |||
| }; | |||
| Component* ComponentDocument::createTestComponent (const bool alwaysFillBackground) | |||
| { | |||
| return new NormalTestComponent (this, alwaysFillBackground); | |||
| } | |||
| void ComponentDocument::fillInGeneratedCode (GeneratedCode& code) const | |||
| { | |||
| JucerDocument::fillInGeneratedCode (code); | |||
| } | |||
| @@ -0,0 +1,63 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTDOCUMENT_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTDOCUMENT_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| //============================================================================== | |||
| class ComponentDocument : public JucerDocument | |||
| { | |||
| public: | |||
| ComponentDocument (SourceCodeDocument* cpp); | |||
| ~ComponentDocument(); | |||
| //============================================================================== | |||
| String getTypeName() const; | |||
| JucerDocument* createCopy(); | |||
| Component* createTestComponent (const bool alwaysFillBackground); | |||
| int getNumPaintRoutines() const { return 1; } | |||
| StringArray getPaintRoutineNames() const { return StringArray ("Graphics"); } | |||
| PaintRoutine* getPaintRoutine (const int index) const { return index == 0 ? backgroundGraphics.get() : nullptr; } | |||
| ComponentLayout* getComponentLayout() const { return components; } | |||
| //============================================================================== | |||
| XmlElement* createXml() const; | |||
| bool loadFromXml (const XmlElement& xml); | |||
| void fillInGeneratedCode (GeneratedCode& code) const; | |||
| private: | |||
| ScopedPointer<ComponentLayout> components; | |||
| ScopedPointer<PaintRoutine> backgroundGraphics; | |||
| }; | |||
| #endif // __JUCER_COMPONENTDOCUMENT_JUCEHEADER__ | |||
| @@ -0,0 +1,356 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../jucer_Headers.h" | |||
| #include "jucer_JucerDocument.h" | |||
| //============================================================================== | |||
| BinaryResources::BinaryResources() | |||
| { | |||
| } | |||
| BinaryResources::~BinaryResources() | |||
| { | |||
| } | |||
| BinaryResources& BinaryResources::operator= (const BinaryResources& other) | |||
| { | |||
| for (int i = 0; i < other.resources.size(); ++i) | |||
| add (other.resources[i]->name, | |||
| other.resources[i]->originalFilename, | |||
| other.resources[i]->data); | |||
| return *this; | |||
| } | |||
| void BinaryResources::changed() | |||
| { | |||
| if (document != nullptr) | |||
| { | |||
| document->changed(); | |||
| document->refreshAllPropertyComps(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void BinaryResources::clear() | |||
| { | |||
| if (resources.size() > 0) | |||
| { | |||
| resources.clear(); | |||
| changed(); | |||
| } | |||
| } | |||
| StringArray BinaryResources::getResourceNames() const | |||
| { | |||
| StringArray s; | |||
| for (int i = 0; i < resources.size(); ++i) | |||
| s.add (resources.getUnchecked(i)->name); | |||
| return s; | |||
| } | |||
| BinaryResources::BinaryResource* BinaryResources::findResource (const String& name) const noexcept | |||
| { | |||
| for (int i = resources.size(); --i >= 0;) | |||
| if (resources.getUnchecked(i)->name == name) | |||
| return resources.getUnchecked(i); | |||
| return 0; | |||
| } | |||
| const BinaryResources::BinaryResource* BinaryResources::getResource (const String& name) const | |||
| { | |||
| return findResource (name); | |||
| } | |||
| const BinaryResources::BinaryResource* BinaryResources::getResourceForFile (const File& file) const | |||
| { | |||
| for (int i = resources.size(); --i >= 0;) | |||
| if (resources.getUnchecked(i)->originalFilename == file.getFullPathName()) | |||
| return resources.getUnchecked(i); | |||
| return 0; | |||
| } | |||
| bool BinaryResources::add (const String& name, const File& file) | |||
| { | |||
| MemoryBlock mb; | |||
| if (! file.loadFileAsData (mb)) | |||
| return false; | |||
| add (name, file.getFullPathName(), mb); | |||
| return true; | |||
| } | |||
| void BinaryResources::add (const String& name, const String& originalFileName, const MemoryBlock& data) | |||
| { | |||
| BinaryResource* r = findResource (name); | |||
| if (r == 0) | |||
| { | |||
| resources.add (r = new BinaryResource()); | |||
| r->name = name; | |||
| } | |||
| r->originalFilename = originalFileName; | |||
| r->data = data; | |||
| deleteAndZero (r->drawable); | |||
| changed(); | |||
| } | |||
| bool BinaryResources::reload (const int index) | |||
| { | |||
| return resources[index] != 0 | |||
| && add (resources [index]->name, | |||
| File (resources [index]->originalFilename)); | |||
| } | |||
| String BinaryResources::browseForResource (const String& title, | |||
| const String& wildcard, | |||
| const File& fileToStartFrom, | |||
| const String& resourceToReplace) | |||
| { | |||
| FileChooser fc (title, fileToStartFrom, wildcard); | |||
| if (fc.browseForFileToOpen()) | |||
| { | |||
| String name (resourceToReplace); | |||
| if (name.isEmpty()) | |||
| name = findUniqueName (fc.getResult().getFileName()); | |||
| if (! add (name, fc.getResult())) | |||
| { | |||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||
| TRANS("Adding Resource"), | |||
| TRANS("Failed to load the file!")); | |||
| name = String::empty; | |||
| } | |||
| return name; | |||
| } | |||
| return String::empty; | |||
| } | |||
| String BinaryResources::findUniqueName (const String& rootName) const | |||
| { | |||
| String nameRoot (CodeHelpers::makeValidIdentifier (rootName, true, true, false)); | |||
| String name (nameRoot); | |||
| const StringArray names (getResourceNames()); | |||
| int suffix = 1; | |||
| while (names.contains (name)) | |||
| name = nameRoot + String (++suffix); | |||
| return name; | |||
| } | |||
| void BinaryResources::remove (const int i) | |||
| { | |||
| if (resources[i] != 0) | |||
| { | |||
| resources.remove (i); | |||
| changed(); | |||
| } | |||
| } | |||
| const Drawable* BinaryResources::getDrawable (const String& name) const | |||
| { | |||
| BinaryResources::BinaryResource* const res = const_cast <BinaryResources::BinaryResource*> (getResource (name)); | |||
| if (res == 0) | |||
| return 0; | |||
| if (res->drawable == 0 && res->data.getSize() > 0) | |||
| res->drawable = Drawable::createFromImageData (res->data.getData(), res->data.getSize()); | |||
| return res->drawable; | |||
| } | |||
| Image BinaryResources::getImageFromCache (const String& name) const | |||
| { | |||
| if (const BinaryResources::BinaryResource* const res = getResource (name)) | |||
| if (res->data.getSize() > 0) | |||
| return ImageCache::getFromMemory (res->data.getData(), (int) res->data.getSize()); | |||
| return Image(); | |||
| } | |||
| void BinaryResources::loadFromCpp (const File& cppFileLocation, const String& cppFile) | |||
| { | |||
| StringArray cpp; | |||
| cpp.addLines (cppFile); | |||
| clear(); | |||
| for (int i = 0; i < cpp.size(); ++i) | |||
| { | |||
| if (cpp[i].contains ("JUCER_RESOURCE:")) | |||
| { | |||
| StringArray tokens; | |||
| tokens.addTokens (cpp[i].fromFirstOccurrenceOf (":", false, false), ",", "\"'"); | |||
| tokens.trim(); | |||
| tokens.removeEmptyStrings(); | |||
| const String resourceName (tokens[0]); | |||
| const int size = tokens[1].getIntValue(); | |||
| const String originalFileName (cppFileLocation.getSiblingFile (tokens[2].unquoted()).getFullPathName()); | |||
| jassert (resourceName.isNotEmpty() && size > 0); | |||
| if (resourceName.isNotEmpty() && size > 0) | |||
| { | |||
| const int firstLine = i; | |||
| while (i < cpp.size()) | |||
| if (cpp [i++].contains ("}")) | |||
| break; | |||
| const String dataString (cpp.joinIntoString (" ", firstLine, i - firstLine) | |||
| .fromFirstOccurrenceOf ("{", false, false)); | |||
| MemoryOutputStream out; | |||
| String::CharPointerType t (dataString.getCharPointer()); | |||
| int n = 0; | |||
| while (! t.isEmpty()) | |||
| { | |||
| const juce_wchar c = t.getAndAdvance(); | |||
| if (c >= '0' && c <= '9') | |||
| n = n * 10 + (c - '0'); | |||
| else if (c == ',') | |||
| { | |||
| out.writeByte ((char) n); | |||
| n = 0; | |||
| } | |||
| else if (c == '}') | |||
| break; | |||
| } | |||
| jassert (size < (int) out.getDataSize() && size > (int) out.getDataSize() - 2); | |||
| MemoryBlock mb (out.getData(), out.getDataSize()); | |||
| mb.setSize (size); | |||
| add (resourceName, originalFileName, mb); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void BinaryResources::fillInGeneratedCode (GeneratedCode& code) const | |||
| { | |||
| if (resources.size() > 0) | |||
| { | |||
| code.publicMemberDeclarations << "// Binary resources:\n"; | |||
| String defs; | |||
| defs << "//==============================================================================\n"; | |||
| defs << "// Binary resources - be careful not to edit any of these sections!\n\n"; | |||
| for (int i = 0; i < resources.size(); ++i) | |||
| { | |||
| code.publicMemberDeclarations | |||
| << "static const char* " | |||
| << resources[i]->name | |||
| << ";\nstatic const int " | |||
| << resources[i]->name | |||
| << "Size;\n"; | |||
| const String name (resources[i]->name); | |||
| const MemoryBlock& mb = resources[i]->data; | |||
| defs << "// JUCER_RESOURCE: " << name << ", " << (int) mb.getSize() | |||
| << ", \"" | |||
| << File (resources[i]->originalFilename) | |||
| .getRelativePathFrom (code.document->getCppFile()) | |||
| .replaceCharacter ('\\', '/') | |||
| << "\"\n"; | |||
| String line1; | |||
| line1 << "static const unsigned char resource_" | |||
| << code.className << "_" << name << "[] = { "; | |||
| defs += line1; | |||
| MemoryOutputStream out (65536); | |||
| int charsOnLine = line1.length(); | |||
| for (size_t j = 0; j < mb.getSize(); ++j) | |||
| { | |||
| const int num = ((int) (unsigned char) mb[j]); | |||
| out << num << ','; | |||
| charsOnLine += 2; | |||
| if (num >= 10) | |||
| ++charsOnLine; | |||
| if (num >= 100) | |||
| ++charsOnLine; | |||
| if (charsOnLine >= 200) | |||
| { | |||
| charsOnLine = 0; | |||
| out << '\n'; | |||
| } | |||
| } | |||
| out << (char) 0; | |||
| defs | |||
| << (const char*) out.getData() | |||
| << "0,0};\n\nconst char* " | |||
| << code.className << "::" << name | |||
| << " = (const char*) resource_" << code.className << "_" << name | |||
| << ";\nconst int " | |||
| << code.className << "::" << name << "Size = " | |||
| << (int) mb.getSize() | |||
| << ";\n\n"; | |||
| } | |||
| code.staticMemberDefinitions += defs; | |||
| } | |||
| } | |||
| BinaryResources::BinaryResource::BinaryResource() | |||
| : drawable (0) | |||
| { | |||
| } | |||
| BinaryResources::BinaryResource::~BinaryResource() | |||
| { | |||
| deleteAndZero (drawable); | |||
| } | |||
| @@ -0,0 +1,105 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_BINARYRESOURCES_JUCEHEADER__ | |||
| #define __JUCER_BINARYRESOURCES_JUCEHEADER__ | |||
| class JucerDocument; | |||
| //============================================================================== | |||
| /** | |||
| Manages a list of binary data objects that a JucerDocument wants to embed in | |||
| the code it generates. | |||
| */ | |||
| class BinaryResources | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| BinaryResources(); | |||
| ~BinaryResources(); | |||
| BinaryResources& operator= (const BinaryResources& other); | |||
| void loadFromCpp (const File& cppFileLocation, const String& cpp); | |||
| //============================================================================== | |||
| struct BinaryResource | |||
| { | |||
| BinaryResource(); | |||
| ~BinaryResource(); | |||
| String name; | |||
| String originalFilename; | |||
| MemoryBlock data; | |||
| Drawable* drawable; | |||
| }; | |||
| void clear(); | |||
| bool add (const String& name, const File& file); | |||
| void add (const String& name, const String& originalFileName, const MemoryBlock& data); | |||
| void remove (const int index); | |||
| bool reload (const int index); | |||
| String browseForResource (const String& title, const String& wildcard, | |||
| const File& fileToStartFrom, const String& resourceToReplace); | |||
| String findUniqueName (const String& rootName) const; | |||
| int size() const noexcept { return resources.size(); } | |||
| const BinaryResource* operator[] (const int index) const noexcept { return resources [index]; } | |||
| const BinaryResource* getResource (const String& resourceName) const; | |||
| const BinaryResource* getResourceForFile (const File& file) const; | |||
| StringArray getResourceNames() const; | |||
| const Drawable* getDrawable (const String& name) const; | |||
| Image getImageFromCache (const String& name) const; | |||
| template <class ElementComparator> | |||
| void sort (ElementComparator& sorter) | |||
| { | |||
| resources.sort (sorter, true); | |||
| changed(); | |||
| } | |||
| //============================================================================== | |||
| void setDocument (JucerDocument* const doc) { document = doc; } | |||
| JucerDocument* getDocument() const noexcept { return document; } | |||
| void fillInGeneratedCode (GeneratedCode& code) const; | |||
| private: | |||
| //============================================================================== | |||
| JucerDocument* document; | |||
| OwnedArray <BinaryResource> resources; | |||
| BinaryResource* findResource (const String& name) const noexcept; | |||
| void changed(); | |||
| }; | |||
| #endif // __JUCER_BINARYRESOURCES_JUCEHEADER__ | |||
| @@ -0,0 +1,967 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../jucer_Headers.h" | |||
| #include "jucer_JucerDocument.h" | |||
| #include "jucer_ObjectTypes.h" | |||
| #include "ui/jucer_JucerDocumentEditor.h" | |||
| #include "components/jucer_ComponentUndoableAction.h" | |||
| //============================================================================== | |||
| ComponentLayout::ComponentLayout() | |||
| : document (nullptr), | |||
| nextCompUID (1) | |||
| { | |||
| } | |||
| ComponentLayout::~ComponentLayout() | |||
| { | |||
| components.clear(); | |||
| } | |||
| //============================================================================== | |||
| void ComponentLayout::changed() | |||
| { | |||
| if (document != nullptr) | |||
| document->changed(); | |||
| } | |||
| void ComponentLayout::perform (UndoableAction* action, const String& actionName) | |||
| { | |||
| jassert (document != nullptr); | |||
| if (document != nullptr) | |||
| { | |||
| document->getUndoManager().perform (action, actionName); | |||
| } | |||
| else | |||
| { | |||
| ScopedPointer<UndoableAction> deleter (action); | |||
| action->perform(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void ComponentLayout::clearComponents() | |||
| { | |||
| selected.deselectAll(); | |||
| selected.dispatchPendingMessages(); | |||
| components.clear(); | |||
| changed(); | |||
| } | |||
| //============================================================================== | |||
| class AddCompAction : public UndoableAction | |||
| { | |||
| public: | |||
| AddCompAction (XmlElement* const xml_, ComponentLayout& layout_) | |||
| : indexAdded (-1), | |||
| xml (xml_), | |||
| layout (layout_) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| Component* const newComp = layout.addComponentFromXml (*xml, false); | |||
| jassert (newComp != nullptr); | |||
| indexAdded = layout.indexOfComponent (newComp); | |||
| jassert (indexAdded >= 0); | |||
| return indexAdded >= 0; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| layout.removeComponent (layout.getComponent (indexAdded), false); | |||
| return true; | |||
| } | |||
| int getSizeInUnits() { return 10; } | |||
| int indexAdded; | |||
| private: | |||
| ScopedPointer<XmlElement> xml; | |||
| ComponentLayout& layout; | |||
| static void showCorrectTab() | |||
| { | |||
| if (JucerDocumentEditor* const ed = JucerDocumentEditor::getActiveDocumentHolder()) | |||
| ed->showLayout(); | |||
| } | |||
| AddCompAction (const AddCompAction&); | |||
| AddCompAction& operator= (const AddCompAction&); | |||
| }; | |||
| //============================================================================== | |||
| class DeleteCompAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| DeleteCompAction (Component* const comp, ComponentLayout& layout) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| oldIndex (-1) | |||
| { | |||
| if (ComponentTypeHandler* const h = ComponentTypeHandler::getHandlerFor (*comp)) | |||
| xml = h->createXmlFor (comp, &layout); | |||
| else | |||
| jassertfalse; | |||
| oldIndex = layout.indexOfComponent (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| layout.removeComponent (getComponent(), false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| Component* c = layout.addComponentFromXml (*xml, false); | |||
| jassert (c != nullptr); | |||
| layout.moveComponentZOrder (layout.indexOfComponent (c), oldIndex); | |||
| showCorrectTab(); | |||
| return c != nullptr; | |||
| } | |||
| private: | |||
| ScopedPointer<XmlElement> xml; | |||
| int oldIndex; | |||
| }; | |||
| void ComponentLayout::removeComponent (Component* comp, const bool undoable) | |||
| { | |||
| if (comp != nullptr && components.contains (comp)) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new DeleteCompAction (comp, *this), "Delete components"); | |||
| } | |||
| else | |||
| { | |||
| selected.deselect (comp); | |||
| selected.changed (true); // synchronous message to get rid of any property components | |||
| components.removeObject (comp); | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class FrontBackCompAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| FrontBackCompAction (Component* const comp, ComponentLayout& layout, int newIndex_) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| newIndex (newIndex_) | |||
| { | |||
| oldIndex = layout.indexOfComponent (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| Component* comp = layout.getComponent (oldIndex); | |||
| layout.moveComponentZOrder (oldIndex, newIndex); | |||
| newIndex = layout.indexOfComponent (comp); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| layout.moveComponentZOrder (newIndex, oldIndex); | |||
| return true; | |||
| } | |||
| private: | |||
| int newIndex, oldIndex; | |||
| }; | |||
| void ComponentLayout::moveComponentZOrder (int oldIndex, int newIndex) | |||
| { | |||
| jassert (components [oldIndex] != nullptr); | |||
| if (oldIndex != newIndex && components [oldIndex] != nullptr) | |||
| { | |||
| components.move (oldIndex, newIndex); | |||
| changed(); | |||
| } | |||
| } | |||
| void ComponentLayout::componentToFront (Component* comp, const bool undoable) | |||
| { | |||
| if (comp != nullptr && components.contains (comp)) | |||
| { | |||
| if (undoable) | |||
| perform (new FrontBackCompAction (comp, *this, -1), "Move components to front"); | |||
| else | |||
| moveComponentZOrder (components.indexOf (comp), -1); | |||
| } | |||
| } | |||
| void ComponentLayout::componentToBack (Component* comp, const bool undoable) | |||
| { | |||
| if (comp != nullptr && components.contains (comp)) | |||
| { | |||
| if (undoable) | |||
| perform (new FrontBackCompAction (comp, *this, 0), "Move components to back"); | |||
| else | |||
| moveComponentZOrder (components.indexOf (comp), 0); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| const char* const ComponentLayout::clipboardXmlTag = "COMPONENTS"; | |||
| void ComponentLayout::copySelectedToClipboard() | |||
| { | |||
| if (selected.getNumSelected() == 0) | |||
| return; | |||
| XmlElement clip (clipboardXmlTag); | |||
| for (int i = 0; i < components.size(); ++i) | |||
| { | |||
| Component* const c = components.getUnchecked(i); | |||
| if (selected.isSelected (c)) | |||
| { | |||
| if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*c)) | |||
| { | |||
| XmlElement* const e = type->createXmlFor (c, this); | |||
| clip.addChildElement (e); | |||
| } | |||
| } | |||
| } | |||
| SystemClipboard::copyTextToClipboard (clip.createDocument (String::empty, false, false)); | |||
| } | |||
| void ComponentLayout::paste() | |||
| { | |||
| XmlDocument clip (SystemClipboard::getTextFromClipboard()); | |||
| ScopedPointer<XmlElement> doc (clip.getDocumentElement()); | |||
| if (doc != nullptr && doc->hasTagName (clipboardXmlTag)) | |||
| { | |||
| selected.deselectAll(); | |||
| forEachXmlChildElement (*doc, e) | |||
| if (Component* newComp = addComponentFromXml (*e, true)) | |||
| selected.addToSelection (newComp); | |||
| startDragging(); | |||
| dragSelectedComps (Random::getSystemRandom().nextInt (40), | |||
| Random::getSystemRandom().nextInt (40)); | |||
| endDragging(); | |||
| } | |||
| } | |||
| void ComponentLayout::deleteSelected() | |||
| { | |||
| const SelectedItemSet <Component*> temp (selected); | |||
| selected.deselectAll(); | |||
| selected.changed (true); // synchronous message to get rid of any property components | |||
| if (temp.getNumSelected() > 0) | |||
| { | |||
| for (int i = temp.getNumSelected(); --i >= 0;) | |||
| removeComponent (temp.getSelectedItem (i), true); | |||
| changed(); | |||
| if (document != nullptr) | |||
| document->dispatchPendingMessages(); // forces the change to propagate before a paint() callback can happen, | |||
| // in case there are components floating around that are now dangling pointers | |||
| } | |||
| } | |||
| void ComponentLayout::selectAll() | |||
| { | |||
| for (int i = 0; i < components.size(); ++i) | |||
| selected.addToSelection (components.getUnchecked (i)); | |||
| } | |||
| void ComponentLayout::selectedToFront() | |||
| { | |||
| const SelectedItemSet <Component*> temp (selected); | |||
| for (int i = temp.getNumSelected(); --i >= 0;) | |||
| componentToFront (temp.getSelectedItem(i), true); | |||
| } | |||
| void ComponentLayout::selectedToBack() | |||
| { | |||
| const SelectedItemSet <Component*> temp (selected); | |||
| for (int i = 0; i < temp.getNumSelected(); ++i) | |||
| componentToBack (temp.getSelectedItem(i), true); | |||
| } | |||
| void ComponentLayout::bringLostItemsBackOnScreen (int width, int height) | |||
| { | |||
| for (int i = components.size(); --i >= 0;) | |||
| { | |||
| Component* const c = components[i]; | |||
| if (! c->getBounds().intersects (Rectangle<int> (0, 0, width, height))) | |||
| { | |||
| c->setTopLeftPosition (width / 2, height / 2); | |||
| updateStoredComponentPosition (c, false); | |||
| } | |||
| } | |||
| } | |||
| Component* ComponentLayout::addNewComponent (ComponentTypeHandler* const type, int x, int y) | |||
| { | |||
| ScopedPointer<Component> c (type->createNewComponent (getDocument())); | |||
| jassert (c != nullptr); | |||
| if (c != nullptr) | |||
| { | |||
| c->setSize (type->getDefaultWidth(), type->getDefaultHeight()); | |||
| c->setCentrePosition (x, y); | |||
| updateStoredComponentPosition (c, false); | |||
| c->getProperties().set ("id", nextCompUID++); | |||
| ScopedPointer<XmlElement> xml (type->createXmlFor (c, this)); | |||
| c = nullptr; | |||
| c = addComponentFromXml (*xml, true); | |||
| String memberName (CodeHelpers::makeValidIdentifier (type->getClassName (c), true, true, false)); | |||
| setComponentMemberVariableName (c, memberName); | |||
| selected.selectOnly (c); | |||
| } | |||
| return c.release(); | |||
| } | |||
| Component* ComponentLayout::addComponentFromXml (const XmlElement& xml, const bool undoable) | |||
| { | |||
| if (undoable) | |||
| { | |||
| AddCompAction* const action = new AddCompAction (new XmlElement (xml), *this); | |||
| perform (action, "Add new components"); | |||
| return components [action->indexAdded]; | |||
| } | |||
| if (ComponentTypeHandler* const type | |||
| = ComponentTypeHandler::getHandlerForXmlTag (xml.getTagName())) | |||
| { | |||
| ScopedPointer<Component> newComp (type->createNewComponent (getDocument())); | |||
| if (type->restoreFromXml (xml, newComp, this)) | |||
| { | |||
| // ensure that the new comp's name is unique | |||
| setComponentMemberVariableName (newComp, getComponentMemberVariableName (newComp)); | |||
| // check for duped IDs.. | |||
| while (findComponentWithId (ComponentTypeHandler::getComponentId (newComp)) != nullptr) | |||
| ComponentTypeHandler::setComponentId (newComp, Random::getSystemRandom().nextInt64()); | |||
| components.add (newComp); | |||
| changed(); | |||
| return newComp.release(); | |||
| } | |||
| } | |||
| return nullptr; | |||
| } | |||
| Component* ComponentLayout::findComponentWithId (const int64 componentId) const | |||
| { | |||
| for (int i = 0; i < components.size(); ++i) | |||
| if (ComponentTypeHandler::getComponentId (components.getUnchecked(i)) == componentId) | |||
| return components.getUnchecked(i); | |||
| return nullptr; | |||
| } | |||
| //============================================================================== | |||
| static const char* const dimensionSuffixes[] = { "X", "Y", "W", "H" }; | |||
| Component* ComponentLayout::getComponentRelativePosTarget (Component* comp, int whichDimension) const | |||
| { | |||
| jassert (comp != nullptr); | |||
| if (PaintElement* const pe = dynamic_cast <PaintElement*> (comp)) | |||
| { | |||
| int64 compId; | |||
| if (whichDimension == 0) compId = pe->getPosition().relativeToX; | |||
| else if (whichDimension == 1) compId = pe->getPosition().relativeToY; | |||
| else if (whichDimension == 2) compId = pe->getPosition().relativeToW; | |||
| else compId = pe->getPosition().relativeToH; | |||
| return findComponentWithId (compId); | |||
| } | |||
| return findComponentWithId (comp->getProperties() [String ("relativeTo") + dimensionSuffixes [whichDimension]] | |||
| .toString().getHexValue64()); | |||
| } | |||
| void ComponentLayout::setComponentRelativeTarget (Component* comp, int whichDimension, Component* compToBeRelativeTo) | |||
| { | |||
| PaintElement* const pe = dynamic_cast <PaintElement*> (comp); | |||
| jassert (comp != nullptr); | |||
| jassert (pe != nullptr || components.contains (comp)); | |||
| jassert (compToBeRelativeTo == 0 || components.contains (compToBeRelativeTo)); | |||
| jassert (compToBeRelativeTo == 0 || ! dependsOnComponentForRelativePos (compToBeRelativeTo, comp)); | |||
| if (compToBeRelativeTo != getComponentRelativePosTarget (comp, whichDimension) | |||
| && (compToBeRelativeTo == 0 || ! dependsOnComponentForRelativePos (compToBeRelativeTo, comp))) | |||
| { | |||
| const int64 compId = ComponentTypeHandler::getComponentId (compToBeRelativeTo); | |||
| Rectangle<int> oldBounds (comp->getBounds()); | |||
| RelativePositionedRectangle pos; | |||
| if (pe != nullptr) | |||
| { | |||
| oldBounds = pe->getCurrentBounds (dynamic_cast <PaintRoutineEditor*> (pe->getParentComponent())->getComponentArea()); | |||
| pos = pe->getPosition(); | |||
| } | |||
| else | |||
| { | |||
| pos = ComponentTypeHandler::getComponentPosition (comp); | |||
| } | |||
| if (whichDimension == 0) pos.relativeToX = compId; | |||
| else if (whichDimension == 1) pos.relativeToY = compId; | |||
| else if (whichDimension == 2) pos.relativeToW = compId; | |||
| else if (whichDimension == 3) pos.relativeToH = compId; | |||
| if (pe != nullptr) | |||
| { | |||
| pe->setPosition (pos, true); | |||
| pe->setCurrentBounds (oldBounds, dynamic_cast <PaintRoutineEditor*> (pe->getParentComponent())->getComponentArea(), true); | |||
| } | |||
| else | |||
| { | |||
| setComponentPosition (comp, pos, true); | |||
| comp->setBounds (oldBounds); | |||
| updateStoredComponentPosition (comp, false); | |||
| } | |||
| changed(); | |||
| } | |||
| } | |||
| bool ComponentLayout::dependsOnComponentForRelativePos (Component* comp, Component* possibleDependee) const | |||
| { | |||
| for (int i = 0; i < 4; ++i) | |||
| if (Component* const c = getComponentRelativePosTarget (comp, i)) | |||
| if (c == possibleDependee || dependsOnComponentForRelativePos (c, possibleDependee)) | |||
| return true; | |||
| return false; | |||
| } | |||
| const int menuIdBase = 0x63240000; | |||
| PopupMenu ComponentLayout::getRelativeTargetMenu (Component* comp, int whichDimension) const | |||
| { | |||
| PopupMenu m; | |||
| Component* const current = getComponentRelativePosTarget (comp, whichDimension); | |||
| m.addItem (menuIdBase, "Relative to parent component", true, current == 0); | |||
| m.addSeparator(); | |||
| for (int i = 0; i < components.size(); ++i) | |||
| { | |||
| Component* const c = components.getUnchecked(i); | |||
| if (c != comp) | |||
| m.addItem (menuIdBase + i + 1, | |||
| "Relative to " + getComponentMemberVariableName (c) | |||
| + " (class: " + ComponentTypeHandler::getHandlerFor (*c)->getClassName (c) + ")", | |||
| ! dependsOnComponentForRelativePos (c, comp), | |||
| current == c); | |||
| } | |||
| return m; | |||
| } | |||
| void ComponentLayout::processRelativeTargetMenuResult (Component* comp, int whichDimension, int menuResultID) | |||
| { | |||
| if (menuResultID != 0) | |||
| { | |||
| Component* const newTarget = components [menuResultID - menuIdBase - 1]; | |||
| setComponentRelativeTarget (comp, whichDimension, newTarget); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class ChangeCompPositionAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| ChangeCompPositionAction (Component* const comp, ComponentLayout& layout, | |||
| const RelativePositionedRectangle& newPos_) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| newPos (newPos_) | |||
| { | |||
| oldPos = ComponentTypeHandler::getComponentPosition (comp); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| layout.setComponentPosition (getComponent(), newPos, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| layout.setComponentPosition (getComponent(), oldPos, false); | |||
| return true; | |||
| } | |||
| private: | |||
| RelativePositionedRectangle newPos, oldPos; | |||
| }; | |||
| void ComponentLayout::setComponentPosition (Component* comp, | |||
| const RelativePositionedRectangle& newPos, | |||
| const bool undoable) | |||
| { | |||
| if (ComponentTypeHandler::getComponentPosition (comp) != newPos) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new ChangeCompPositionAction (comp, *this, newPos), "Move components"); | |||
| } | |||
| else | |||
| { | |||
| ComponentTypeHandler::setComponentPosition (comp, newPos, this); | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| void ComponentLayout::updateStoredComponentPosition (Component* comp, const bool undoable) | |||
| { | |||
| RelativePositionedRectangle newPos (ComponentTypeHandler::getComponentPosition (comp)); | |||
| newPos.updateFromComponent (*comp, this); | |||
| setComponentPosition (comp, newPos, undoable); | |||
| } | |||
| //============================================================================== | |||
| void ComponentLayout::startDragging() | |||
| { | |||
| for (int i = 0; i < components.size(); ++i) | |||
| { | |||
| Component* const c = components[i]; | |||
| c->getProperties().set ("xDragStart", c->getX()); | |||
| c->getProperties().set ("yDragStart", c->getY()); | |||
| } | |||
| jassert (document != nullptr); | |||
| document->beginTransaction(); | |||
| } | |||
| void ComponentLayout::dragSelectedComps (int dx, int dy, const bool allowSnap) | |||
| { | |||
| if (allowSnap && document != nullptr && selected.getNumSelected() > 1) | |||
| { | |||
| dx = document->snapPosition (dx); | |||
| dy = document->snapPosition (dy); | |||
| } | |||
| for (int i = 0; i < selected.getNumSelected(); ++i) | |||
| { | |||
| Component* const c = selected.getSelectedItem (i); | |||
| const int startX = c->getProperties() ["xDragStart"]; | |||
| const int startY = c->getProperties() ["yDragStart"]; | |||
| if (allowSnap && document != nullptr && selected.getNumSelected() == 1) | |||
| { | |||
| c->setTopLeftPosition (document->snapPosition (startX + dx), | |||
| document->snapPosition (startY + dy)); | |||
| } | |||
| else | |||
| { | |||
| c->setTopLeftPosition (startX + dx, | |||
| startY + dy); | |||
| } | |||
| updateStoredComponentPosition (c, false); | |||
| } | |||
| } | |||
| void ComponentLayout::endDragging() | |||
| { | |||
| // after the drag, roll back all the comps to their start position, then | |||
| // back to their finish positions using an undoable command. | |||
| document->beginTransaction(); | |||
| for (int i = 0; i < selected.getNumSelected(); ++i) | |||
| { | |||
| Component* const c = selected.getSelectedItem (i); | |||
| const int newX = c->getX(); | |||
| const int newY = c->getY(); | |||
| const int startX = c->getProperties() ["xDragStart"]; | |||
| const int startY = c->getProperties() ["yDragStart"]; | |||
| c->setTopLeftPosition (startX, startY); | |||
| updateStoredComponentPosition (c, false); | |||
| c->setTopLeftPosition (newX, newY); | |||
| updateStoredComponentPosition (c, true); | |||
| } | |||
| document->beginTransaction(); | |||
| } | |||
| void ComponentLayout::moveSelectedComps (int dx, int dy, bool snap) | |||
| { | |||
| startDragging(); | |||
| dragSelectedComps (dx, dy, snap); | |||
| endDragging(); | |||
| } | |||
| void ComponentLayout::stretchSelectedComps (int dw, int dh, bool allowSnap) | |||
| { | |||
| int neww, newh; | |||
| if (document != nullptr && selected.getNumSelected() == 1) | |||
| { | |||
| Component* const c = selected.getSelectedItem (0); | |||
| if (allowSnap) | |||
| { | |||
| int bot = c->getBottom() + dh; | |||
| int right = c->getRight() + dw; | |||
| bot = (dh != 0) ? document->snapPosition (bot) : bot; | |||
| right = (dw != 0) ? document->snapPosition (right) : right; | |||
| newh = bot - c->getY(); | |||
| neww = right - c->getX(); | |||
| } | |||
| else | |||
| { | |||
| newh = c->getHeight() + dh; | |||
| neww = c->getWidth() + dw; | |||
| } | |||
| c->setSize (neww, newh); | |||
| updateStoredComponentPosition (c, true); | |||
| } | |||
| else | |||
| { | |||
| for (int i = 0; i < selected.getNumSelected(); ++i) | |||
| { | |||
| Component* const c = selected.getSelectedItem (i); | |||
| neww = c->getWidth() + dw; | |||
| newh = c->getHeight() + dh; | |||
| c->setSize (neww, newh); | |||
| updateStoredComponentPosition (c, true); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void ComponentLayout::fillInGeneratedCode (GeneratedCode& code) const | |||
| { | |||
| for (int i = 0; i < components.size(); ++i) | |||
| if (Component* const comp = components.getUnchecked(i)) | |||
| if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp)) | |||
| type->fillInGeneratedCode (comp, code); | |||
| } | |||
| //============================================================================== | |||
| String ComponentLayout::getComponentMemberVariableName (Component* comp) const | |||
| { | |||
| if (comp == nullptr) | |||
| return String::empty; | |||
| String name (comp->getProperties() ["memberName"].toString()); | |||
| if (name.isEmpty()) | |||
| name = getUnusedMemberName (CodeHelpers::makeValidIdentifier (comp->getName(), true, true, false), comp); | |||
| return name; | |||
| } | |||
| void ComponentLayout::setComponentMemberVariableName (Component* comp, const String& newName) | |||
| { | |||
| const String oldName (getComponentMemberVariableName (comp)); | |||
| comp->getProperties().set ("memberName", String::empty); | |||
| const String n (getUnusedMemberName (CodeHelpers::makeValidIdentifier (newName, false, true, false), comp)); | |||
| comp->getProperties().set ("memberName", n); | |||
| if (n != oldName) | |||
| changed(); | |||
| } | |||
| String ComponentLayout::getUnusedMemberName (String nameRoot, Component* comp) const | |||
| { | |||
| String n (nameRoot); | |||
| while (CharacterFunctions::isDigit (nameRoot.getLastCharacter())) | |||
| nameRoot = nameRoot.dropLastCharacters (1); | |||
| int suffix = 2; | |||
| for (;;) | |||
| { | |||
| bool alreadyUsed = false; | |||
| for (int i = 0; i < components.size(); ++i) | |||
| { | |||
| if (components[i] != comp | |||
| && components[i]->getProperties() ["memberName"] == n) | |||
| { | |||
| alreadyUsed = true; | |||
| break; | |||
| } | |||
| } | |||
| if (! alreadyUsed) | |||
| break; | |||
| n = nameRoot + String (suffix++); | |||
| } | |||
| return n; | |||
| } | |||
| //============================================================================== | |||
| String ComponentLayout::getComponentVirtualClassName (Component* comp) const | |||
| { | |||
| if (comp == nullptr) | |||
| return String::empty; | |||
| return comp->getProperties() ["virtualName"]; | |||
| } | |||
| void ComponentLayout::setComponentVirtualClassName (Component* comp, const String& newName) | |||
| { | |||
| const String name (CodeHelpers::makeValidIdentifier (newName, false, false, true)); | |||
| if (name != getComponentVirtualClassName (comp)) | |||
| { | |||
| comp->getProperties().set ("virtualName", name); | |||
| changed(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void ComponentLayout::addToXml (XmlElement& xml) const | |||
| { | |||
| for (int i = 0; i < components.size(); ++i) | |||
| if (ComponentTypeHandler* h = ComponentTypeHandler::getHandlerFor (*components [i])) | |||
| xml.addChildElement (h->createXmlFor (components [i], this)); | |||
| } | |||
| //============================================================================== | |||
| void positionToCode (const RelativePositionedRectangle& position, | |||
| const ComponentLayout* layout, | |||
| String& x, String& y, String& w, String& h) | |||
| { | |||
| // these are the code sections for the positions of the relative comps | |||
| String xrx, xry, xrw, xrh; | |||
| if (Component* const relCompX = layout != nullptr ? layout->findComponentWithId (position.relativeToX) : nullptr) | |||
| positionToCode (ComponentTypeHandler::getComponentPosition (relCompX), layout, xrx, xry, xrw, xrh); | |||
| String yrx, yry, yrw, yrh; | |||
| if (Component* const relCompY = layout != nullptr ? layout->findComponentWithId (position.relativeToY) : nullptr) | |||
| positionToCode (ComponentTypeHandler::getComponentPosition (relCompY), layout, yrx, yry, yrw, yrh); | |||
| String wrx, wry, wrw, wrh; | |||
| if (Component* const relCompW = (layout != nullptr && position.rect.getWidthMode() != PositionedRectangle::absoluteSize) | |||
| ? layout->findComponentWithId (position.relativeToW) : nullptr) | |||
| positionToCode (ComponentTypeHandler::getComponentPosition (relCompW), layout, wrx, wry, wrw, wrh); | |||
| String hrx, hry, hrw, hrh; | |||
| if (Component* const relCompH = (layout != nullptr && position.rect.getHeightMode() != PositionedRectangle::absoluteSize) | |||
| ? layout->findComponentWithId (position.relativeToH) : nullptr) | |||
| positionToCode (ComponentTypeHandler::getComponentPosition (relCompH), layout, hrx, hry, hrw, hrh); | |||
| // width | |||
| if (position.rect.getWidthMode() == PositionedRectangle::proportionalSize) | |||
| { | |||
| if (wrw.isNotEmpty()) | |||
| w << "roundFloatToInt ((" << wrw << ") * " << CodeHelpers::floatLiteral (position.rect.getWidth(), 4) << ")"; | |||
| else | |||
| w << "proportionOfWidth (" << CodeHelpers::floatLiteral (position.rect.getWidth(), 4) << ")"; | |||
| } | |||
| else if (position.rect.getWidthMode() == PositionedRectangle::parentSizeMinusAbsolute) | |||
| { | |||
| if (wrw.isNotEmpty()) | |||
| w << "(" << wrw << ") - " << roundToInt (position.rect.getWidth()); | |||
| else | |||
| w << "getWidth() - " << roundToInt (position.rect.getWidth()); | |||
| } | |||
| else | |||
| { | |||
| if (wrw.isNotEmpty()) | |||
| w << "(" << wrw << ") + "; | |||
| w << roundToInt (position.rect.getWidth()); | |||
| } | |||
| // height | |||
| if (position.rect.getHeightMode() == PositionedRectangle::proportionalSize) | |||
| { | |||
| if (hrh.isNotEmpty()) | |||
| h << "roundFloatToInt ((" << hrh << ") * " << CodeHelpers::floatLiteral (position.rect.getHeight(), 4) << ")"; | |||
| else | |||
| h << "proportionOfHeight (" << CodeHelpers::floatLiteral (position.rect.getHeight(), 4) << ")"; | |||
| } | |||
| else if (position.rect.getHeightMode() == PositionedRectangle::parentSizeMinusAbsolute) | |||
| { | |||
| if (hrh.isNotEmpty()) | |||
| h << "(" << hrh << ") - " << roundToInt (position.rect.getHeight()); | |||
| else | |||
| h << "getHeight() - " << roundToInt (position.rect.getHeight()); | |||
| } | |||
| else | |||
| { | |||
| if (hrh.isNotEmpty()) | |||
| h << "(" << hrh << ") + "; | |||
| h << roundToInt (position.rect.getHeight()); | |||
| } | |||
| // x-pos | |||
| if (position.rect.getPositionModeX() == PositionedRectangle::proportionOfParentSize) | |||
| { | |||
| if (xrx.isNotEmpty() && xrw.isNotEmpty()) | |||
| x << "(" << xrx << ") + roundFloatToInt ((" << xrw << ") * " << CodeHelpers::floatLiteral (position.rect.getX(), 4) << ")"; | |||
| else | |||
| x << "proportionOfWidth (" << CodeHelpers::floatLiteral (position.rect.getX(), 4) << ")"; | |||
| } | |||
| else if (position.rect.getPositionModeX() == PositionedRectangle::absoluteFromParentTopLeft) | |||
| { | |||
| if (xrx.isNotEmpty()) | |||
| x << "(" << xrx << ") + "; | |||
| x << roundToInt (position.rect.getX()); | |||
| } | |||
| else if (position.rect.getPositionModeX() == PositionedRectangle::absoluteFromParentBottomRight) | |||
| { | |||
| if (xrx.isNotEmpty()) | |||
| x << "(" << xrx << ") + (" << xrw << ")"; | |||
| else | |||
| x << "getWidth()"; | |||
| const int d = roundToInt (position.rect.getX()); | |||
| if (d != 0) | |||
| x << " - " << d; | |||
| } | |||
| else if (position.rect.getPositionModeX() == PositionedRectangle::absoluteFromParentCentre) | |||
| { | |||
| if (xrx.isNotEmpty()) | |||
| x << "(" << xrx << ") + (" << xrw << ") / 2"; | |||
| else | |||
| x << "(getWidth() / 2)"; | |||
| const int d = roundToInt (position.rect.getX()); | |||
| if (d != 0) | |||
| x << " + " << d; | |||
| } | |||
| if (w != "0") | |||
| { | |||
| if (position.rect.getAnchorPointX() == PositionedRectangle::anchorAtRightOrBottom) | |||
| x << " - " << w; | |||
| else if (position.rect.getAnchorPointX() == PositionedRectangle::anchorAtCentre) | |||
| x << " - ((" << w << ") / 2)"; | |||
| } | |||
| // y-pos | |||
| if (position.rect.getPositionModeY() == PositionedRectangle::proportionOfParentSize) | |||
| { | |||
| if (yry.isNotEmpty() && yrh.isNotEmpty()) | |||
| y << "(" << yry << ") + roundFloatToInt ((" << yrh << ") * " << CodeHelpers::floatLiteral (position.rect.getY(), 4) << ")"; | |||
| else | |||
| y << "proportionOfHeight (" << CodeHelpers::floatLiteral (position.rect.getY(), 4) << ")"; | |||
| } | |||
| else if (position.rect.getPositionModeY() == PositionedRectangle::absoluteFromParentTopLeft) | |||
| { | |||
| if (yry.isNotEmpty()) | |||
| y << "(" << yry << ") + "; | |||
| y << roundToInt (position.rect.getY()); | |||
| } | |||
| else if (position.rect.getPositionModeY() == PositionedRectangle::absoluteFromParentBottomRight) | |||
| { | |||
| if (yry.isNotEmpty()) | |||
| y << "(" << yry << ") + (" << yrh << ")"; | |||
| else | |||
| y << "getHeight()"; | |||
| const int d = roundToInt (position.rect.getY()); | |||
| if (d != 0) | |||
| y << " - " << d; | |||
| } | |||
| else if (position.rect.getPositionModeY() == PositionedRectangle::absoluteFromParentCentre) | |||
| { | |||
| if (yry.isNotEmpty()) | |||
| y << "(" << yry << ") + (" << yrh << ") / 2"; | |||
| else | |||
| y << "(getHeight() / 2)"; | |||
| const int d = roundToInt (position.rect.getY()); | |||
| if (d != 0) | |||
| y << " + " << d; | |||
| } | |||
| if (h != "0") | |||
| { | |||
| if (position.rect.getAnchorPointY() == PositionedRectangle::anchorAtRightOrBottom) | |||
| y << " - " << h; | |||
| else if (position.rect.getAnchorPointY() == PositionedRectangle::anchorAtCentre) | |||
| y << " - ((" << h << ") / 2)"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,136 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTLAYOUT_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTLAYOUT_JUCEHEADER__ | |||
| #include "components/jucer_ComponentTypeHandler.h" | |||
| class JucerDocument; | |||
| //============================================================================== | |||
| /** | |||
| Manages the set of sub-components for a JucerDocument. | |||
| */ | |||
| class ComponentLayout | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentLayout(); | |||
| ~ComponentLayout(); | |||
| //============================================================================== | |||
| void changed(); | |||
| int getNumComponents() const noexcept { return components.size(); } | |||
| Component* getComponent (const int index) const noexcept { return components [index]; } | |||
| int indexOfComponent (Component* const comp) const noexcept { return components.indexOf (comp); } | |||
| bool containsComponent (Component* const comp) const noexcept { return components.contains (comp); } | |||
| //============================================================================== | |||
| void clearComponents(); | |||
| void removeComponent (Component* comp, const bool undoable); | |||
| Component* addNewComponent (ComponentTypeHandler* const type, int x, int y); | |||
| Component* addComponentFromXml (const XmlElement& xml, const bool undoable); | |||
| Component* findComponentWithId (const int64 componentId) const; | |||
| //============================================================================== | |||
| void componentToFront (Component* comp, const bool undoable); | |||
| void componentToBack (Component* comp, const bool undoable); | |||
| void setComponentPosition (Component* comp, const RelativePositionedRectangle& newPos, const bool undoable); | |||
| void updateStoredComponentPosition (Component* comp, const bool undoable); | |||
| //============================================================================== | |||
| Component* getComponentRelativePosTarget (Component* comp, int whichDimension) const; | |||
| void setComponentRelativeTarget (Component* comp, int whichDimension, Component* compToBeRelativeTo); | |||
| // checks recursively whether the comp depends on the given comp for its position | |||
| bool dependsOnComponentForRelativePos (Component* comp, Component* possibleDependee) const; | |||
| PopupMenu getRelativeTargetMenu (Component* comp, int whichDimension) const; | |||
| void processRelativeTargetMenuResult (Component* comp, int whichDimension, int menuResultID); | |||
| //============================================================================== | |||
| void setComponentMemberVariableName (Component* comp, const String& newName); | |||
| String getComponentMemberVariableName (Component* comp) const; | |||
| //============================================================================== | |||
| void setComponentVirtualClassName (Component* comp, const String& newName); | |||
| String getComponentVirtualClassName (Component* comp) const; | |||
| //============================================================================== | |||
| SelectedItemSet <Component*>& getSelectedSet() { return selected; } | |||
| static const char* const clipboardXmlTag; | |||
| void copySelectedToClipboard(); | |||
| void paste(); | |||
| void deleteSelected(); | |||
| void selectAll(); | |||
| void selectedToFront(); | |||
| void selectedToBack(); | |||
| void startDragging(); | |||
| void dragSelectedComps (int dxFromDragStart, int dyFromDragStart, const bool allowSnap = true); | |||
| void endDragging(); | |||
| void moveSelectedComps (int dx, int dy, bool snap); | |||
| void stretchSelectedComps (int dw, int dh, bool allowSnap); | |||
| void bringLostItemsBackOnScreen (int width, int height); | |||
| //============================================================================== | |||
| void setDocument (JucerDocument* const doc) { document = doc; } | |||
| JucerDocument* getDocument() const noexcept { return document; } | |||
| //============================================================================== | |||
| void addToXml (XmlElement& xml) const; | |||
| void fillInGeneratedCode (GeneratedCode& code) const; | |||
| void perform (UndoableAction* action, const String& actionName); | |||
| private: | |||
| JucerDocument* document; | |||
| OwnedArray <Component> components; | |||
| SelectedItemSet <Component*> selected; | |||
| int nextCompUID; | |||
| String getUnusedMemberName (String nameRoot, Component* comp) const; | |||
| friend class FrontBackCompAction; | |||
| friend class DeleteCompAction; | |||
| void moveComponentZOrder (int oldIndex, int newIndex); | |||
| }; | |||
| void positionToCode (const RelativePositionedRectangle& position, | |||
| const ComponentLayout* layout, | |||
| String& x, String& y, String& w, String& h); | |||
| #endif // __JUCER_COMPONENTLAYOUT_JUCEHEADER__ | |||
| @@ -0,0 +1,379 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../jucer_Headers.h" | |||
| #include "jucer_GeneratedCode.h" | |||
| //============================================================================== | |||
| GeneratedCode::GeneratedCode (const JucerDocument* const doc) | |||
| : document (doc), suffix (0) | |||
| { | |||
| } | |||
| GeneratedCode::~GeneratedCode() | |||
| { | |||
| } | |||
| int GeneratedCode::getUniqueSuffix() | |||
| { | |||
| return ++suffix; | |||
| } | |||
| //============================================================================== | |||
| String& GeneratedCode::getCallbackCode (const String& requiredParentClass, | |||
| const String& returnType, | |||
| const String& prototype, | |||
| const bool hasPrePostUserSections) | |||
| { | |||
| String parentClass (requiredParentClass); | |||
| if (parentClass.isNotEmpty() | |||
| && ! (parentClass.startsWith ("public ") | |||
| || parentClass.startsWith ("private ") | |||
| || parentClass.startsWith ("protected "))) | |||
| { | |||
| parentClass = "public " + parentClass; | |||
| } | |||
| for (int i = callbacks.size(); --i >= 0;) | |||
| { | |||
| CallbackMethod* const cm = callbacks.getUnchecked(i); | |||
| if (cm->requiredParentClass == parentClass | |||
| && cm->returnType == returnType | |||
| && cm->prototype == prototype) | |||
| return cm->content; | |||
| } | |||
| CallbackMethod* const cm = new CallbackMethod(); | |||
| callbacks.add (cm); | |||
| cm->requiredParentClass = parentClass; | |||
| cm->returnType = returnType; | |||
| cm->prototype = prototype; | |||
| cm->hasPrePostUserSections = hasPrePostUserSections; | |||
| return cm->content; | |||
| } | |||
| void GeneratedCode::removeCallback (const String& returnType, const String& prototype) | |||
| { | |||
| for (int i = callbacks.size(); --i >= 0;) | |||
| { | |||
| CallbackMethod* const cm = callbacks.getUnchecked(i); | |||
| if (cm->returnType == returnType && cm->prototype == prototype) | |||
| callbacks.remove (i); | |||
| } | |||
| } | |||
| void GeneratedCode::addImageResourceLoader (const String& imageMemberName, const String& resourceName) | |||
| { | |||
| const String initialiser (imageMemberName + " (0)"); | |||
| if (! initialisers.contains (initialiser, false)) | |||
| { | |||
| initialisers.add (initialiser); | |||
| privateMemberDeclarations | |||
| << "Image " << imageMemberName << ";\n"; | |||
| if (resourceName.isNotEmpty()) | |||
| { | |||
| constructorCode | |||
| << imageMemberName << " = ImageCache::getFromMemory (" | |||
| << resourceName << ", " << resourceName << "Size);\n"; | |||
| } | |||
| } | |||
| } | |||
| StringArray GeneratedCode::getExtraParentClasses() const | |||
| { | |||
| StringArray s; | |||
| for (int i = 0; i < callbacks.size(); ++i) | |||
| { | |||
| CallbackMethod* const cm = callbacks.getUnchecked(i); | |||
| s.add (cm->requiredParentClass); | |||
| } | |||
| return s; | |||
| } | |||
| String GeneratedCode::getCallbackDeclarations() const | |||
| { | |||
| String s; | |||
| for (int i = 0; i < callbacks.size(); ++i) | |||
| { | |||
| CallbackMethod* const cm = callbacks.getUnchecked(i); | |||
| s << cm->returnType << " " << cm->prototype << ";\n"; | |||
| } | |||
| return s; | |||
| } | |||
| String GeneratedCode::getCallbackDefinitions() const | |||
| { | |||
| String s; | |||
| for (int i = 0; i < callbacks.size(); ++i) | |||
| { | |||
| CallbackMethod* const cm = callbacks.getUnchecked(i); | |||
| const String userCodeBlockName ("User" | |||
| + CodeHelpers::makeValidIdentifier (cm->prototype.upToFirstOccurrenceOf ("(", false, false), | |||
| true, true, false).trim()); | |||
| if (userCodeBlockName.isNotEmpty() && cm->hasPrePostUserSections) | |||
| { | |||
| s << cm->returnType << " " << className << "::" << cm->prototype | |||
| << "\n{\n //[" << userCodeBlockName << "_Pre]\n //[/" << userCodeBlockName | |||
| << "_Pre]\n\n " | |||
| << CodeHelpers::indent (cm->content.trim(), 4, false) | |||
| << "\n\n //[" << userCodeBlockName << "_Post]\n //[/" << userCodeBlockName | |||
| << "_Post]\n}\n\n"; | |||
| } | |||
| else | |||
| { | |||
| s << cm->returnType << " " << className << "::" << cm->prototype | |||
| << "\n{\n " | |||
| << CodeHelpers::indent (cm->content.trim(), 4, false) | |||
| << "\n}\n\n"; | |||
| } | |||
| } | |||
| return s; | |||
| } | |||
| //============================================================================== | |||
| String GeneratedCode::getClassDeclaration() const | |||
| { | |||
| StringArray parentClassLines; | |||
| parentClassLines.addTokens (parentClasses, ",", String::empty); | |||
| parentClassLines.addArray (getExtraParentClasses()); | |||
| parentClassLines.trim(); | |||
| parentClassLines.removeEmptyStrings(); | |||
| parentClassLines.removeDuplicates (false); | |||
| if (parentClassLines.contains ("public Button", false)) | |||
| parentClassLines.removeString ("public Component", false); | |||
| String r ("class "); | |||
| r << className << " : "; | |||
| r += parentClassLines.joinIntoString (",\n" + String::repeatedString (" ", r.length())); | |||
| return r; | |||
| } | |||
| String GeneratedCode::getInitialiserList() const | |||
| { | |||
| StringArray inits (initialisers); | |||
| if (parentClassInitialiser.isNotEmpty()) | |||
| inits.insert (0, parentClassInitialiser); | |||
| inits.trim(); | |||
| inits.removeEmptyStrings(); | |||
| inits.removeDuplicates (false); | |||
| String s; | |||
| if (inits.size() == 0) | |||
| return s; | |||
| s << " : "; | |||
| for (int i = 0; i < inits.size(); ++i) | |||
| { | |||
| String init (inits[i]); | |||
| while (init.endsWithChar (',')) | |||
| init = init.dropLastCharacters (1); | |||
| s << init; | |||
| if (i < inits.size() - 1) | |||
| s << ",\n "; | |||
| else | |||
| s << "\n"; | |||
| } | |||
| return s; | |||
| } | |||
| static String getIncludeFileCode (StringArray files) | |||
| { | |||
| files.trim(); | |||
| files.removeEmptyStrings(); | |||
| files.removeDuplicates (false); | |||
| String s; | |||
| for (int i = 0; i < files.size(); ++i) | |||
| s << "#include \"" << files[i] << "\"\n"; | |||
| return s; | |||
| } | |||
| //============================================================================== | |||
| static void replaceTemplate (String& text, const String& itemName, const String& value) | |||
| { | |||
| for (;;) | |||
| { | |||
| const int index = text.indexOf ("%%" + itemName + "%%"); | |||
| if (index < 0) | |||
| break; | |||
| int indentLevel = 0; | |||
| for (int i = index; --i >= 0;) | |||
| { | |||
| if (text[i] == '\n') | |||
| break; | |||
| ++indentLevel; | |||
| } | |||
| text = text.replaceSection (index, itemName.length() + 4, | |||
| CodeHelpers::indent (value, indentLevel, false)); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| static bool getUserSection (const StringArray& lines, const String& tag, StringArray& resultLines) | |||
| { | |||
| const int start = indexOfLineStartingWith (lines, "//[" + tag + "]", 0); | |||
| if (start < 0) | |||
| return false; | |||
| const int end = indexOfLineStartingWith (lines, "//[/" + tag + "]", start + 1); | |||
| for (int i = start + 1; i < end; ++i) | |||
| resultLines.add (lines [i]); | |||
| return true; | |||
| } | |||
| static void copyAcrossUserSections (String& dest, const String& src) | |||
| { | |||
| StringArray srcLines, dstLines; | |||
| srcLines.addLines (src); | |||
| dstLines.addLines (dest); | |||
| for (int i = 0; i < dstLines.size(); ++i) | |||
| { | |||
| if (dstLines[i].trimStart().startsWith ("//[")) | |||
| { | |||
| String tag (dstLines[i].trimStart().substring (3)); | |||
| tag = tag.upToFirstOccurrenceOf ("]", false, false); | |||
| jassert (! tag.startsWithChar ('/')); | |||
| if (! tag.startsWithChar ('/')) | |||
| { | |||
| const int endLine = indexOfLineStartingWith (dstLines, | |||
| "//[/" + tag + "]", | |||
| i + 1); | |||
| if (endLine > i) | |||
| { | |||
| StringArray sourceLines; | |||
| if (getUserSection (srcLines, tag, sourceLines)) | |||
| { | |||
| int j; | |||
| for (j = endLine - i; --j > 0;) | |||
| dstLines.remove (i + 1); | |||
| for (j = 0; j < sourceLines.size(); ++j) | |||
| dstLines.insert (++i, sourceLines [j].trimEnd()); | |||
| ++i; | |||
| } | |||
| else | |||
| { | |||
| i = endLine; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| dstLines.set (i, dstLines[i].trimEnd()); | |||
| } | |||
| dest = dstLines.joinIntoString ("\n") + "\n"; | |||
| } | |||
| //============================================================================== | |||
| void GeneratedCode::applyToCode (String& code, | |||
| const String& fileNameRoot, | |||
| const bool isForPreview, | |||
| const String& oldFileWithUserData) const | |||
| { | |||
| // header guard.. | |||
| String headerGuard ("__JUCER_HEADER_"); | |||
| headerGuard << className.toUpperCase().retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZ") | |||
| << "_" << fileNameRoot.toUpperCase().retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZ") | |||
| << "_" << String::toHexString (Random::getSystemRandom().nextInt()).toUpperCase() | |||
| << "__"; | |||
| replaceTemplate (code, "headerGuard", headerGuard); | |||
| replaceTemplate (code, "version", JUCEApplication::getInstance()->getApplicationVersion()); | |||
| replaceTemplate (code, "creationTime", Time::getCurrentTime().toString (true, true, true)); | |||
| replaceTemplate (code, "className", className); | |||
| replaceTemplate (code, "constructorParams", constructorParams); | |||
| replaceTemplate (code, "initialisers", getInitialiserList()); | |||
| replaceTemplate (code, "classDeclaration", getClassDeclaration()); | |||
| replaceTemplate (code, "privateMemberDeclarations", privateMemberDeclarations); | |||
| replaceTemplate (code, "publicMemberDeclarations", getCallbackDeclarations() + "\n" + publicMemberDeclarations); | |||
| replaceTemplate (code, "methodDefinitions", getCallbackDefinitions()); | |||
| replaceTemplate (code, "includeFilesH", getIncludeFileCode (includeFilesH)); | |||
| replaceTemplate (code, "includeFilesCPP", getIncludeFileCode (includeFilesCPP)); | |||
| replaceTemplate (code, "constructor", constructorCode); | |||
| replaceTemplate (code, "destructor", destructorCode); | |||
| if (! isForPreview) | |||
| { | |||
| replaceTemplate (code, "metadata", jucerMetadata); | |||
| replaceTemplate (code, "staticMemberDefinitions", staticMemberDefinitions); | |||
| } | |||
| else | |||
| { | |||
| replaceTemplate (code, "metadata", " << Metadata isn't shown in the code preview >>\n"); | |||
| replaceTemplate (code, "staticMemberDefinitions", "// Static member declarations and resources would go here... (these aren't shown in the code preview)"); | |||
| } | |||
| copyAcrossUserSections (code, oldFileWithUserData); | |||
| } | |||
| @@ -0,0 +1,101 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_GENERATEDCODE_JUCEHEADER__ | |||
| #define __JUCER_GENERATEDCODE_JUCEHEADER__ | |||
| class JucerDocument; | |||
| //============================================================================== | |||
| /** | |||
| A class for collecting the various snippets of c++ that will be assembled into | |||
| the final cpp and header files. | |||
| */ | |||
| class GeneratedCode | |||
| { | |||
| public: | |||
| GeneratedCode (const JucerDocument*); | |||
| ~GeneratedCode(); | |||
| //============================================================================== | |||
| void applyToCode (String& code, | |||
| const String& fileNameRoot, | |||
| const bool isForPreview, | |||
| const String& oldFileWithUserData = String::empty) const; | |||
| int getUniqueSuffix(); | |||
| //============================================================================== | |||
| const JucerDocument* const document; | |||
| String className; | |||
| String componentName; | |||
| String parentClassInitialiser; // optional parent class initialiser to go before the items in the initialisers list | |||
| StringArray initialisers; // (a list of the member variables that need initalising after the constructor declaration) | |||
| String parentClasses; | |||
| String constructorParams; | |||
| String privateMemberDeclarations; | |||
| String publicMemberDeclarations; | |||
| StringArray includeFilesH, includeFilesCPP; | |||
| String constructorCode; | |||
| String destructorCode; | |||
| String staticMemberDefinitions; | |||
| String jucerMetadata; | |||
| struct CallbackMethod | |||
| { | |||
| String requiredParentClass; | |||
| String returnType; | |||
| String prototype; | |||
| String content; | |||
| bool hasPrePostUserSections; | |||
| }; | |||
| OwnedArray <CallbackMethod> callbacks; | |||
| String& getCallbackCode (const String& requiredParentClass, | |||
| const String& returnType, | |||
| const String& prototype, | |||
| const bool hasPrePostUserSections); | |||
| void removeCallback (const String& returnType, const String& prototype); | |||
| void addImageResourceLoader (const String& imageMemberName, const String& resourceName); | |||
| String getCallbackDeclarations() const; | |||
| String getCallbackDefinitions() const; | |||
| StringArray getExtraParentClasses() const; | |||
| private: | |||
| String getClassDeclaration() const; | |||
| String getInitialiserList() const; | |||
| int suffix; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GeneratedCode) | |||
| }; | |||
| #endif // __JUCER_GENERATEDCODE_JUCEHEADER__ | |||
| @@ -0,0 +1,723 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../jucer_Headers.h" | |||
| #include "../Application/jucer_Application.h" | |||
| #include "../Project/jucer_NewFileWizard.h" | |||
| #include "jucer_JucerDocument.h" | |||
| #include "jucer_ObjectTypes.h" | |||
| #include "ui/jucer_JucerDocumentEditor.h" | |||
| #include "ui/jucer_TestComponent.h" | |||
| #include "jucer_UtilityFunctions.h" | |||
| #include "documents/jucer_ComponentDocument.h" | |||
| #include "documents/jucer_ButtonDocument.h" | |||
| const char* const defaultClassName = "NewComponent"; | |||
| const char* const defaultParentClasses = "public Component"; | |||
| //============================================================================== | |||
| JucerDocument::JucerDocument (SourceCodeDocument* c) | |||
| : cpp (c), | |||
| className (defaultClassName), | |||
| parentClasses (defaultParentClasses), | |||
| fixedSize (false), | |||
| initialWidth (600), | |||
| initialHeight (400), | |||
| snapGridPixels (8), | |||
| snapActive (true), | |||
| snapShown (true), | |||
| componentOverlayOpacity (0.33f) | |||
| { | |||
| jassert (cpp != nullptr); | |||
| resources.setDocument (this); | |||
| commandManager->commandStatusChanged(); | |||
| cpp->getCodeDocument().addListener (this); | |||
| } | |||
| JucerDocument::~JucerDocument() | |||
| { | |||
| cpp->getCodeDocument().removeListener (this); | |||
| commandManager->commandStatusChanged(); | |||
| } | |||
| //============================================================================== | |||
| void JucerDocument::changed() | |||
| { | |||
| sendChangeMessage(); | |||
| commandManager->commandStatusChanged(); | |||
| startTimer (800); | |||
| } | |||
| struct UserDocChangeTimer : public Timer | |||
| { | |||
| UserDocChangeTimer (JucerDocument& d) : doc (d) {} | |||
| void timerCallback() { doc.reloadFromDocument(); } | |||
| JucerDocument& doc; | |||
| }; | |||
| void JucerDocument::userEditedCpp() | |||
| { | |||
| if (userDocChangeTimer == nullptr) | |||
| userDocChangeTimer = new UserDocChangeTimer (*this); | |||
| userDocChangeTimer->startTimer (500); | |||
| } | |||
| void JucerDocument::beginTransaction() | |||
| { | |||
| getUndoManager().beginNewTransaction(); | |||
| } | |||
| void JucerDocument::beginTransaction (const String& name) | |||
| { | |||
| getUndoManager().beginNewTransaction (name); | |||
| } | |||
| void JucerDocument::timerCallback() | |||
| { | |||
| if (! Component::isMouseButtonDownAnywhere()) | |||
| { | |||
| stopTimer(); | |||
| beginTransaction(); | |||
| flushChangesToDocuments(); | |||
| } | |||
| } | |||
| void JucerDocument::codeDocumentTextInserted (const String&, int) { userEditedCpp(); } | |||
| void JucerDocument::codeDocumentTextDeleted (int, int) { userEditedCpp(); } | |||
| bool JucerDocument::perform (UndoableAction* const action, const String& actionName) | |||
| { | |||
| return undoManager.perform (action, actionName); | |||
| } | |||
| void JucerDocument::refreshAllPropertyComps() | |||
| { | |||
| if (ComponentLayout* l = getComponentLayout()) | |||
| l->getSelectedSet().changed(); | |||
| for (int i = getNumPaintRoutines(); --i >= 0;) | |||
| { | |||
| getPaintRoutine (i)->getSelectedElements().changed(); | |||
| getPaintRoutine (i)->getSelectedPoints().changed(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void JucerDocument::setClassName (const String& newName) | |||
| { | |||
| if (newName != className | |||
| && CodeHelpers::makeValidIdentifier (newName, false, false, true).isNotEmpty()) | |||
| { | |||
| className = CodeHelpers::makeValidIdentifier (newName, false, false, true); | |||
| changed(); | |||
| } | |||
| } | |||
| void JucerDocument::setComponentName (const String& newName) | |||
| { | |||
| if (newName != componentName) | |||
| { | |||
| componentName = newName; | |||
| changed(); | |||
| } | |||
| } | |||
| void JucerDocument::setParentClasses (const String& classes) | |||
| { | |||
| if (classes != parentClasses) | |||
| { | |||
| StringArray parentClassLines; | |||
| parentClassLines.addTokens (classes, ",", String::empty); | |||
| parentClassLines.trim(); | |||
| parentClassLines.removeEmptyStrings(); | |||
| parentClassLines.removeDuplicates (false); | |||
| for (int i = parentClassLines.size(); --i >= 0;) | |||
| { | |||
| String s (parentClassLines[i]); | |||
| String type; | |||
| if (s.startsWith ("public ") | |||
| || s.startsWith ("protected ") | |||
| || s.startsWith ("private ")) | |||
| { | |||
| type = s.upToFirstOccurrenceOf (" ", true, false); | |||
| s = s.fromFirstOccurrenceOf (" ", false, false); | |||
| if (s.trim().isEmpty()) | |||
| type = s = String::empty; | |||
| } | |||
| s = type + CodeHelpers::makeValidIdentifier (s.trim(), false, false, true); | |||
| parentClassLines.set (i, s); | |||
| } | |||
| parentClasses = parentClassLines.joinIntoString (", "); | |||
| changed(); | |||
| } | |||
| } | |||
| void JucerDocument::setConstructorParams (const String& newParams) | |||
| { | |||
| if (constructorParams != newParams) | |||
| { | |||
| constructorParams = newParams; | |||
| changed(); | |||
| } | |||
| } | |||
| void JucerDocument::setVariableInitialisers (const String& newInitlialisers) | |||
| { | |||
| if (variableInitialisers != newInitlialisers) | |||
| { | |||
| variableInitialisers = newInitlialisers; | |||
| changed(); | |||
| } | |||
| } | |||
| void JucerDocument::setFixedSize (const bool isFixed) | |||
| { | |||
| if (fixedSize != isFixed) | |||
| { | |||
| fixedSize = isFixed; | |||
| changed(); | |||
| } | |||
| } | |||
| void JucerDocument::setInitialSize (int w, int h) | |||
| { | |||
| w = jmax (1, w); | |||
| h = jmax (1, h); | |||
| if (initialWidth != w || initialHeight != h) | |||
| { | |||
| initialWidth = w; | |||
| initialHeight = h; | |||
| changed(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| bool JucerDocument::isSnapActive (const bool disableIfCtrlKeyDown) const noexcept | |||
| { | |||
| return snapActive != (disableIfCtrlKeyDown && ModifierKeys::getCurrentModifiers().isCtrlDown()); | |||
| } | |||
| int JucerDocument::snapPosition (int pos) const noexcept | |||
| { | |||
| if (isSnapActive (true)) | |||
| { | |||
| jassert (snapGridPixels > 0); | |||
| pos = ((pos + snapGridPixels * 1024 + snapGridPixels / 2) / snapGridPixels - 1024) * snapGridPixels; | |||
| } | |||
| return pos; | |||
| } | |||
| void JucerDocument::setSnappingGrid (const int numPixels, const bool active, const bool shown) | |||
| { | |||
| if (numPixels != snapGridPixels | |||
| || active != snapActive | |||
| || shown != snapShown) | |||
| { | |||
| snapGridPixels = numPixels; | |||
| snapActive = active; | |||
| snapShown = shown; | |||
| changed(); | |||
| } | |||
| } | |||
| void JucerDocument::setComponentOverlayOpacity (const float alpha) | |||
| { | |||
| if (alpha != componentOverlayOpacity) | |||
| { | |||
| componentOverlayOpacity = alpha; | |||
| changed(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void JucerDocument::addMethod (const String& base, const String& returnVal, const String& method, const String& initialContent, | |||
| StringArray& baseClasses, StringArray& returnValues, StringArray& methods, StringArray& initialContents) | |||
| { | |||
| baseClasses.add (base); | |||
| returnValues.add (returnVal); | |||
| methods.add (method); | |||
| initialContents.add (initialContent); | |||
| } | |||
| void JucerDocument::getOptionalMethods (StringArray& baseClasses, | |||
| StringArray& returnValues, | |||
| StringArray& methods, | |||
| StringArray& initialContents) const | |||
| { | |||
| addMethod ("Component", "void", "visibilityChanged()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "moved()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "parentHierarchyChanged()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "parentSizeChanged()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "lookAndFeelChanged()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "bool", "hitTest (int x, int y)", "return true;", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "broughtToFront()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "filesDropped (const StringArray& filenames, int mouseX, int mouseY)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "handleCommandMessage (int commandId)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "childrenChanged()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "enablementChanged()", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseMove (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseEnter (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseExit (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseDown (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseDrag (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseUp (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseDoubleClick (const MouseEvent& e)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "bool", "keyPressed (const KeyPress& key)", "return false; // Return true if your handler uses this key event, or false to allow it to be passed-on.", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "bool", "keyStateChanged (const bool isKeyDown)", "return false; // Return true if your handler uses this key event, or false to allow it to be passed-on.", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "modifierKeysChanged (const ModifierKeys& modifiers)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "focusGained (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "focusLost (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "focusOfChildComponentChanged (FocusChangeType cause)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "modifierKeysChanged (const ModifierKeys& modifiers)", "", baseClasses, returnValues, methods, initialContents); | |||
| addMethod ("Component", "void", "inputAttemptWhenModal()", "", baseClasses, returnValues, methods, initialContents); | |||
| } | |||
| void JucerDocument::setOptionalMethodEnabled (const String& methodSigniture, const bool enable) | |||
| { | |||
| if (enable) | |||
| activeExtraMethods.addIfNotAlreadyThere (methodSigniture); | |||
| else | |||
| activeExtraMethods.removeString (methodSigniture); | |||
| changed(); | |||
| } | |||
| bool JucerDocument::isOptionalMethodEnabled (const String& sig) const noexcept | |||
| { | |||
| return activeExtraMethods.contains (sig); | |||
| } | |||
| void JucerDocument::addExtraClassProperties (PropertyPanel&) | |||
| { | |||
| } | |||
| //============================================================================== | |||
| const char* const JucerDocument::jucerCompXmlTag = "JUCER_COMPONENT"; | |||
| XmlElement* JucerDocument::createXml() const | |||
| { | |||
| XmlElement* doc = new XmlElement (jucerCompXmlTag); | |||
| doc->setAttribute ("documentType", getTypeName()); | |||
| doc->setAttribute ("className", className); | |||
| if (templateFile.trim().isNotEmpty()) | |||
| doc->setAttribute ("template", templateFile); | |||
| doc->setAttribute ("componentName", componentName); | |||
| doc->setAttribute ("parentClasses", parentClasses); | |||
| doc->setAttribute ("constructorParams", constructorParams); | |||
| doc->setAttribute ("variableInitialisers", variableInitialisers); | |||
| doc->setAttribute ("snapPixels", snapGridPixels); | |||
| doc->setAttribute ("snapActive", snapActive); | |||
| doc->setAttribute ("snapShown", snapShown); | |||
| doc->setAttribute ("overlayOpacity", (double) componentOverlayOpacity); | |||
| doc->setAttribute ("fixedSize", fixedSize); | |||
| doc->setAttribute ("initialWidth", initialWidth); | |||
| doc->setAttribute ("initialHeight", initialHeight); | |||
| if (activeExtraMethods.size() > 0) | |||
| { | |||
| XmlElement* extraMethods = new XmlElement ("METHODS"); | |||
| doc->addChildElement (extraMethods); | |||
| for (int i = 0; i < activeExtraMethods.size(); ++i) | |||
| { | |||
| XmlElement* e = new XmlElement ("METHOD"); | |||
| extraMethods ->addChildElement (e); | |||
| e->setAttribute ("name", activeExtraMethods[i]); | |||
| } | |||
| } | |||
| return doc; | |||
| } | |||
| bool JucerDocument::loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (jucerCompXmlTag) | |||
| && getTypeName().equalsIgnoreCase (xml.getStringAttribute ("documentType"))) | |||
| { | |||
| className = xml.getStringAttribute ("className", defaultClassName); | |||
| templateFile = xml.getStringAttribute ("template", String::empty); | |||
| componentName = xml.getStringAttribute ("componentName", String::empty); | |||
| parentClasses = xml.getStringAttribute ("parentClasses", defaultParentClasses); | |||
| constructorParams = xml.getStringAttribute ("constructorParams", String::empty); | |||
| variableInitialisers = xml.getStringAttribute ("variableInitialisers", String::empty); | |||
| fixedSize = xml.getBoolAttribute ("fixedSize", false); | |||
| initialWidth = xml.getIntAttribute ("initialWidth", 300); | |||
| initialHeight = xml.getIntAttribute ("initialHeight", 200); | |||
| snapGridPixels = xml.getIntAttribute ("snapPixels", snapGridPixels); | |||
| snapActive = xml.getBoolAttribute ("snapActive", snapActive); | |||
| snapShown = xml.getBoolAttribute ("snapShown", snapShown); | |||
| componentOverlayOpacity = (float) xml.getDoubleAttribute ("overlayOpacity", 0.0); | |||
| activeExtraMethods.clear(); | |||
| if (XmlElement* const methods = xml.getChildByName ("METHODS")) | |||
| { | |||
| forEachXmlChildElementWithTagName (*methods, e, "METHOD") | |||
| { | |||
| activeExtraMethods.addIfNotAlreadyThere (e->getStringAttribute ("name")); | |||
| } | |||
| } | |||
| activeExtraMethods.trim(); | |||
| activeExtraMethods.removeEmptyStrings(); | |||
| changed(); | |||
| getUndoManager().clearUndoHistory(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| void JucerDocument::fillInGeneratedCode (GeneratedCode& code) const | |||
| { | |||
| code.className = className; | |||
| code.componentName = componentName; | |||
| code.parentClasses = parentClasses; | |||
| code.constructorParams = constructorParams; | |||
| code.initialisers.addLines (variableInitialisers); | |||
| if (! componentName.isEmpty()) | |||
| code.parentClassInitialiser = "Component (" + quotedString (code.componentName) + ")"; | |||
| // call these now, just to make sure they're the first two methods in the list. | |||
| code.getCallbackCode (String::empty, "void", "paint (Graphics& g)", false) | |||
| << "//[UserPrePaint] Add your own custom painting code here..\n//[/UserPrePaint]\n\n"; | |||
| code.getCallbackCode (String::empty, "void", "resized()", false); | |||
| if (ComponentLayout* l = getComponentLayout()) | |||
| l->fillInGeneratedCode (code); | |||
| fillInPaintCode (code); | |||
| ScopedPointer<XmlElement> e (createXml()); | |||
| jassert (e != nullptr); | |||
| code.jucerMetadata = e->createDocument (String::empty, false, false); | |||
| resources.fillInGeneratedCode (code); | |||
| code.constructorCode | |||
| << "\n//[UserPreSize]\n" | |||
| "//[/UserPreSize]\n"; | |||
| if (initialWidth > 0 || initialHeight > 0) | |||
| code.constructorCode | |||
| << "\nsetSize (" << initialWidth << ", " << initialHeight << ");\n"; | |||
| code.getCallbackCode (String::empty, "void", "paint (Graphics& g)", false) | |||
| << "//[UserPaint] Add your own custom painting code here..\n//[/UserPaint]"; | |||
| code.getCallbackCode (String::empty, "void", "resized()", false) | |||
| << "//[UserResized] Add your own custom resize handling here..\n//[/UserResized]"; | |||
| // add optional methods | |||
| StringArray baseClasses, returnValues, methods, initialContents; | |||
| getOptionalMethods (baseClasses, returnValues, methods, initialContents); | |||
| for (int i = 0; i < methods.size(); ++i) | |||
| { | |||
| if (isOptionalMethodEnabled (methods[i])) | |||
| { | |||
| String& s = code.getCallbackCode (baseClasses[i], returnValues[i], methods[i], false); | |||
| if (! s.contains ("//[")) | |||
| { | |||
| String userCommentTag ("UserCode_"); | |||
| userCommentTag += methods[i].upToFirstOccurrenceOf ("(", false, false).trim(); | |||
| s << "\n//[" | |||
| << userCommentTag | |||
| << "] -- Add your code here...\n" | |||
| << initialContents[i]; | |||
| if (initialContents[i].isNotEmpty() && ! initialContents[i].endsWithChar ('\n')) | |||
| s << '\n'; | |||
| s << "//[/" | |||
| << userCommentTag | |||
| << "]\n"; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void JucerDocument::fillInPaintCode (GeneratedCode& code) const | |||
| { | |||
| for (int i = 0; i < getNumPaintRoutines(); ++i) | |||
| getPaintRoutine (i) | |||
| ->fillInGeneratedCode (code, code.getCallbackCode (String::empty, "void", "paint (Graphics& g)", false)); | |||
| } | |||
| void JucerDocument::setTemplateFile (const String& newFile) | |||
| { | |||
| if (templateFile != newFile) | |||
| { | |||
| templateFile = newFile; | |||
| changed(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| bool JucerDocument::findTemplateFiles (String& headerContent, String& cppContent) const | |||
| { | |||
| if (templateFile.isNotEmpty()) | |||
| { | |||
| const File f (getCppFile().getSiblingFile (templateFile)); | |||
| const File templateCpp (f.withFileExtension (".cpp")); | |||
| const File templateH (f.withFileExtension (".h")); | |||
| headerContent = templateH.loadFileAsString(); | |||
| cppContent = templateCpp.loadFileAsString(); | |||
| if (headerContent.isNotEmpty() && cppContent.isNotEmpty()) | |||
| return true; | |||
| } | |||
| headerContent = BinaryData::jucer_ComponentTemplate_h; | |||
| cppContent = BinaryData::jucer_ComponentTemplate_cpp; | |||
| return true; | |||
| } | |||
| bool JucerDocument::flushChangesToDocuments() | |||
| { | |||
| String headerTemplate, cppTemplate; | |||
| if (! findTemplateFiles (headerTemplate, cppTemplate)) | |||
| return false; | |||
| GeneratedCode generated (this); | |||
| fillInGeneratedCode (generated); | |||
| const File headerFile (getHeaderFile()); | |||
| generated.includeFilesCPP.insert (0, headerFile.getFileName()); | |||
| OpenDocumentManager& odm = IntrojucerApp::getApp().openDocumentManager; | |||
| if (SourceCodeDocument* header = dynamic_cast <SourceCodeDocument*> (odm.openFile (nullptr, getHeaderFile()))) | |||
| { | |||
| String existingHeader (header->getCodeDocument().getAllContent()); | |||
| String existingCpp (cpp->getCodeDocument().getAllContent()); | |||
| generated.applyToCode (headerTemplate, headerFile.getFileNameWithoutExtension(), false, existingHeader); | |||
| generated.applyToCode (cppTemplate, headerFile.getFileNameWithoutExtension(), false, existingCpp); | |||
| header->getCodeDocument().applyChanges (headerTemplate); | |||
| cpp->getCodeDocument().applyChanges (cppTemplate); | |||
| } | |||
| return true; | |||
| } | |||
| bool JucerDocument::reloadFromDocument() | |||
| { | |||
| ScopedPointer<XmlElement> newXML (pullMetaDataFromCppFile (cpp->getCodeDocument().getAllContent())); | |||
| if (newXML == nullptr || ! newXML->hasTagName (jucerCompXmlTag)) | |||
| return false; | |||
| if (currentXML != nullptr && currentXML->isEquivalentTo (newXML, true)) | |||
| return true; | |||
| currentXML = newXML; | |||
| stopTimer(); | |||
| return loadFromXml (*currentXML); | |||
| } | |||
| XmlElement* JucerDocument::pullMetaDataFromCppFile (const String& cpp) | |||
| { | |||
| StringArray lines; | |||
| lines.addLines (cpp); | |||
| const int startLine = indexOfLineStartingWith (lines, "BEGIN_JUCER_METADATA", 0); | |||
| if (startLine > 0) | |||
| { | |||
| const int endLine = indexOfLineStartingWith (lines, "END_JUCER_METADATA", startLine); | |||
| if (endLine > startLine) | |||
| return XmlDocument::parse (lines.joinIntoString ("\n", startLine + 1, | |||
| endLine - startLine - 1)); | |||
| } | |||
| return nullptr; | |||
| } | |||
| bool JucerDocument::isValidJucerCppFile (const File& f) | |||
| { | |||
| if (f.hasFileExtension (".cpp")) | |||
| { | |||
| const ScopedPointer<XmlElement> xml (pullMetaDataFromCppFile (f.loadFileAsString())); | |||
| return xml != nullptr && xml->hasTagName (jucerCompXmlTag); | |||
| } | |||
| return false; | |||
| } | |||
| static JucerDocument* createDocument (SourceCodeDocument* cpp) | |||
| { | |||
| CodeDocument& codeDoc = cpp->getCodeDocument(); | |||
| ScopedPointer<XmlElement> xml (JucerDocument::pullMetaDataFromCppFile (codeDoc.getAllContent())); | |||
| if (xml == nullptr || ! xml->hasTagName (JucerDocument::jucerCompXmlTag)) | |||
| return nullptr; | |||
| const String docType (xml->getStringAttribute ("documentType")); | |||
| ScopedPointer<JucerDocument> newDoc; | |||
| if (docType.equalsIgnoreCase ("Button")) | |||
| newDoc = new ButtonDocument (cpp); | |||
| if (docType.equalsIgnoreCase ("Component") || docType.isEmpty()) | |||
| newDoc = new ComponentDocument (cpp); | |||
| if (newDoc != nullptr && newDoc->reloadFromDocument()) | |||
| return newDoc.release(); | |||
| return nullptr; | |||
| } | |||
| JucerDocument* JucerDocument::createForCppFile (Project* p, const File& file) | |||
| { | |||
| OpenDocumentManager& odm = IntrojucerApp::getApp().openDocumentManager; | |||
| if (SourceCodeDocument* cpp = dynamic_cast <SourceCodeDocument*> (odm.openFile (p, file))) | |||
| if (dynamic_cast <SourceCodeDocument*> (odm.openFile (p, file.withFileExtension (".h"))) != nullptr) | |||
| return createDocument (cpp); | |||
| return nullptr; | |||
| } | |||
| //============================================================================== | |||
| class JucerComponentDocument : public SourceCodeDocument | |||
| { | |||
| public: | |||
| JucerComponentDocument (Project* p, const File& f) | |||
| : SourceCodeDocument (p, f) | |||
| { | |||
| } | |||
| Component* createEditor() | |||
| { | |||
| ScopedPointer<JucerDocument> jucerDoc (JucerDocument::createForCppFile (getProject(), getFile())); | |||
| if (jucerDoc != nullptr) | |||
| return new JucerDocumentEditor (jucerDoc.release()); | |||
| return SourceCodeDocument::createEditor(); | |||
| } | |||
| class Type : public OpenDocumentManager::DocumentType | |||
| { | |||
| public: | |||
| Type() {} | |||
| bool canOpenFile (const File& f) { return JucerDocument::isValidJucerCppFile (f); } | |||
| Document* openFile (Project* p, const File& f) { return new JucerComponentDocument (p, f); } | |||
| }; | |||
| }; | |||
| OpenDocumentManager::DocumentType* createGUIDocumentType() | |||
| { | |||
| return new JucerComponentDocument::Type(); | |||
| } | |||
| //============================================================================== | |||
| class JucerFileWizard : public NewFileWizard::Type | |||
| { | |||
| public: | |||
| JucerFileWizard() {} | |||
| String getName() { return "GUI Component"; } | |||
| void createNewFile (Project::Item parent) | |||
| { | |||
| const File newFile (askUserToChooseNewFile (String (defaultClassName) + ".h", "*.h;*.cpp", parent)); | |||
| if (newFile != File::nonexistent) | |||
| { | |||
| const File headerFile (newFile.withFileExtension (".h")); | |||
| const File cppFile (newFile.withFileExtension (".cpp")); | |||
| headerFile.replaceWithText (String::empty); | |||
| cppFile.replaceWithText (String::empty); | |||
| OpenDocumentManager& odm = IntrojucerApp::getApp().openDocumentManager; | |||
| if (SourceCodeDocument* cpp = dynamic_cast <SourceCodeDocument*> (odm.openFile (nullptr, cppFile))) | |||
| { | |||
| if (SourceCodeDocument* header = dynamic_cast <SourceCodeDocument*> (odm.openFile (nullptr, headerFile))) | |||
| { | |||
| ScopedPointer<JucerDocument> jucerDoc (new ComponentDocument (cpp)); | |||
| if (jucerDoc != nullptr) | |||
| { | |||
| jucerDoc->flushChangesToDocuments(); | |||
| jucerDoc = nullptr; | |||
| cpp->save(); | |||
| header->save(); | |||
| odm.closeDocument (cpp, true); | |||
| odm.closeDocument (header, true); | |||
| parent.addFile (headerFile, 0, true); | |||
| parent.addFile (cppFile, 0, true); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }; | |||
| NewFileWizard::Type* createGUIComponentWizard() | |||
| { | |||
| return new JucerFileWizard(); | |||
| } | |||
| @@ -0,0 +1,176 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_JUCERDOCUMENT_JUCEHEADER__ | |||
| #define __JUCER_JUCERDOCUMENT_JUCEHEADER__ | |||
| #include "../Application/jucer_OpenDocumentManager.h" | |||
| #include "../Code Editor/jucer_SourceCodeEditor.h" | |||
| #include "components/jucer_ComponentTypeHandler.h" | |||
| #include "jucer_PaintRoutine.h" | |||
| #include "jucer_ComponentLayout.h" | |||
| #include "jucer_BinaryResources.h" | |||
| //============================================================================== | |||
| class JucerDocument : public ChangeBroadcaster, | |||
| private Timer, | |||
| private CodeDocument::Listener | |||
| { | |||
| public: | |||
| JucerDocument (SourceCodeDocument* cpp); | |||
| ~JucerDocument(); | |||
| static bool isValidJucerCppFile (const File&); | |||
| static XmlElement* pullMetaDataFromCppFile (const String& cpp); | |||
| static JucerDocument* createForCppFile (Project* project, const File&); | |||
| void changed(); | |||
| void beginTransaction(); | |||
| void beginTransaction (const String& name); | |||
| virtual JucerDocument* createCopy() = 0; | |||
| virtual String getTypeName() const = 0; | |||
| SourceCodeDocument& getCppDocument() const { return *cpp; } | |||
| File getCppFile() const { return cpp->getFile(); } | |||
| File getHeaderFile() const { return getCppFile().withFileExtension (".h"); } | |||
| bool flushChangesToDocuments(); | |||
| bool reloadFromDocument(); | |||
| //============================================================================== | |||
| UndoManager& getUndoManager() noexcept { return undoManager; } | |||
| bool perform (UndoableAction* const action, const String& actionName); | |||
| void refreshAllPropertyComps(); | |||
| //============================================================================== | |||
| const String& getClassName() const noexcept { return className; } | |||
| void setClassName (const String& newName); | |||
| const String& getComponentName() const noexcept { return componentName; } | |||
| void setComponentName (const String& newName); | |||
| String getParentClassString() const { return parentClasses; } | |||
| void setParentClasses (const String& classes); | |||
| String getConstructorParams() const { return constructorParams; } | |||
| void setConstructorParams (const String& newParams); | |||
| String getVariableInitialisers() const { return variableInitialisers; } | |||
| void setVariableInitialisers (const String& newInitlialisers); | |||
| void setFixedSize (const bool isFixed); | |||
| bool isFixedSize() const noexcept { return fixedSize; } | |||
| void setInitialSize (int w, int h); | |||
| int getInitialWidth() const noexcept { return initialWidth; } | |||
| int getInitialHeight() const noexcept { return initialHeight; } | |||
| //============================================================================== | |||
| virtual int getNumPaintRoutines() const = 0; | |||
| virtual StringArray getPaintRoutineNames() const = 0; | |||
| virtual PaintRoutine* getPaintRoutine (const int index) const = 0; | |||
| virtual ComponentLayout* getComponentLayout() const = 0; | |||
| virtual Component* createTestComponent (const bool alwaysFillBackground) = 0; | |||
| virtual void addExtraClassProperties (PropertyPanel&); | |||
| //============================================================================== | |||
| virtual void getOptionalMethods (StringArray& baseClasses, | |||
| StringArray& returnValues, | |||
| StringArray& methods, | |||
| StringArray& initialContents) const; | |||
| void setOptionalMethodEnabled (const String& methodSigniture, const bool enable); | |||
| bool isOptionalMethodEnabled (const String& methodSigniture) const noexcept; | |||
| //============================================================================== | |||
| BinaryResources& getResources() noexcept { return resources; } | |||
| //============================================================================== | |||
| void setSnappingGrid (const int numPixels, const bool active, const bool shown); | |||
| int getSnappingGridSize() const noexcept { return snapGridPixels; } | |||
| bool isSnapActive (const bool disableIfCtrlKeyDown) const noexcept; | |||
| bool isSnapShown() const noexcept { return snapShown; } | |||
| int snapPosition (int pos) const noexcept; | |||
| //============================================================================== | |||
| void setComponentOverlayOpacity (const float alpha); | |||
| float getComponentOverlayOpacity() const noexcept { return componentOverlayOpacity; } | |||
| //============================================================================== | |||
| static const char* const jucerCompXmlTag; | |||
| bool findTemplateFiles (String& templateH, String& templateCpp) const; | |||
| String getTemplateFile() const { return templateFile; } | |||
| void setTemplateFile (const String&); | |||
| protected: | |||
| SourceCodeDocument* cpp; | |||
| String className, componentName, templateFile; | |||
| String parentClasses, constructorParams, variableInitialisers; | |||
| bool fixedSize; | |||
| int initialWidth, initialHeight; | |||
| BinaryResources resources; | |||
| virtual XmlElement* createXml() const; | |||
| virtual bool loadFromXml (const XmlElement&); | |||
| virtual void fillInGeneratedCode (GeneratedCode&) const; | |||
| virtual void fillInPaintCode (GeneratedCode&) const; | |||
| static void addMethod (const String& base, const String& returnVal, | |||
| const String& method, const String& initialContent, | |||
| StringArray& baseClasses, StringArray& returnValues, | |||
| StringArray& methods, StringArray& initialContents); | |||
| private: | |||
| UndoManager undoManager; | |||
| int snapGridPixels; | |||
| bool snapActive, snapShown; | |||
| float componentOverlayOpacity; | |||
| StringArray activeExtraMethods; | |||
| ScopedPointer<XmlElement> currentXML; | |||
| ScopedPointer<Timer> userDocChangeTimer; | |||
| void timerCallback(); | |||
| void codeDocumentTextInserted (const String& newText, int insertIndex); | |||
| void codeDocumentTextDeleted (int startIndex, int endIndex); | |||
| void userEditedCpp(); | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JucerDocument); | |||
| }; | |||
| #endif // __JUCER_JUCERDOCUMENT_JUCEHEADER__ | |||
| @@ -0,0 +1,163 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../jucer_Headers.h" | |||
| #include "jucer_JucerDocument.h" | |||
| #include "components/jucer_ComponentUndoableAction.h" | |||
| #include "properties/jucer_JustificationProperty.h" | |||
| #include "properties/jucer_FontPropertyComponent.h" | |||
| #include "properties/jucer_ComponentBooleanProperty.h" | |||
| #include "properties/jucer_ComponentChoiceProperty.h" | |||
| #include "properties/jucer_ComponentTextProperty.h" | |||
| #include "properties/jucer_ComponentColourProperty.h" | |||
| #include "properties/jucer_FilePropertyComponent.h" | |||
| #include "paintelements/jucer_ImageResourceProperty.h" | |||
| #include "jucer_ObjectTypes.h" | |||
| #include "paintelements/jucer_PaintElementUndoableAction.h" | |||
| #include "paintelements/jucer_PaintElementRectangle.h" | |||
| #include "paintelements/jucer_PaintElementRoundedRectangle.h" | |||
| #include "paintelements/jucer_PaintElementImage.h" | |||
| #include "paintelements/jucer_PaintElementEllipse.h" | |||
| #include "paintelements/jucer_PaintElementPath.h" | |||
| #include "paintelements/jucer_PaintElementText.h" | |||
| #include "paintelements/jucer_PaintElementGroup.h" | |||
| #include "components/jucer_ButtonHandler.h" | |||
| #include "components/jucer_TextButtonHandler.h" | |||
| #include "components/jucer_ToggleButtonHandler.h" | |||
| #include "components/jucer_SliderHandler.h" | |||
| #include "components/jucer_LabelHandler.h" | |||
| #include "components/jucer_TextEditorHandler.h" | |||
| #include "components/jucer_ComboBoxHandler.h" | |||
| #include "components/jucer_GroupComponentHandler.h" | |||
| #include "components/jucer_JucerComponentHandler.h" | |||
| #include "components/jucer_HyperlinkButtonHandler.h" | |||
| #include "components/jucer_ViewportHandler.h" | |||
| #include "components/jucer_TabbedComponentHandler.h" | |||
| #include "components/jucer_TreeViewHandler.h" | |||
| #include "components/jucer_GenericComponentHandler.h" | |||
| #include "components/jucer_ImageButtonHandler.h" | |||
| namespace ObjectTypes | |||
| { | |||
| static const char* const elementNames[] = | |||
| { | |||
| "Rectangle", | |||
| "Rounded Rectangle", | |||
| "Ellipse", | |||
| "Path", | |||
| "Image", | |||
| "Text", | |||
| nullptr | |||
| }; | |||
| const char** const elementTypeNames = (const char**) elementNames; | |||
| const int numElementTypes = (sizeof (elementNames) / sizeof (elementNames[0])) - 1; | |||
| PaintElement* createNewElement (const int index, PaintRoutine* owner) | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: return new PaintElementRectangle (owner); | |||
| case 1: return new PaintElementRoundedRectangle (owner); | |||
| case 2: return new PaintElementEllipse (owner); | |||
| case 3: return new PaintElementPath (owner); | |||
| case 4: return new PaintElementImage (owner); | |||
| case 5: return new PaintElementText (owner); | |||
| default: jassertfalse; break; | |||
| } | |||
| return nullptr; | |||
| } | |||
| PaintElement* createNewImageElement (PaintRoutine* owner) | |||
| { | |||
| return new PaintElementImage (owner); | |||
| } | |||
| PaintElement* createElementForXml (const XmlElement* const e, PaintRoutine* const owner) | |||
| { | |||
| jassert (e != nullptr); | |||
| ScopedPointer<PaintElement> pe; | |||
| if (e->hasTagName (PaintElementRectangle::getTagName())) pe = new PaintElementRectangle (owner); | |||
| else if (e->hasTagName (PaintElementRoundedRectangle::getTagName())) pe = new PaintElementRoundedRectangle (owner); | |||
| else if (e->hasTagName (PaintElementEllipse::getTagName())) pe = new PaintElementEllipse (owner); | |||
| else if (e->hasTagName (PaintElementImage::getTagName())) pe = new PaintElementImage (owner); | |||
| else if (e->hasTagName (PaintElementPath::getTagName())) pe = new PaintElementPath (owner); | |||
| else if (e->hasTagName (PaintElementText::getTagName())) pe = new PaintElementText (owner); | |||
| else if (e->hasTagName (PaintElementGroup::getTagName())) pe = new PaintElementGroup (owner); | |||
| if (pe != nullptr && pe->loadFromXml (*e)) | |||
| return pe.release(); | |||
| jassertfalse; | |||
| return nullptr; | |||
| } | |||
| //============================================================================== | |||
| static TextButtonHandler textButton; | |||
| static ToggleButtonHandler toggleButton; | |||
| static SliderHandler slider; | |||
| static LabelHandler label; | |||
| static TextEditorHandler textEditor; | |||
| static ComboBoxHandler comboBox; | |||
| static JucerComponentHandler jucerCompHandler; | |||
| static GroupComponentHandler group; | |||
| static HyperlinkButtonHandler hyperlink; | |||
| static ViewportHandler viewport; | |||
| static TabbedComponentHandler tabbedComp; | |||
| static TreeViewHandler treeview; | |||
| static GenericComponentHandler genericHandler; | |||
| static ImageButtonHandler imageButtonHandler; | |||
| static ComponentTypeHandler* const compTypes[] = | |||
| { | |||
| &textButton, | |||
| &toggleButton, | |||
| &slider, | |||
| &label, | |||
| &textEditor, | |||
| &comboBox, | |||
| &group, | |||
| &jucerCompHandler, | |||
| &hyperlink, | |||
| &viewport, | |||
| &tabbedComp, | |||
| &treeview, | |||
| &genericHandler, | |||
| &imageButtonHandler, | |||
| nullptr | |||
| }; | |||
| ComponentTypeHandler** const componentTypeHandlers = (ComponentTypeHandler**) compTypes; | |||
| const int numComponentTypes = numElementsInArray (compTypes) - 1; | |||
| } | |||
| @@ -0,0 +1,50 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_OBJECTTYPES_JUCEHEADER__ | |||
| #define __JUCER_OBJECTTYPES_JUCEHEADER__ | |||
| #include "jucer_JucerDocument.h" | |||
| #include "paintelements/jucer_PaintElement.h" | |||
| namespace ObjectTypes | |||
| { | |||
| //============================================================================== | |||
| // Component types | |||
| extern ComponentTypeHandler** const componentTypeHandlers; | |||
| extern const int numComponentTypes; | |||
| //============================================================================== | |||
| // Element types | |||
| extern const char** const elementTypeNames; | |||
| extern const int numElementTypes; | |||
| PaintElement* createNewElement (const int index, PaintRoutine* owner); | |||
| PaintElement* createNewImageElement (PaintRoutine* owner); | |||
| PaintElement* createElementForXml (const XmlElement* const e, PaintRoutine* const owner); | |||
| } | |||
| #endif // __JUCER_OBJECTTYPES_JUCEHEADER__ | |||
| @@ -0,0 +1,585 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../jucer_Headers.h" | |||
| #include "jucer_PaintRoutine.h" | |||
| #include "jucer_JucerDocument.h" | |||
| #include "jucer_ObjectTypes.h" | |||
| #include "paintelements/jucer_PaintElementUndoableAction.h" | |||
| #include "paintelements/jucer_PaintElementPath.h" | |||
| #include "paintelements/jucer_PaintElementImage.h" | |||
| #include "paintelements/jucer_PaintElementGroup.h" | |||
| #include "ui/jucer_JucerDocumentEditor.h" | |||
| //============================================================================== | |||
| PaintRoutine::PaintRoutine() | |||
| : document (nullptr), | |||
| backgroundColour (Colours::white) | |||
| { | |||
| clear(); | |||
| } | |||
| PaintRoutine::~PaintRoutine() | |||
| { | |||
| elements.clear(); // do this explicitly before the scalar destructor because these | |||
| // objects will be listeners on this object | |||
| } | |||
| //============================================================================== | |||
| void PaintRoutine::changed() | |||
| { | |||
| if (document != nullptr) | |||
| document->changed(); | |||
| } | |||
| bool PaintRoutine::perform (UndoableAction* action, const String& actionName) | |||
| { | |||
| if (document != nullptr) | |||
| return document->getUndoManager().perform (action, actionName); | |||
| ScopedPointer<UndoableAction> deleter (action); | |||
| action->perform(); | |||
| return false; | |||
| } | |||
| void PaintRoutine::setBackgroundColour (const Colour& newColour) noexcept | |||
| { | |||
| backgroundColour = newColour; | |||
| changed(); | |||
| } | |||
| void PaintRoutine::clear() | |||
| { | |||
| if (elements.size() > 0) | |||
| { | |||
| elements.clear(); | |||
| changed(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class AddXmlElementAction : public UndoableAction | |||
| { | |||
| public: | |||
| AddXmlElementAction (PaintRoutine& routine_, XmlElement* xml_) | |||
| : routine (routine_), xml (xml_) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| PaintElement* newElement = routine.addElementFromXml (*xml, -1, false); | |||
| jassert (newElement != nullptr); | |||
| indexAdded = routine.indexOfElement (newElement); | |||
| jassert (indexAdded >= 0); | |||
| return indexAdded >= 0; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| routine.removeElement (routine.getElement (indexAdded), false); | |||
| return true; | |||
| } | |||
| int getSizeInUnits() { return 10; } | |||
| int indexAdded; | |||
| private: | |||
| PaintRoutine& routine; | |||
| ScopedPointer<XmlElement> xml; | |||
| void showCorrectTab() const | |||
| { | |||
| if (JucerDocumentEditor* const ed = JucerDocumentEditor::getActiveDocumentHolder()) | |||
| ed->showGraphics (&routine); | |||
| } | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AddXmlElementAction) | |||
| }; | |||
| PaintElement* PaintRoutine::addElementFromXml (const XmlElement& xml, const int index, const bool undoable) | |||
| { | |||
| selectedPoints.deselectAll(); | |||
| if (undoable) | |||
| { | |||
| AddXmlElementAction* action = new AddXmlElementAction (*this, new XmlElement (xml)); | |||
| perform (action, "Add new element"); | |||
| return elements [action->indexAdded]; | |||
| } | |||
| else | |||
| { | |||
| if (PaintElement* const newElement = ObjectTypes::createElementForXml (&xml, this)) | |||
| { | |||
| elements.insert (index, newElement); | |||
| changed(); | |||
| return newElement; | |||
| } | |||
| } | |||
| return nullptr; | |||
| } | |||
| PaintElement* PaintRoutine::addNewElement (PaintElement* e, const int index, const bool undoable) | |||
| { | |||
| if (e != nullptr) | |||
| { | |||
| ScopedPointer<PaintElement> deleter (e); | |||
| ScopedPointer<XmlElement> xml (e->createXml()); | |||
| e = addElementFromXml (*xml, index, undoable); | |||
| } | |||
| return e; | |||
| } | |||
| //============================================================================== | |||
| class DeleteElementAction : public PaintElementUndoableAction <PaintElement> | |||
| { | |||
| public: | |||
| DeleteElementAction (PaintElement* const element) | |||
| : PaintElementUndoableAction <PaintElement> (element), | |||
| oldIndex (-1) | |||
| { | |||
| xml = element->createXml(); | |||
| oldIndex = routine.indexOfElement (element); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| routine.removeElement (getElement(), false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| PaintElement* newElement = routine.addElementFromXml (*xml, oldIndex, false); | |||
| showCorrectTab(); | |||
| return newElement != nullptr; | |||
| } | |||
| int getSizeInUnits() { return 10; } | |||
| private: | |||
| ScopedPointer<XmlElement> xml; | |||
| int oldIndex; | |||
| }; | |||
| void PaintRoutine::removeElement (PaintElement* element, const bool undoable) | |||
| { | |||
| if (elements.contains (element)) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new DeleteElementAction (element), | |||
| "Delete " + element->getTypeName()); | |||
| } | |||
| else | |||
| { | |||
| selectedElements.deselect (element); | |||
| selectedPoints.deselectAll(); | |||
| selectedPoints.changed (true); | |||
| selectedElements.changed (true); | |||
| elements.removeObject (element); | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class FrontOrBackElementAction : public PaintElementUndoableAction <PaintElement> | |||
| { | |||
| public: | |||
| FrontOrBackElementAction (PaintElement* const element, int newIndex_) | |||
| : PaintElementUndoableAction <PaintElement> (element), | |||
| newIndex (newIndex_) | |||
| { | |||
| oldIndex = routine.indexOfElement (element); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| PaintElement* e = routine.getElement (oldIndex); | |||
| routine.moveElementZOrder (oldIndex, newIndex); | |||
| newIndex = routine.indexOfElement (e); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| routine.moveElementZOrder (newIndex, oldIndex); | |||
| return true; | |||
| } | |||
| private: | |||
| int newIndex, oldIndex; | |||
| }; | |||
| void PaintRoutine::moveElementZOrder (int oldIndex, int newIndex) | |||
| { | |||
| jassert (elements [oldIndex] != nullptr); | |||
| if (oldIndex != newIndex && elements [oldIndex] != nullptr) | |||
| { | |||
| elements.move (oldIndex, newIndex); | |||
| changed(); | |||
| } | |||
| } | |||
| void PaintRoutine::elementToFront (PaintElement* element, const bool undoable) | |||
| { | |||
| if (element != nullptr && elements.contains (element)) | |||
| { | |||
| if (undoable) | |||
| perform (new FrontOrBackElementAction (element, -1), "Move elements to front"); | |||
| else | |||
| moveElementZOrder (elements.indexOf (element), -1); | |||
| } | |||
| } | |||
| void PaintRoutine::elementToBack (PaintElement* element, const bool undoable) | |||
| { | |||
| if (element != nullptr && elements.contains (element)) | |||
| { | |||
| if (undoable) | |||
| perform (new FrontOrBackElementAction (element, 0), "Move elements to back"); | |||
| else | |||
| moveElementZOrder (elements.indexOf (element), 0); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| const char* const PaintRoutine::clipboardXmlTag = "PAINTELEMENTS"; | |||
| void PaintRoutine::copySelectedToClipboard() | |||
| { | |||
| if (selectedElements.getNumSelected() == 0) | |||
| return; | |||
| XmlElement clip (clipboardXmlTag); | |||
| for (int i = 0; i < elements.size(); ++i) | |||
| { | |||
| PaintElement* const pe = elements.getUnchecked(i); | |||
| if (selectedElements.isSelected (pe)) | |||
| { | |||
| XmlElement* const e = pe->createXml(); | |||
| clip.addChildElement (e); | |||
| } | |||
| } | |||
| SystemClipboard::copyTextToClipboard (clip.createDocument (String::empty, false, false)); | |||
| } | |||
| void PaintRoutine::paste() | |||
| { | |||
| XmlDocument clip (SystemClipboard::getTextFromClipboard()); | |||
| ScopedPointer<XmlElement> doc (clip.getDocumentElement()); | |||
| if (doc != nullptr && doc->hasTagName (clipboardXmlTag)) | |||
| { | |||
| selectedElements.deselectAll(); | |||
| selectedPoints.deselectAll(); | |||
| forEachXmlChildElement (*doc, e) | |||
| if (PaintElement* newElement = addElementFromXml (*e, -1, true)) | |||
| selectedElements.addToSelection (newElement); | |||
| } | |||
| } | |||
| void PaintRoutine::deleteSelected() | |||
| { | |||
| const SelectedItemSet <PaintElement*> temp1 (selectedElements); | |||
| const SelectedItemSet <PathPoint*> temp2 (selectedPoints); | |||
| if (temp2.getNumSelected() > 0) | |||
| { | |||
| selectedPoints.deselectAll(); | |||
| selectedPoints.changed (true); // synchronous message to get rid of any property components | |||
| // if any points are selected, just delete them, and not the element, which may | |||
| // also be selected.. | |||
| for (int i = temp2.getNumSelected(); --i >= 0;) | |||
| temp2.getSelectedItem (i)->deleteFromPath(); | |||
| changed(); | |||
| } | |||
| else if (temp1.getNumSelected() > 0) | |||
| { | |||
| selectedElements.deselectAll(); | |||
| selectedElements.changed (true); | |||
| for (int i = temp1.getNumSelected(); --i >= 0;) | |||
| removeElement (temp1.getSelectedItem (i), true); | |||
| changed(); | |||
| } | |||
| } | |||
| void PaintRoutine::selectAll() | |||
| { | |||
| if (selectedPoints.getNumSelected() > 0) | |||
| { | |||
| if (const PaintElementPath* path = selectedPoints.getSelectedItem (0)->owner) | |||
| for (int i = 0; i < path->getNumPoints(); ++i) | |||
| selectedPoints.addToSelection (path->getPoint (i)); | |||
| } | |||
| else | |||
| { | |||
| for (int i = 0; i < elements.size(); ++i) | |||
| selectedElements.addToSelection (elements.getUnchecked (i)); | |||
| } | |||
| } | |||
| void PaintRoutine::selectedToFront() | |||
| { | |||
| const SelectedItemSet <PaintElement*> temp (selectedElements); | |||
| for (int i = temp.getNumSelected(); --i >= 0;) | |||
| elementToFront (temp.getSelectedItem(i), true); | |||
| } | |||
| void PaintRoutine::selectedToBack() | |||
| { | |||
| const SelectedItemSet <PaintElement*> temp (selectedElements); | |||
| for (int i = 0; i < temp.getNumSelected(); ++i) | |||
| elementToBack (temp.getSelectedItem(i), true); | |||
| } | |||
| void PaintRoutine::groupSelected() | |||
| { | |||
| PaintElementGroup::groupSelected (this); | |||
| } | |||
| void PaintRoutine::ungroupSelected() | |||
| { | |||
| const SelectedItemSet <PaintElement*> temp (selectedElements); | |||
| for (int i = 0; i < temp.getNumSelected(); ++i) | |||
| if (PaintElementGroup* const pg = dynamic_cast <PaintElementGroup*> (temp.getSelectedItem (i))) | |||
| pg->ungroup (true); | |||
| } | |||
| void PaintRoutine::bringLostItemsBackOnScreen (const Rectangle<int>& parentArea) | |||
| { | |||
| for (int i = 0; i < elements.size(); ++i) | |||
| { | |||
| PaintElement* const c = elements[i]; | |||
| Rectangle<int> r (c->getCurrentBounds (parentArea)); | |||
| if (! r.intersects (parentArea)) | |||
| { | |||
| r.setPosition (parentArea.getCentreX(), parentArea.getCentreY()); | |||
| c->setCurrentBounds (r, parentArea, true); | |||
| } | |||
| } | |||
| } | |||
| void PaintRoutine::startDragging (const Rectangle<int>& parentArea) | |||
| { | |||
| for (int i = 0; i < elements.size(); ++i) | |||
| { | |||
| PaintElement* const c = elements[i]; | |||
| Rectangle<int> r (c->getCurrentBounds (parentArea)); | |||
| c->getProperties().set ("xDragStart", r.getX()); | |||
| c->getProperties().set ("yDragStart", r.getY()); | |||
| } | |||
| getDocument()->beginTransaction(); | |||
| } | |||
| void PaintRoutine::dragSelectedComps (int dx, int dy, const Rectangle<int>& parentArea) | |||
| { | |||
| getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| if (document != nullptr && selectedElements.getNumSelected() > 1) | |||
| { | |||
| dx = document->snapPosition (dx); | |||
| dy = document->snapPosition (dy); | |||
| } | |||
| for (int i = 0; i < selectedElements.getNumSelected(); ++i) | |||
| { | |||
| PaintElement* const c = selectedElements.getSelectedItem (i); | |||
| const int startX = c->getProperties() ["xDragStart"]; | |||
| const int startY = c->getProperties() ["yDragStart"]; | |||
| Rectangle<int> r (c->getCurrentBounds (parentArea)); | |||
| if (document != nullptr && selectedElements.getNumSelected() == 1) | |||
| { | |||
| r.setPosition (document->snapPosition (startX + dx), | |||
| document->snapPosition (startY + dy)); | |||
| } | |||
| else | |||
| { | |||
| r.setPosition (startX + dx, | |||
| startY + dy); | |||
| } | |||
| c->setCurrentBounds (r, parentArea, true); | |||
| } | |||
| changed(); | |||
| } | |||
| void PaintRoutine::endDragging() | |||
| { | |||
| getDocument()->beginTransaction(); | |||
| } | |||
| //============================================================================== | |||
| void PaintRoutine::fillWithBackground (Graphics& g, const bool drawOpaqueBackground) | |||
| { | |||
| if ((! backgroundColour.isOpaque()) && drawOpaqueBackground) | |||
| { | |||
| g.fillCheckerBoard (Rectangle<int> (0, 0, g.getClipBounds().getRight(), g.getClipBounds().getBottom()), | |||
| 50, 50, | |||
| Colour (0xffdddddd).overlaidWith (backgroundColour), | |||
| Colour (0xffffffff).overlaidWith (backgroundColour)); | |||
| } | |||
| else | |||
| { | |||
| g.fillAll (backgroundColour); | |||
| } | |||
| } | |||
| void PaintRoutine::drawElements (Graphics& g, const Rectangle<int>& relativeTo) | |||
| { | |||
| Component temp; | |||
| temp.setBounds (relativeTo); | |||
| for (int i = 0; i < elements.size(); ++i) | |||
| elements.getUnchecked (i)->draw (g, getDocument()->getComponentLayout(), relativeTo); | |||
| } | |||
| //============================================================================== | |||
| void PaintRoutine::dropImageAt (const File& f, int x, int y) | |||
| { | |||
| ScopedPointer<Drawable> d (Drawable::createFromImageFile (f)); | |||
| if (d != nullptr) | |||
| { | |||
| Rectangle<float> bounds (d->getDrawableBounds()); | |||
| d = nullptr; | |||
| PaintElement* newElement | |||
| = addNewElement (ObjectTypes::createNewImageElement (this), -1, true); | |||
| if (PaintElementImage* pei = dynamic_cast <PaintElementImage*> (newElement)) | |||
| { | |||
| String resourceName (getDocument()->getResources().findUniqueName (f.getFileName())); | |||
| if (const BinaryResources::BinaryResource* existingResource = getDocument()->getResources().getResourceForFile (f)) | |||
| { | |||
| resourceName = existingResource->name; | |||
| } | |||
| else | |||
| { | |||
| MemoryBlock data; | |||
| f.loadFileAsData (data); | |||
| getDocument()->getResources().add (resourceName, f.getFullPathName(), data); | |||
| } | |||
| pei->setResource (resourceName, true); | |||
| const int imageW = (int) (bounds.getRight() + 0.999f); | |||
| const int imageH = (int) (bounds.getBottom() + 0.999f); | |||
| RelativePositionedRectangle pr; | |||
| pr.rect.setX (x - imageW / 2); | |||
| pr.rect.setY (y - imageH / 2); | |||
| pr.rect.setWidth (imageW); | |||
| pr.rect.setHeight (imageH); | |||
| pei->setPosition (pr, true); | |||
| getSelectedElements().selectOnly (pei); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| const char* PaintRoutine::xmlTagName = "BACKGROUND"; | |||
| XmlElement* PaintRoutine::createXml() const | |||
| { | |||
| XmlElement* const xml = new XmlElement (xmlTagName); | |||
| xml->setAttribute ("backgroundColour", backgroundColour.toString()); | |||
| for (int i = 0; i < elements.size(); ++i) | |||
| xml->addChildElement (elements.getUnchecked (i)->createXml()); | |||
| return xml; | |||
| } | |||
| bool PaintRoutine::loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (xmlTagName)) | |||
| { | |||
| backgroundColour = Colour::fromString (xml.getStringAttribute ("backgroundColour", Colours::white.toString())); | |||
| clear(); | |||
| forEachXmlChildElement (xml, e) | |||
| if (PaintElement* const newElement = ObjectTypes::createElementForXml (e, this)) | |||
| elements.add (newElement); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| void PaintRoutine::fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) const | |||
| { | |||
| if (! backgroundColour.isTransparent()) | |||
| paintMethodCode << "g.fillAll (" << CodeHelpers::colourToCode (backgroundColour) << ");\n\n"; | |||
| for (int i = 0; i < elements.size(); ++i) | |||
| elements[i]->fillInGeneratedCode (code, paintMethodCode); | |||
| } | |||
| @@ -0,0 +1,120 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTROUTINE_JUCEHEADER__ | |||
| #define __JUCER_PAINTROUTINE_JUCEHEADER__ | |||
| #include "paintelements/jucer_PaintElement.h" | |||
| class JucerDocument; | |||
| class PathPoint; | |||
| //============================================================================== | |||
| /** | |||
| Contains a set of PaintElements that constitute some kind of paint() method. | |||
| */ | |||
| class PaintRoutine | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| PaintRoutine(); | |||
| ~PaintRoutine(); | |||
| //============================================================================== | |||
| void changed(); | |||
| bool perform (UndoableAction* action, const String& actionName); | |||
| //============================================================================== | |||
| int getNumElements() const noexcept { return elements.size(); } | |||
| PaintElement* getElement (const int index) const noexcept { return elements [index]; } | |||
| int indexOfElement (PaintElement* e) const noexcept { return elements.indexOf (e); } | |||
| bool containsElement (PaintElement* e) const noexcept { return elements.contains (e); } | |||
| //============================================================================== | |||
| void clear(); | |||
| PaintElement* addElementFromXml (const XmlElement& xml, const int index, const bool undoable); | |||
| PaintElement* addNewElement (PaintElement* elementToCopy, const int index, const bool undoable); | |||
| void removeElement (PaintElement* element, const bool undoable); | |||
| void elementToFront (PaintElement* element, const bool undoable); | |||
| void elementToBack (PaintElement* element, const bool undoable); | |||
| const Colour getBackgroundColour() const noexcept { return backgroundColour; } | |||
| void setBackgroundColour (const Colour& newColour) noexcept; | |||
| void fillWithBackground (Graphics& g, const bool drawOpaqueBackground); | |||
| void drawElements (Graphics& g, const Rectangle<int>& relativeTo); | |||
| void dropImageAt (const File& f, int x, int y); | |||
| //============================================================================== | |||
| SelectedItemSet <PaintElement*>& getSelectedElements() noexcept { return selectedElements; } | |||
| SelectedItemSet <PathPoint*>& getSelectedPoints() noexcept { return selectedPoints; } | |||
| static const char* const clipboardXmlTag; | |||
| void copySelectedToClipboard(); | |||
| void paste(); | |||
| void deleteSelected(); | |||
| void selectAll(); | |||
| void selectedToFront(); | |||
| void selectedToBack(); | |||
| void groupSelected(); | |||
| void ungroupSelected(); | |||
| void startDragging (const Rectangle<int>& parentArea); | |||
| void dragSelectedComps (int dxFromDragStart, int dyFromDragStart, const Rectangle<int>& parentArea); | |||
| void endDragging(); | |||
| void bringLostItemsBackOnScreen (const Rectangle<int>& parentArea); | |||
| //============================================================================== | |||
| void setDocument (JucerDocument* const doc) { document = doc; } | |||
| JucerDocument* getDocument() const noexcept { return document; } | |||
| //============================================================================== | |||
| static const char* xmlTagName; | |||
| XmlElement* createXml() const; | |||
| bool loadFromXml (const XmlElement& xml); | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) const; | |||
| //============================================================================== | |||
| private: | |||
| OwnedArray <PaintElement> elements; | |||
| SelectedItemSet <PaintElement*> selectedElements; | |||
| SelectedItemSet <PathPoint*> selectedPoints; | |||
| JucerDocument* document; | |||
| Colour backgroundColour; | |||
| friend class DeleteElementAction; | |||
| friend class FrontOrBackElementAction; | |||
| void moveElementZOrder (int oldIndex, int newIndex); | |||
| }; | |||
| #endif // __JUCER_PAINTROUTINE_JUCEHEADER__ | |||
| @@ -0,0 +1,112 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 JUCER_UTILS_H | |||
| #define JUCER_UTILS_H | |||
| inline String quotedString (const String& s) | |||
| { | |||
| const int embeddedIndex = s.indexOfIgnoreCase ("%%"); | |||
| if (embeddedIndex >= 0) | |||
| { | |||
| String s1 (s.substring (0, embeddedIndex)); | |||
| String s2 (s.substring (embeddedIndex + 2)); | |||
| String code; | |||
| const int closeIndex = s2.indexOf ("%%"); | |||
| if (closeIndex > 0) | |||
| { | |||
| code = s2.substring (0, closeIndex).trim(); | |||
| s2 = s2.substring (closeIndex + 2); | |||
| } | |||
| if (code.isNotEmpty()) | |||
| { | |||
| String result; | |||
| if (s1.isNotEmpty()) | |||
| result << quotedString (s1) << " + "; | |||
| result << code; | |||
| if (s2.isNotEmpty()) | |||
| result << " + " << quotedString (s2); | |||
| return result; | |||
| } | |||
| } | |||
| return CodeHelpers::stringLiteral (s); | |||
| } | |||
| inline String castToFloat (const String& expression) | |||
| { | |||
| if (expression.containsOnly ("0123456789.f")) | |||
| { | |||
| String s (expression.getFloatValue()); | |||
| if (s.containsChar ('.')) | |||
| return s + "f"; | |||
| return s + ".0f"; | |||
| } | |||
| return "static_cast<float> (" + expression + ")"; | |||
| } | |||
| inline void drawResizableBorder (Graphics& g, int w, int h, | |||
| const BorderSize<int> borderSize, | |||
| const bool isMouseOver) | |||
| { | |||
| g.setColour (Colours::orange.withAlpha (isMouseOver ? 0.4f : 0.3f)); | |||
| g.fillRect (0, 0, w, borderSize.getTop()); | |||
| g.fillRect (0, 0, borderSize.getLeft(), h); | |||
| g.fillRect (0, h - borderSize.getBottom(), w, borderSize.getBottom()); | |||
| g.fillRect (w - borderSize.getRight(), 0, borderSize.getRight(), h); | |||
| g.drawRect (borderSize.getLeft() - 1, borderSize.getTop() - 1, | |||
| w - borderSize.getRight() - borderSize.getLeft() + 2, | |||
| h - borderSize.getTop() - borderSize.getBottom() + 2); | |||
| } | |||
| inline void drawMouseOverCorners (Graphics& g, int w, int h) | |||
| { | |||
| RectangleList r (Rectangle<int> (0, 0, w, h)); | |||
| r.subtract (Rectangle<int> (1, 1, w - 2, h - 2)); | |||
| const int size = jmin (w / 3, h / 3, 12); | |||
| r.subtract (Rectangle<int> (size, 0, w - size - size, h)); | |||
| r.subtract (Rectangle<int> (0, size, w, h - size - size)); | |||
| g.setColour (Colours::darkgrey); | |||
| for (int i = r.getNumRectangles(); --i >= 0;) | |||
| g.fillRect (r.getRectangle (i)); | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,994 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_ColouredElement.h" | |||
| #include "jucer_GradientPointComponent.h" | |||
| #include "../properties/jucer_PositionPropertyBase.h" | |||
| #include "../properties/jucer_ColourPropertyComponent.h" | |||
| #include "jucer_PaintElementUndoableAction.h" | |||
| #include "jucer_PaintElementPath.h" | |||
| #include "jucer_ImageResourceProperty.h" | |||
| //============================================================================== | |||
| class ElementFillModeProperty : public ChoicePropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ElementFillModeProperty (ColouredElement* const owner_, const bool isForStroke_) | |||
| : ChoicePropertyComponent ("fill mode"), | |||
| owner (owner_), | |||
| isForStroke (isForStroke_) | |||
| { | |||
| choices.add ("Solid Colour"); | |||
| choices.add ("Linear Gradient"); | |||
| choices.add ("Radial Gradient"); | |||
| choices.add ("Image Brush"); | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~ElementFillModeProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| JucerFillType fill (isForStroke ? owner->getStrokeType().fill | |||
| : owner->getFillType()); | |||
| switch (newIndex) | |||
| { | |||
| case 0: fill.mode = JucerFillType::solidColour; break; | |||
| case 1: fill.mode = JucerFillType::linearGradient; break; | |||
| case 2: fill.mode = JucerFillType::radialGradient; break; | |||
| case 3: fill.mode = JucerFillType::imageBrush; break; | |||
| default: jassertfalse; break; | |||
| } | |||
| if (! isForStroke) | |||
| owner->setFillType (fill, true); | |||
| else | |||
| owner->setStrokeFill (fill, true); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| switch (isForStroke ? owner->getStrokeType().fill.mode | |||
| : owner->getFillType().mode) | |||
| { | |||
| case JucerFillType::solidColour: return 0; | |||
| case JucerFillType::linearGradient: return 1; | |||
| case JucerFillType::radialGradient: return 2; | |||
| case JucerFillType::imageBrush: return 3; | |||
| default: jassertfalse; break; | |||
| } | |||
| return 0; | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| ColouredElement* const owner; | |||
| const bool isForStroke; | |||
| }; | |||
| //============================================================================== | |||
| class ElementFillColourProperty : public JucerColourPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| enum ColourType | |||
| { | |||
| solidColour, | |||
| gradientColour1, | |||
| gradientColour2 | |||
| }; | |||
| ElementFillColourProperty (const String& name, | |||
| ColouredElement* const owner_, | |||
| const ColourType type_, | |||
| const bool isForStroke_) | |||
| : JucerColourPropertyComponent (name, false), | |||
| owner (owner_), | |||
| type (type_), | |||
| isForStroke (isForStroke_) | |||
| { | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~ElementFillColourProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setColour (const Colour& newColour) | |||
| { | |||
| owner->getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| JucerFillType fill (isForStroke ? owner->getStrokeType().fill | |||
| : owner->getFillType()); | |||
| switch (type) | |||
| { | |||
| case solidColour: fill.colour = newColour; break; | |||
| case gradientColour1: fill.gradCol1 = newColour; break; | |||
| case gradientColour2: fill.gradCol2 = newColour; break; | |||
| default: jassertfalse; break; | |||
| } | |||
| if (! isForStroke) | |||
| owner->setFillType (fill, true); | |||
| else | |||
| owner->setStrokeFill (fill, true); | |||
| } | |||
| Colour getColour() const | |||
| { | |||
| const JucerFillType fill (isForStroke ? owner->getStrokeType().fill | |||
| : owner->getFillType()); | |||
| switch (type) | |||
| { | |||
| case solidColour: return fill.colour; break; | |||
| case gradientColour1: return fill.gradCol1; break; | |||
| case gradientColour2: return fill.gradCol2; break; | |||
| default: jassertfalse; break; | |||
| } | |||
| return Colours::black; | |||
| } | |||
| void resetToDefault() | |||
| { | |||
| jassertfalse; // option shouldn't be visible | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| ColouredElement* const owner; | |||
| const ColourType type; | |||
| const bool isForStroke; | |||
| }; | |||
| //============================================================================== | |||
| class ElementFillPositionProperty : public PositionPropertyBase | |||
| { | |||
| public: | |||
| ElementFillPositionProperty (ColouredElement* const owner_, | |||
| const String& name, | |||
| ComponentPositionDimension dimension_, | |||
| const bool isStart_, | |||
| const bool isForStroke_) | |||
| : PositionPropertyBase (owner_, name, dimension_, false, false, | |||
| owner_->getDocument()->getComponentLayout()), | |||
| owner (owner_), | |||
| isStart (isStart_), | |||
| isForStroke (isForStroke_) | |||
| { | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~ElementFillPositionProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setPosition (const RelativePositionedRectangle& newPos) | |||
| { | |||
| JucerFillType fill (isForStroke ? owner->getStrokeType().fill | |||
| : owner->getFillType()); | |||
| if (isStart) | |||
| fill.gradPos1 = newPos; | |||
| else | |||
| fill.gradPos2 = newPos; | |||
| if (! isForStroke) | |||
| owner->setFillType (fill, true); | |||
| else | |||
| owner->setStrokeFill (fill, true); | |||
| } | |||
| RelativePositionedRectangle getPosition() const | |||
| { | |||
| const JucerFillType fill (isForStroke ? owner->getStrokeType().fill | |||
| : owner->getFillType()); | |||
| return isStart ? fill.gradPos1 | |||
| : fill.gradPos2; | |||
| } | |||
| private: | |||
| ColouredElement* const owner; | |||
| const bool isStart, isForStroke; | |||
| }; | |||
| //============================================================================== | |||
| class EnableStrokeProperty : public BooleanPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| EnableStrokeProperty (ColouredElement* const owner_) | |||
| : BooleanPropertyComponent ("outline", "Outline enabled", "No outline"), | |||
| owner (owner_) | |||
| { | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~EnableStrokeProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| //============================================================================== | |||
| void setState (bool newState) { owner->enableStroke (newState, true); } | |||
| bool getState() const { return owner->isStrokeEnabled(); } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| ColouredElement* const owner; | |||
| }; | |||
| //============================================================================== | |||
| class StrokeThicknessProperty : public SliderPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| StrokeThicknessProperty (ColouredElement* const owner_) | |||
| : SliderPropertyComponent ("outline thickness", 0.1, 200.0, 0.1, 0.3), | |||
| owner (owner_) | |||
| { | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~StrokeThicknessProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| owner->getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| owner->setStrokeType (PathStrokeType ((float) newValue, | |||
| owner->getStrokeType().stroke.getJointStyle(), | |||
| owner->getStrokeType().stroke.getEndStyle()), | |||
| true); | |||
| } | |||
| double getValue() const { return owner->getStrokeType().stroke.getStrokeThickness(); } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| ColouredElement* const owner; | |||
| }; | |||
| //============================================================================== | |||
| class StrokeJointProperty : public ChoicePropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| StrokeJointProperty (ColouredElement* const owner_) | |||
| : ChoicePropertyComponent ("joint style"), | |||
| owner (owner_) | |||
| { | |||
| choices.add ("mitered"); | |||
| choices.add ("curved"); | |||
| choices.add ("beveled"); | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~StrokeJointProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| const PathStrokeType::JointStyle joints[] = { PathStrokeType::mitered, | |||
| PathStrokeType::curved, | |||
| PathStrokeType::beveled }; | |||
| jassert (newIndex >= 0 && newIndex < 3); | |||
| owner->setStrokeType (PathStrokeType (owner->getStrokeType().stroke.getStrokeThickness(), | |||
| joints [newIndex], | |||
| owner->getStrokeType().stroke.getEndStyle()), | |||
| true); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| switch (owner->getStrokeType().stroke.getJointStyle()) | |||
| { | |||
| case PathStrokeType::mitered: return 0; | |||
| case PathStrokeType::curved: return 1; | |||
| case PathStrokeType::beveled: return 2; | |||
| default: jassertfalse; break; | |||
| } | |||
| return 0; | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| ColouredElement* const owner; | |||
| }; | |||
| //============================================================================== | |||
| class StrokeEndCapProperty : public ChoicePropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| StrokeEndCapProperty (ColouredElement* const owner_) | |||
| : ChoicePropertyComponent ("end-cap style"), | |||
| owner (owner_) | |||
| { | |||
| choices.add ("butt"); | |||
| choices.add ("square"); | |||
| choices.add ("round"); | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~StrokeEndCapProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| const PathStrokeType::EndCapStyle ends[] = { PathStrokeType::butt, | |||
| PathStrokeType::square, | |||
| PathStrokeType::rounded }; | |||
| jassert (newIndex >= 0 && newIndex < 3); | |||
| owner->setStrokeType (PathStrokeType (owner->getStrokeType().stroke.getStrokeThickness(), | |||
| owner->getStrokeType().stroke.getJointStyle(), | |||
| ends [newIndex]), | |||
| true); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| switch (owner->getStrokeType().stroke.getEndStyle()) | |||
| { | |||
| case PathStrokeType::butt: return 0; | |||
| case PathStrokeType::square: return 1; | |||
| case PathStrokeType::rounded: return 2; | |||
| default: jassertfalse; break; | |||
| } | |||
| return 0; | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| ColouredElement* const owner; | |||
| }; | |||
| //============================================================================== | |||
| class ImageBrushResourceProperty : public ImageResourceProperty <ColouredElement> | |||
| { | |||
| public: | |||
| ImageBrushResourceProperty (ColouredElement* const e, const bool isForStroke_) | |||
| : ImageResourceProperty <ColouredElement> (e, isForStroke_ ? "stroke image" | |||
| : "fill image"), | |||
| isForStroke (isForStroke_) | |||
| { | |||
| } | |||
| //============================================================================== | |||
| void setResource (const String& newName) | |||
| { | |||
| if (isForStroke) | |||
| { | |||
| JucerFillType type (element->getStrokeType().fill); | |||
| type.imageResourceName = newName; | |||
| element->setStrokeFill (type, true); | |||
| } | |||
| else | |||
| { | |||
| JucerFillType type (element->getFillType()); | |||
| type.imageResourceName = newName; | |||
| element->setFillType (type, true); | |||
| } | |||
| } | |||
| String getResource() const | |||
| { | |||
| if (isForStroke) | |||
| return element->getStrokeType().fill.imageResourceName; | |||
| return element->getFillType().imageResourceName; | |||
| } | |||
| private: | |||
| bool isForStroke; | |||
| }; | |||
| //============================================================================== | |||
| class ImageBrushPositionProperty : public PositionPropertyBase | |||
| { | |||
| public: | |||
| ImageBrushPositionProperty (ColouredElement* const owner_, | |||
| const String& name, | |||
| ComponentPositionDimension dimension_, | |||
| const bool isForStroke_) | |||
| : PositionPropertyBase (owner_, name, dimension_, false, false, | |||
| owner_->getDocument()->getComponentLayout()), | |||
| owner (owner_), | |||
| isForStroke (isForStroke_) | |||
| { | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~ImageBrushPositionProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setPosition (const RelativePositionedRectangle& newPos) | |||
| { | |||
| if (isForStroke) | |||
| { | |||
| JucerFillType type (owner->getStrokeType().fill); | |||
| type.imageAnchor = newPos; | |||
| owner->setStrokeFill (type, true); | |||
| } | |||
| else | |||
| { | |||
| JucerFillType type (owner->getFillType()); | |||
| type.imageAnchor = newPos; | |||
| owner->setFillType (type, true); | |||
| } | |||
| } | |||
| RelativePositionedRectangle getPosition() const | |||
| { | |||
| if (isForStroke) | |||
| return owner->getStrokeType().fill.imageAnchor; | |||
| return owner->getFillType().imageAnchor; | |||
| } | |||
| private: | |||
| ColouredElement* const owner; | |||
| const bool isForStroke; | |||
| }; | |||
| //============================================================================== | |||
| class ImageBrushOpacityProperty : public SliderPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ImageBrushOpacityProperty (ColouredElement* const e, const bool isForStroke_) | |||
| : SliderPropertyComponent ("opacity", 0.0, 1.0, 0.001), | |||
| element (e), | |||
| isForStroke (isForStroke_) | |||
| { | |||
| element->getDocument()->addChangeListener (this); | |||
| } | |||
| ~ImageBrushOpacityProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| element->getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| if (isForStroke) | |||
| { | |||
| JucerFillType type (element->getStrokeType().fill); | |||
| type.imageOpacity = newValue; | |||
| element->setStrokeFill (type, true); | |||
| } | |||
| else | |||
| { | |||
| JucerFillType type (element->getFillType()); | |||
| type.imageOpacity = newValue; | |||
| element->setFillType (type, true); | |||
| } | |||
| } | |||
| double getValue() const | |||
| { | |||
| if (isForStroke) | |||
| return element->getStrokeType().fill.imageOpacity; | |||
| else | |||
| return element->getFillType().imageOpacity; | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| ColouredElement* const element; | |||
| bool isForStroke; | |||
| }; | |||
| //============================================================================== | |||
| ColouredElement::ColouredElement (PaintRoutine* owner_, | |||
| const String& name, | |||
| const bool showOutline_, | |||
| const bool showJointAndEnd_) | |||
| : PaintElement (owner_, name), | |||
| isStrokePresent (false), | |||
| showOutline (showOutline_), | |||
| showJointAndEnd (showJointAndEnd_) | |||
| { | |||
| } | |||
| ColouredElement::~ColouredElement() | |||
| { | |||
| } | |||
| //============================================================================== | |||
| void ColouredElement::getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| PaintElement::getEditableProperties (properties); | |||
| getColourSpecificProperties (properties); | |||
| } | |||
| void ColouredElement::getColourSpecificProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| properties.add (new ElementFillModeProperty (this, false)); | |||
| switch (getFillType().mode) | |||
| { | |||
| case JucerFillType::solidColour: | |||
| properties.add (new ElementFillColourProperty ("colour", this, ElementFillColourProperty::solidColour, false)); | |||
| break; | |||
| case JucerFillType::linearGradient: | |||
| case JucerFillType::radialGradient: | |||
| properties.add (new ElementFillColourProperty ("colour 1", this, ElementFillColourProperty::gradientColour1, false)); | |||
| properties.add (new ElementFillPositionProperty (this, "x1", PositionPropertyBase::componentX, true, false)); | |||
| properties.add (new ElementFillPositionProperty (this, "y1", PositionPropertyBase::componentY, true, false)); | |||
| properties.add (new ElementFillColourProperty ("colour 2", this, ElementFillColourProperty::gradientColour2, false)); | |||
| properties.add (new ElementFillPositionProperty (this, "x2", PositionPropertyBase::componentX, false, false)); | |||
| properties.add (new ElementFillPositionProperty (this, "y2", PositionPropertyBase::componentY, false, false)); | |||
| break; | |||
| case JucerFillType::imageBrush: | |||
| properties.add (new ImageBrushResourceProperty (this, false)); | |||
| properties.add (new ImageBrushPositionProperty (this, "anchor x", PositionPropertyBase::componentX, false)); | |||
| properties.add (new ImageBrushPositionProperty (this, "anchor y", PositionPropertyBase::componentY, false)); | |||
| properties.add (new ImageBrushOpacityProperty (this, false)); | |||
| break; | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| } | |||
| if (showOutline) | |||
| { | |||
| properties.add (new EnableStrokeProperty (this)); | |||
| if (isStrokePresent) | |||
| { | |||
| properties.add (new StrokeThicknessProperty (this)); | |||
| if (showJointAndEnd) | |||
| { | |||
| properties.add (new StrokeJointProperty (this)); | |||
| properties.add (new StrokeEndCapProperty (this)); | |||
| } | |||
| properties.add (new ElementFillModeProperty (this, true)); | |||
| switch (getStrokeType().fill.mode) | |||
| { | |||
| case JucerFillType::solidColour: | |||
| properties.add (new ElementFillColourProperty ("colour", this, ElementFillColourProperty::solidColour, true)); | |||
| break; | |||
| case JucerFillType::linearGradient: | |||
| case JucerFillType::radialGradient: | |||
| properties.add (new ElementFillColourProperty ("colour 1", this, ElementFillColourProperty::gradientColour1, true)); | |||
| properties.add (new ElementFillPositionProperty (this, "x1", PositionPropertyBase::componentX, true, true)); | |||
| properties.add (new ElementFillPositionProperty (this, "y1", PositionPropertyBase::componentY, true, true)); | |||
| properties.add (new ElementFillColourProperty ("colour 2", this, ElementFillColourProperty::gradientColour2, true)); | |||
| properties.add (new ElementFillPositionProperty (this, "x2", PositionPropertyBase::componentX, false, true)); | |||
| properties.add (new ElementFillPositionProperty (this, "y2", PositionPropertyBase::componentY, false, true)); | |||
| break; | |||
| case JucerFillType::imageBrush: | |||
| properties.add (new ImageBrushResourceProperty (this, true)); | |||
| properties.add (new ImageBrushPositionProperty (this, "stroke anchor x", PositionPropertyBase::componentX, true)); | |||
| properties.add (new ImageBrushPositionProperty (this, "stroke anchor y", PositionPropertyBase::componentY, true)); | |||
| properties.add (new ImageBrushOpacityProperty (this, true)); | |||
| break; | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| const JucerFillType& ColouredElement::getFillType() noexcept | |||
| { | |||
| return fillType; | |||
| } | |||
| class FillTypeChangeAction : public PaintElementUndoableAction <ColouredElement> | |||
| { | |||
| public: | |||
| FillTypeChangeAction (ColouredElement* const element, const JucerFillType& newState_) | |||
| : PaintElementUndoableAction <ColouredElement> (element), | |||
| newState (newState_) | |||
| { | |||
| oldState = element->getFillType(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setFillType (newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setFillType (oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| JucerFillType newState, oldState; | |||
| }; | |||
| void ColouredElement::setFillType (const JucerFillType& newType, const bool undoable) | |||
| { | |||
| if (fillType != newType) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new FillTypeChangeAction (this, newType), | |||
| "Change fill type"); | |||
| } | |||
| else | |||
| { | |||
| repaint(); | |||
| if (fillType.mode != newType.mode) | |||
| { | |||
| owner->getSelectedElements().changed(); | |||
| siblingComponentsChanged(); | |||
| } | |||
| fillType = newType; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| bool ColouredElement::isStrokeEnabled() const noexcept | |||
| { | |||
| return isStrokePresent && showOutline; | |||
| } | |||
| class StrokeEnableChangeAction : public PaintElementUndoableAction <ColouredElement> | |||
| { | |||
| public: | |||
| StrokeEnableChangeAction (ColouredElement* const element, const bool newState_) | |||
| : PaintElementUndoableAction <ColouredElement> (element), | |||
| newState (newState_) | |||
| { | |||
| oldState = element->isStrokeEnabled(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->enableStroke (newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->enableStroke (oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| bool newState, oldState; | |||
| }; | |||
| void ColouredElement::enableStroke (bool enable, const bool undoable) | |||
| { | |||
| enable = enable && showOutline; | |||
| if (isStrokePresent != enable) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new StrokeEnableChangeAction (this, enable), | |||
| "Change stroke mode"); | |||
| } | |||
| else | |||
| { | |||
| repaint(); | |||
| isStrokePresent = enable; | |||
| siblingComponentsChanged(); | |||
| owner->changed(); | |||
| owner->getSelectedElements().changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| const StrokeType& ColouredElement::getStrokeType() noexcept | |||
| { | |||
| return strokeType; | |||
| } | |||
| class StrokeTypeChangeAction : public PaintElementUndoableAction <ColouredElement> | |||
| { | |||
| public: | |||
| StrokeTypeChangeAction (ColouredElement* const element, const PathStrokeType& newState_) | |||
| : PaintElementUndoableAction <ColouredElement> (element), | |||
| newState (newState_), | |||
| oldState (element->getStrokeType().stroke) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setStrokeType (newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setStrokeType (oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| PathStrokeType newState, oldState; | |||
| }; | |||
| void ColouredElement::setStrokeType (const PathStrokeType& newType, const bool undoable) | |||
| { | |||
| if (strokeType.stroke != newType) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new StrokeTypeChangeAction (this, newType), | |||
| "Change stroke type"); | |||
| } | |||
| else | |||
| { | |||
| repaint(); | |||
| strokeType.stroke = newType; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| class StrokeFillTypeChangeAction : public PaintElementUndoableAction <ColouredElement> | |||
| { | |||
| public: | |||
| StrokeFillTypeChangeAction (ColouredElement* const element, const JucerFillType& newState_) | |||
| : PaintElementUndoableAction <ColouredElement> (element), | |||
| newState (newState_) | |||
| { | |||
| oldState = element->getStrokeType().fill; | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setStrokeFill (newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setStrokeFill (oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| JucerFillType newState, oldState; | |||
| }; | |||
| void ColouredElement::setStrokeFill (const JucerFillType& newType, const bool undoable) | |||
| { | |||
| if (strokeType.fill != newType) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new StrokeFillTypeChangeAction (this, newType), | |||
| "Change stroke fill type"); | |||
| } | |||
| else | |||
| { | |||
| repaint(); | |||
| if (strokeType.fill.mode != newType.mode) | |||
| { | |||
| siblingComponentsChanged(); | |||
| owner->getSelectedElements().changed(); | |||
| } | |||
| strokeType.fill = newType; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void ColouredElement::createSiblingComponents() | |||
| { | |||
| { | |||
| GradientPointComponent* g1 = new GradientPointComponent (this, false, true); | |||
| siblingComponents.add (g1); | |||
| GradientPointComponent* g2 = new GradientPointComponent (this, false, false); | |||
| siblingComponents.add (g2); | |||
| getParentComponent()->addAndMakeVisible (g1); | |||
| getParentComponent()->addAndMakeVisible (g2); | |||
| g1->updatePosition(); | |||
| g2->updatePosition(); | |||
| } | |||
| if (isStrokePresent && showOutline) | |||
| { | |||
| GradientPointComponent* g1 = new GradientPointComponent (this, true, true); | |||
| siblingComponents.add (g1); | |||
| GradientPointComponent* g2 = new GradientPointComponent (this, true, false); | |||
| siblingComponents.add (g2); | |||
| getParentComponent()->addAndMakeVisible (g1); | |||
| getParentComponent()->addAndMakeVisible (g2); | |||
| g1->updatePosition(); | |||
| g2->updatePosition(); | |||
| } | |||
| } | |||
| Rectangle<int> ColouredElement::getCurrentBounds (const Rectangle<int>& parentArea) const | |||
| { | |||
| int border = 0; | |||
| if (isStrokePresent) | |||
| border = (int) strokeType.stroke.getStrokeThickness() / 2 + 1; | |||
| return position.getRectangle (parentArea, getDocument()->getComponentLayout()) | |||
| .expanded (border, border); | |||
| } | |||
| void ColouredElement::setCurrentBounds (const Rectangle<int>& newBounds, | |||
| const Rectangle<int>& parentArea, | |||
| const bool undoable) | |||
| { | |||
| Rectangle<int> r (newBounds); | |||
| if (isStrokePresent) | |||
| { | |||
| const int border = (int) strokeType.stroke.getStrokeThickness() / 2 + 1; | |||
| r = r.expanded (-border, -border); | |||
| r.setSize (jmax (1, r.getWidth()), jmax (1, r.getHeight())); | |||
| } | |||
| RelativePositionedRectangle pr (position); | |||
| pr.updateFrom (r.getX() - parentArea.getX(), | |||
| r.getY() - parentArea.getY(), | |||
| r.getWidth(), r.getHeight(), | |||
| Rectangle<int> (0, 0, parentArea.getWidth(), parentArea.getHeight()), | |||
| getDocument()->getComponentLayout()); | |||
| setPosition (pr, undoable); | |||
| updateBounds (parentArea); | |||
| } | |||
| //============================================================================== | |||
| void ColouredElement::addColourAttributes (XmlElement* const e) const | |||
| { | |||
| e->setAttribute ("fill", fillType.toString()); | |||
| e->setAttribute ("hasStroke", isStrokePresent); | |||
| if (isStrokePresent && showOutline) | |||
| { | |||
| e->setAttribute ("stroke", strokeType.toString()); | |||
| e->setAttribute ("strokeColour", strokeType.fill.toString()); | |||
| } | |||
| } | |||
| bool ColouredElement::loadColourAttributes (const XmlElement& xml) | |||
| { | |||
| fillType.restoreFromString (xml.getStringAttribute ("fill", String::empty)); | |||
| isStrokePresent = showOutline && xml.getBoolAttribute ("hasStroke", false); | |||
| strokeType.restoreFromString (xml.getStringAttribute ("stroke", String::empty)); | |||
| strokeType.fill.restoreFromString (xml.getStringAttribute ("strokeColour", String::empty)); | |||
| return true; | |||
| } | |||
| //============================================================================== | |||
| void ColouredElement::convertToNewPathElement (const Path& path) | |||
| { | |||
| if (! path.isEmpty()) | |||
| { | |||
| PaintElementPath newElement (getOwner()); | |||
| newElement.setToPath (path); | |||
| newElement.setFillType (fillType, false); | |||
| newElement.enableStroke (isStrokeEnabled(), false); | |||
| newElement.setStrokeType (getStrokeType().stroke, false); | |||
| newElement.setStrokeFill (getStrokeType().fill, false); | |||
| ScopedPointer<XmlElement> xml (newElement.createXml()); | |||
| PaintElement* e = getOwner()->addElementFromXml (*xml, getOwner()->indexOfElement (this), true); | |||
| getOwner()->getSelectedElements().selectOnly (e); | |||
| getOwner()->removeElement (this, true); | |||
| } | |||
| } | |||
| @@ -0,0 +1,86 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COLOUREDELEMENT_JUCEHEADER__ | |||
| #define __JUCER_COLOUREDELEMENT_JUCEHEADER__ | |||
| #include "../jucer_PaintRoutine.h" | |||
| #include "../jucer_JucerDocument.h" | |||
| #include "jucer_StrokeType.h" | |||
| //============================================================================== | |||
| /** | |||
| Base class for paint elements that have a fill colour and stroke. | |||
| */ | |||
| class ColouredElement : public PaintElement | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ColouredElement (PaintRoutine* owner, | |||
| const String& name, | |||
| const bool showOutline_, | |||
| const bool showJointAndEnd_); | |||
| ~ColouredElement(); | |||
| //============================================================================== | |||
| void getEditableProperties (Array <PropertyComponent*>& properties); | |||
| void getColourSpecificProperties (Array <PropertyComponent*>& properties); | |||
| //============================================================================== | |||
| const JucerFillType& getFillType() noexcept; | |||
| void setFillType (const JucerFillType& newType, const bool undoable); | |||
| bool isStrokeEnabled() const noexcept; | |||
| void enableStroke (bool enable, const bool undoable); | |||
| const StrokeType& getStrokeType() noexcept; | |||
| void setStrokeType (const PathStrokeType& newType, const bool undoable); | |||
| void setStrokeFill (const JucerFillType& newType, const bool undoable); | |||
| //============================================================================== | |||
| Rectangle<int> getCurrentBounds (const Rectangle<int>& parentArea) const; | |||
| void setCurrentBounds (const Rectangle<int>& newBounds, const Rectangle<int>& parentArea, const bool undoable); | |||
| void createSiblingComponents(); | |||
| //============================================================================== | |||
| void addColourAttributes (XmlElement* const e) const; | |||
| bool loadColourAttributes (const XmlElement& xml); | |||
| protected: | |||
| JucerFillType fillType; | |||
| bool isStrokePresent; | |||
| const bool showOutline, showJointAndEnd; | |||
| StrokeType strokeType; | |||
| void convertToNewPathElement (const Path& path); | |||
| }; | |||
| #endif // __JUCER_COLOUREDELEMENT_JUCEHEADER__ | |||
| @@ -0,0 +1,60 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_ELEMENTSIBLINGCOMPONENT_JUCEHEADER__ | |||
| #define __JUCER_ELEMENTSIBLINGCOMPONENT_JUCEHEADER__ | |||
| //============================================================================== | |||
| class ElementSiblingComponent : public Component, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| ElementSiblingComponent (PaintElement* const owner_) | |||
| : owner (owner_) | |||
| { | |||
| setAlwaysOnTop (true); | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~ElementSiblingComponent() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| virtual void updatePosition() = 0; | |||
| protected: | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| updatePosition(); | |||
| } | |||
| PaintElement* const owner; | |||
| }; | |||
| #endif // __JUCER_ELEMENTSIBLINGCOMPONENT_JUCEHEADER__ | |||
| @@ -0,0 +1,371 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_FILLTYPE_JUCEHEADER__ | |||
| #define __JUCER_FILLTYPE_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| #include "../jucer_UtilityFunctions.h" | |||
| //============================================================================== | |||
| class JucerFillType | |||
| { | |||
| public: | |||
| JucerFillType() | |||
| { | |||
| reset(); | |||
| } | |||
| JucerFillType (const JucerFillType& other) | |||
| { | |||
| image = Image(); | |||
| mode = other.mode; | |||
| colour = other.colour; | |||
| gradCol1 = other.gradCol1; | |||
| gradCol2 = other.gradCol2; | |||
| gradPos1 = other.gradPos1; | |||
| gradPos2 = other.gradPos2; | |||
| imageResourceName = other.imageResourceName; | |||
| imageOpacity = other.imageOpacity; | |||
| imageAnchor = other.imageAnchor; | |||
| } | |||
| JucerFillType& operator= (const JucerFillType& other) | |||
| { | |||
| image = Image(); | |||
| mode = other.mode; | |||
| colour = other.colour; | |||
| gradCol1 = other.gradCol1; | |||
| gradCol2 = other.gradCol2; | |||
| gradPos1 = other.gradPos1; | |||
| gradPos2 = other.gradPos2; | |||
| imageResourceName = other.imageResourceName; | |||
| imageOpacity = other.imageOpacity; | |||
| imageAnchor = other.imageAnchor; | |||
| return *this; | |||
| } | |||
| bool operator== (const JucerFillType& other) const | |||
| { | |||
| return mode == other.mode | |||
| && colour == other.colour | |||
| && gradCol1 == other.gradCol1 | |||
| && gradCol2 == other.gradCol2 | |||
| && gradPos1 == other.gradPos1 | |||
| && gradPos2 == other.gradPos2 | |||
| && imageResourceName == other.imageResourceName | |||
| && imageOpacity == other.imageOpacity | |||
| && imageAnchor == other.imageAnchor; | |||
| } | |||
| bool operator!= (const JucerFillType& other) const | |||
| { | |||
| return ! operator== (other); | |||
| } | |||
| //============================================================================== | |||
| void setFillType (Graphics& g, JucerDocument* const document, const Rectangle<int>& parentArea) | |||
| { | |||
| if (mode == solidColour) | |||
| { | |||
| image = Image(); | |||
| g.setColour (colour); | |||
| } | |||
| else if (mode == imageBrush) | |||
| { | |||
| loadImage (document); | |||
| Rectangle<int> r (imageAnchor.getRectangle (parentArea, document->getComponentLayout())); | |||
| g.setTiledImageFill (image, r.getX(), r.getY(), (float) imageOpacity); | |||
| } | |||
| else | |||
| { | |||
| image = Image(); | |||
| Rectangle<int> r1 (gradPos1.getRectangle (parentArea, document->getComponentLayout())); | |||
| Rectangle<int> r2 (gradPos2.getRectangle (parentArea, document->getComponentLayout())); | |||
| g.setGradientFill (ColourGradient (gradCol1, (float) r1.getX(), (float) r1.getY(), | |||
| gradCol2, (float) r2.getX(), (float) r2.getY(), | |||
| mode == radialGradient)); | |||
| } | |||
| } | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) const | |||
| { | |||
| String s; | |||
| switch (mode) | |||
| { | |||
| case solidColour: | |||
| s << "g.setColour (" << CodeHelpers::colourToCode (colour) << ");\n"; | |||
| break; | |||
| case linearGradient: | |||
| case radialGradient: | |||
| { | |||
| String x1, y1, w, h, x2, y2; | |||
| positionToCode (gradPos1, code.document->getComponentLayout(), x1, y1, w, h); | |||
| positionToCode (gradPos2, code.document->getComponentLayout(), x2, y2, w, h); | |||
| s << "g.setGradientFill (ColourGradient ("; | |||
| const String indent (String::repeatedString (" ", s.length())); | |||
| s << CodeHelpers::colourToCode (gradCol1) << ",\n" | |||
| << indent << castToFloat (x1) << ", " << castToFloat (y1) << ",\n" | |||
| << indent << CodeHelpers::colourToCode (gradCol2) << ",\n" | |||
| << indent << castToFloat (x2) << ", " << castToFloat (y2) << ",\n" | |||
| << indent << CodeHelpers::boolLiteral (mode == radialGradient) << "));\n"; | |||
| break; | |||
| } | |||
| case imageBrush: | |||
| { | |||
| const String imageVariable ("cachedImage_" + imageResourceName + "_" + String (code.getUniqueSuffix())); | |||
| code.addImageResourceLoader (imageVariable, imageResourceName); | |||
| String x, y, w, h; | |||
| positionToCode (imageAnchor, code.document->getComponentLayout(), x, y, w, h); | |||
| s << "g.setTiledImageFill ("; | |||
| const String indent (String::repeatedString (" ", s.length())); | |||
| s << imageVariable << ",\n" | |||
| << indent << x << ", " << y << ",\n" | |||
| << indent << CodeHelpers::floatLiteral (imageOpacity, 4) << ");\n"; | |||
| break; | |||
| } | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| } | |||
| paintMethodCode += s; | |||
| } | |||
| String toString() const | |||
| { | |||
| switch (mode) | |||
| { | |||
| case solidColour: | |||
| return "solid: " + colour.toString(); | |||
| case linearGradient: | |||
| case radialGradient: | |||
| return (mode == linearGradient ? "linear: " | |||
| : " radial: ") | |||
| + gradPos1.toString() | |||
| + ", " | |||
| + gradPos2.toString() | |||
| + ", 0=" + gradCol1.toString() | |||
| + ", 1=" + gradCol2.toString(); | |||
| case imageBrush: | |||
| return "image: " + imageResourceName | |||
| + ", " | |||
| + String (imageOpacity) | |||
| + ", " | |||
| + imageAnchor.toString(); | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| } | |||
| return String::empty; | |||
| } | |||
| void restoreFromString (const String& s) | |||
| { | |||
| reset(); | |||
| if (s.isNotEmpty()) | |||
| { | |||
| StringArray toks; | |||
| toks.addTokens (s, ",:", String::empty); | |||
| toks.trim(); | |||
| if (toks[0] == "solid") | |||
| { | |||
| mode = solidColour; | |||
| colour = Colour (toks[1].getHexValue32()); | |||
| } | |||
| else if (toks[0] == "linear" | |||
| || toks[0] == "radial") | |||
| { | |||
| mode = (toks[0] == "linear") ? linearGradient : radialGradient; | |||
| gradPos1 = RelativePositionedRectangle(); | |||
| gradPos1.rect = PositionedRectangle (toks[1]); | |||
| gradPos2 = RelativePositionedRectangle(); | |||
| gradPos2.rect = PositionedRectangle (toks[2]); | |||
| gradCol1 = Colour (toks[3].fromFirstOccurrenceOf ("=", false, false).getHexValue32()); | |||
| gradCol2 = Colour (toks[4].fromFirstOccurrenceOf ("=", false, false).getHexValue32()); | |||
| } | |||
| else if (toks[0] == "image") | |||
| { | |||
| mode = imageBrush; | |||
| imageResourceName = toks[1]; | |||
| imageOpacity = toks[2].getDoubleValue(); | |||
| imageAnchor= RelativePositionedRectangle(); | |||
| imageAnchor.rect = PositionedRectangle (toks[3]); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; | |||
| } | |||
| } | |||
| } | |||
| bool isOpaque() const | |||
| { | |||
| switch (mode) | |||
| { | |||
| case solidColour: | |||
| return colour.isOpaque(); | |||
| case linearGradient: | |||
| case radialGradient: | |||
| return gradCol1.isOpaque() && gradCol1.isOpaque(); | |||
| case imageBrush: | |||
| return image.isValid() | |||
| && imageOpacity >= 1.0f | |||
| && ! image.hasAlphaChannel(); | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| } | |||
| return false; | |||
| } | |||
| bool isInvisible() const | |||
| { | |||
| switch (mode) | |||
| { | |||
| case solidColour: | |||
| return colour.isTransparent(); | |||
| case linearGradient: | |||
| case radialGradient: | |||
| return gradCol1.isTransparent() && gradCol2.isTransparent(); | |||
| case imageBrush: | |||
| return imageOpacity == 0; | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| } | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| enum FillMode | |||
| { | |||
| solidColour, | |||
| linearGradient, | |||
| radialGradient, | |||
| imageBrush | |||
| }; | |||
| FillMode mode; | |||
| Colour colour, gradCol1, gradCol2; | |||
| // just the x, y, of these are used | |||
| RelativePositionedRectangle gradPos1, gradPos2; | |||
| String imageResourceName; | |||
| double imageOpacity; | |||
| RelativePositionedRectangle imageAnchor; | |||
| //============================================================================== | |||
| private: | |||
| Image image; | |||
| void reset() | |||
| { | |||
| image = Image(); | |||
| mode = solidColour; | |||
| colour = Colours::brown.withHue (Random::getSystemRandom().nextFloat()); | |||
| gradCol1 = Colours::red; | |||
| gradCol2 = Colours::green; | |||
| gradPos1 = RelativePositionedRectangle(); | |||
| gradPos1.rect = PositionedRectangle ("50 50"); | |||
| gradPos2 = RelativePositionedRectangle(); | |||
| gradPos2.rect = PositionedRectangle ("100 100"); | |||
| imageResourceName = String::empty; | |||
| imageOpacity = 1.0; | |||
| imageAnchor = RelativePositionedRectangle(); | |||
| imageAnchor.rect = PositionedRectangle ("0 0"); | |||
| } | |||
| void loadImage (JucerDocument* const document) | |||
| { | |||
| if (image.isNull()) | |||
| { | |||
| if (document != nullptr) | |||
| image = document->getResources().getImageFromCache (imageResourceName); | |||
| if (image.isNull()) | |||
| { | |||
| const int hashCode = 0x3437856f; | |||
| image = ImageCache::getFromHashCode (hashCode); | |||
| if (image.isNull()) | |||
| { | |||
| image = Image (Image::RGB, 100, 100, true); | |||
| Graphics g (image); | |||
| g.fillCheckerBoard (image.getBounds(), | |||
| image.getWidth() / 2, image.getHeight() / 2, | |||
| Colours::white, Colours::lightgrey); | |||
| g.setFont (12.0f); | |||
| g.setColour (Colours::grey); | |||
| g.drawText ("(image missing)", 0, 0, image.getWidth(), image.getHeight() / 2, Justification::centred, true); | |||
| ImageCache::addImageToCache (image, hashCode); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }; | |||
| #endif // __JUCER_FILLTYPE_JUCEHEADER__ | |||
| @@ -0,0 +1,104 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_GRADIENTPOINTCOMPONENT_JUCEHEADER__ | |||
| #define __JUCER_GRADIENTPOINTCOMPONENT_JUCEHEADER__ | |||
| #include "jucer_PointComponent.h" | |||
| #include "jucer_ColouredElement.h" | |||
| //============================================================================== | |||
| class GradientPointComponent : public PointComponent | |||
| { | |||
| public: | |||
| GradientPointComponent (ColouredElement* const owner_, | |||
| const bool isStroke_, | |||
| const bool isStart_) | |||
| : PointComponent (owner_), | |||
| isStroke (isStroke_), | |||
| isStart (isStart_) | |||
| { | |||
| } | |||
| RelativePositionedRectangle getPosition() | |||
| { | |||
| ColouredElement* e = dynamic_cast <ColouredElement*> (owner); | |||
| if (isStroke) | |||
| return isStart ? e->getStrokeType().fill.gradPos1 | |||
| : e->getStrokeType().fill.gradPos2; | |||
| return isStart ? e->getFillType().gradPos1 | |||
| : e->getFillType().gradPos2; | |||
| } | |||
| void setPosition (const RelativePositionedRectangle& newPos) | |||
| { | |||
| ColouredElement* e = dynamic_cast <ColouredElement*> (owner); | |||
| if (isStroke) | |||
| { | |||
| JucerFillType f (e->getStrokeType().fill); | |||
| if (isStart) | |||
| f.gradPos1 = newPos; | |||
| else | |||
| f.gradPos2 = newPos; | |||
| e->setStrokeFill (f, true); | |||
| } | |||
| else | |||
| { | |||
| JucerFillType f (e->getFillType()); | |||
| if (isStart) | |||
| f.gradPos1 = newPos; | |||
| else | |||
| f.gradPos2 = newPos; | |||
| e->setFillType (f, true); | |||
| } | |||
| } | |||
| void updatePosition() | |||
| { | |||
| PointComponent::updatePosition(); | |||
| ColouredElement* e = dynamic_cast <ColouredElement*> (owner); | |||
| JucerFillType f (isStroke ? e->getStrokeType().fill | |||
| : e->getFillType()); | |||
| setVisible (f.mode == JucerFillType::linearGradient | |||
| || f.mode == JucerFillType::radialGradient); | |||
| } | |||
| private: | |||
| bool isStroke, isStart; | |||
| }; | |||
| #endif // __JUCER_GRADIENTPOINTCOMPONENT_JUCEHEADER__ | |||
| @@ -0,0 +1,126 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_IMAGERESOURCEPROPERTY_JUCEHEADER__ | |||
| #define __JUCER_IMAGERESOURCEPROPERTY_JUCEHEADER__ | |||
| //============================================================================== | |||
| /** | |||
| A property that lets you pick a resource to use as an image, or create a | |||
| new one with a file selector. | |||
| */ | |||
| template <class ElementType> | |||
| class ImageResourceProperty : public ChoicePropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ImageResourceProperty (JucerDocument& doc, | |||
| ElementType* const e, | |||
| const String& name, | |||
| const bool allowChoiceOfNoResource_) | |||
| : ChoicePropertyComponent (name), | |||
| element (e), document (doc), | |||
| allowChoiceOfNoResource (allowChoiceOfNoResource_) | |||
| { | |||
| choices.add ("-- create a new image resource -- "); | |||
| choices.add (String::empty); | |||
| if (allowChoiceOfNoResource_) | |||
| choices.add ("<< none >>"); | |||
| choices.addArray (doc.getResources().getResourceNames()); | |||
| doc.addChangeListener (this); | |||
| } | |||
| ImageResourceProperty (ElementType* const e, const String& name, | |||
| const bool allowChoiceOfNoResource_ = false) | |||
| : ChoicePropertyComponent (name), | |||
| element (e), document (*e->getDocument()), | |||
| allowChoiceOfNoResource (allowChoiceOfNoResource_) | |||
| { | |||
| choices.add ("-- create a new image resource -- "); | |||
| choices.add (String::empty); | |||
| if (allowChoiceOfNoResource_) | |||
| choices.add ("<< none >>"); | |||
| choices.addArray (document.getResources().getResourceNames()); | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ImageResourceProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| //============================================================================== | |||
| virtual void setResource (const String& newName) = 0; | |||
| virtual String getResource() const = 0; | |||
| //============================================================================== | |||
| void setIndex (int newIndex) | |||
| { | |||
| if (newIndex == 0) | |||
| { | |||
| String resource (document.getResources() | |||
| .browseForResource ("Select an image file to add as a resource", | |||
| "*.jpg;*.jpeg;*.png;*.gif;*.svg", | |||
| File::nonexistent, | |||
| String::empty)); | |||
| if (resource.isNotEmpty()) | |||
| setResource (resource); | |||
| } | |||
| else | |||
| { | |||
| if (choices[newIndex] == "<< none >>" && allowChoiceOfNoResource) | |||
| setResource (String::empty); | |||
| else | |||
| setResource (choices [newIndex]); | |||
| } | |||
| } | |||
| int getIndex() const | |||
| { | |||
| if (getResource().isEmpty()) | |||
| return -1; | |||
| return choices.indexOf (getResource()); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| protected: | |||
| ElementType* const element; | |||
| JucerDocument& document; | |||
| const bool allowChoiceOfNoResource; | |||
| }; | |||
| #endif // __JUCER_IMAGERESOURCEPROPERTY_JUCEHEADER__ | |||
| @@ -0,0 +1,482 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "../jucer_PaintRoutine.h" | |||
| #include "../jucer_UtilityFunctions.h" | |||
| #include "../ui/jucer_JucerCommandIDs.h" | |||
| #include "../ui/jucer_PaintRoutineEditor.h" | |||
| #include "../properties/jucer_PositionPropertyBase.h" | |||
| #include "jucer_ElementSiblingComponent.h" | |||
| #include "jucer_PaintElementUndoableAction.h" | |||
| //============================================================================== | |||
| PaintElement::PaintElement (PaintRoutine* owner_, | |||
| const String& typeName_) | |||
| : borderThickness (4), | |||
| owner (owner_), | |||
| typeName (typeName_), | |||
| selected (false), | |||
| dragging (false), | |||
| originalAspectRatio (1.0) | |||
| { | |||
| setRepaintsOnMouseActivity (true); | |||
| position.rect.setWidth (100); | |||
| position.rect.setHeight (100); | |||
| setMinimumOnscreenAmounts (0, 0, 0, 0); | |||
| setSizeLimits (borderThickness * 2 + 1, borderThickness * 2 + 1, 8192, 8192); | |||
| addChildComponent (border = new ResizableBorderComponent (this, this)); | |||
| border->setBorderThickness (BorderSize<int> (borderThickness)); | |||
| if (owner != nullptr) | |||
| owner->getSelectedElements().addChangeListener (this); | |||
| selfChangeListenerList.addChangeListener (this); | |||
| siblingComponentsChanged(); | |||
| } | |||
| PaintElement::~PaintElement() | |||
| { | |||
| siblingComponents.clear(); | |||
| if (owner != nullptr) | |||
| owner->getSelectedElements().removeChangeListener (this); | |||
| } | |||
| //============================================================================== | |||
| void PaintElement::setInitialBounds (int parentWidth, int parentHeight) | |||
| { | |||
| RelativePositionedRectangle pr (getPosition()); | |||
| pr.rect.setX (parentWidth / 4 + Random::getSystemRandom().nextInt (parentWidth / 4) - parentWidth / 8); | |||
| pr.rect.setY (parentHeight / 3 + Random::getSystemRandom().nextInt (parentHeight / 4) - parentHeight / 8); | |||
| setPosition (pr, false); | |||
| } | |||
| //============================================================================== | |||
| const RelativePositionedRectangle& PaintElement::getPosition() const | |||
| { | |||
| return position; | |||
| } | |||
| class PaintElementMoveAction : public PaintElementUndoableAction <PaintElement> | |||
| { | |||
| public: | |||
| PaintElementMoveAction (PaintElement* const element, const RelativePositionedRectangle& newState_) | |||
| : PaintElementUndoableAction <PaintElement> (element), | |||
| newState (newState_), | |||
| oldState (element->getPosition()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setPosition (newState, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setPosition (oldState, false); | |||
| return true; | |||
| } | |||
| private: | |||
| RelativePositionedRectangle newState, oldState; | |||
| }; | |||
| void PaintElement::setPosition (const RelativePositionedRectangle& newPosition, const bool undoable) | |||
| { | |||
| if (position != newPosition) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new PaintElementMoveAction (this, newPosition), | |||
| "Move " + getTypeName()); | |||
| } | |||
| else | |||
| { | |||
| position = newPosition; | |||
| if (owner != nullptr) | |||
| owner->changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| Rectangle<int> PaintElement::getCurrentBounds (const Rectangle<int>& parentArea) const | |||
| { | |||
| return position.getRectangle (parentArea, getDocument()->getComponentLayout()); | |||
| } | |||
| void PaintElement::setCurrentBounds (const Rectangle<int>& newBounds, | |||
| const Rectangle<int>& parentArea, | |||
| const bool undoable) | |||
| { | |||
| RelativePositionedRectangle pr (position); | |||
| pr.updateFrom (newBounds.getX() - parentArea.getX(), | |||
| newBounds.getY() - parentArea.getY(), | |||
| jmax (1, newBounds.getWidth()), | |||
| jmax (1, newBounds.getHeight()), | |||
| Rectangle<int> (0, 0, parentArea.getWidth(), parentArea.getHeight()), | |||
| getDocument()->getComponentLayout()); | |||
| setPosition (pr, undoable); | |||
| updateBounds (parentArea); | |||
| } | |||
| void PaintElement::updateBounds (const Rectangle<int>& parentArea) | |||
| { | |||
| if (! parentArea.isEmpty()) | |||
| { | |||
| setBounds (getCurrentBounds (parentArea) | |||
| .expanded (borderThickness, | |||
| borderThickness)); | |||
| for (int i = siblingComponents.size(); --i >= 0;) | |||
| siblingComponents.getUnchecked(i)->updatePosition(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class ElementPositionProperty : public PositionPropertyBase | |||
| { | |||
| public: | |||
| ElementPositionProperty (PaintElement* e, const String& name, | |||
| ComponentPositionDimension dimension_) | |||
| : PositionPropertyBase (e, name, dimension_, true, false, | |||
| e->getDocument()->getComponentLayout()), | |||
| element (e) | |||
| { | |||
| e->getDocument()->addChangeListener (this); | |||
| } | |||
| ~ElementPositionProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setPosition (const RelativePositionedRectangle& newPos) | |||
| { | |||
| element->setPosition (newPos, true); | |||
| } | |||
| RelativePositionedRectangle getPosition() const | |||
| { | |||
| return element->getPosition(); | |||
| } | |||
| private: | |||
| PaintElement* const element; | |||
| }; | |||
| //============================================================================== | |||
| void PaintElement::getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| properties.add (new ElementPositionProperty (this, "x", PositionPropertyBase::componentX)); | |||
| properties.add (new ElementPositionProperty (this, "y", PositionPropertyBase::componentY)); | |||
| properties.add (new ElementPositionProperty (this, "width", PositionPropertyBase::componentWidth)); | |||
| properties.add (new ElementPositionProperty (this, "height", PositionPropertyBase::componentHeight)); | |||
| } | |||
| //============================================================================== | |||
| JucerDocument* PaintElement::getDocument() const | |||
| { | |||
| return owner->getDocument(); | |||
| } | |||
| void PaintElement::changed() | |||
| { | |||
| repaint(); | |||
| owner->changed(); | |||
| } | |||
| bool PaintElement::perform (UndoableAction* action, const String& actionName) | |||
| { | |||
| return owner->perform (action, actionName); | |||
| } | |||
| void PaintElement::parentHierarchyChanged() | |||
| { | |||
| updateSiblingComps(); | |||
| } | |||
| //============================================================================== | |||
| void PaintElement::drawExtraEditorGraphics (Graphics&, const Rectangle<int>& /*relativeTo*/) | |||
| { | |||
| } | |||
| void PaintElement::paint (Graphics& g) | |||
| { | |||
| Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| g.saveState(); | |||
| g.setOrigin (area.getX() - getX(), area.getY() - getY()); | |||
| area.setPosition (0, 0); | |||
| g.saveState(); | |||
| g.reduceClipRegion (0, 0, area.getWidth(), area.getHeight()); | |||
| draw (g, getDocument()->getComponentLayout(), area); | |||
| g.restoreState(); | |||
| drawExtraEditorGraphics (g, area); | |||
| g.restoreState(); | |||
| if (selected) | |||
| { | |||
| const BorderSize<int> borderSize (border->getBorderThickness()); | |||
| drawResizableBorder (g, getWidth(), getHeight(), borderSize, | |||
| (isMouseOverOrDragging() || border->isMouseOverOrDragging())); | |||
| } | |||
| else if (isMouseOverOrDragging()) | |||
| { | |||
| drawMouseOverCorners (g, getWidth(), getHeight()); | |||
| } | |||
| } | |||
| void PaintElement::resized() | |||
| { | |||
| border->setBounds (getLocalBounds()); | |||
| } | |||
| void PaintElement::mouseDown (const MouseEvent& e) | |||
| { | |||
| dragging = false; | |||
| if (owner != nullptr) | |||
| { | |||
| owner->getSelectedPoints().deselectAll(); | |||
| mouseDownSelectStatus = owner->getSelectedElements().addToSelectionOnMouseDown (this, e.mods); | |||
| } | |||
| if (e.mods.isPopupMenu()) | |||
| { | |||
| showPopupMenu(); | |||
| return; // this may be deleted now.. | |||
| } | |||
| } | |||
| void PaintElement::mouseDrag (const MouseEvent& e) | |||
| { | |||
| if (! e.mods.isPopupMenu()) | |||
| { | |||
| jassert (dynamic_cast <PaintRoutineEditor*> (getParentComponent()) != nullptr); | |||
| const Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| if (selected && ! dragging) | |||
| { | |||
| dragging = ! e.mouseWasClicked(); | |||
| if (dragging) | |||
| owner->startDragging (area); | |||
| } | |||
| if (dragging) | |||
| owner->dragSelectedComps (e.getDistanceFromDragStartX(), | |||
| e.getDistanceFromDragStartY(), | |||
| area); | |||
| } | |||
| } | |||
| void PaintElement::mouseUp (const MouseEvent& e) | |||
| { | |||
| if (dragging) | |||
| owner->endDragging(); | |||
| if (owner != nullptr) | |||
| owner->getSelectedElements().addToSelectionOnMouseUp (this, e.mods, dragging, mouseDownSelectStatus); | |||
| } | |||
| void PaintElement::resizeStart() | |||
| { | |||
| if (getHeight() > 0) | |||
| originalAspectRatio = getWidth() / (double) getHeight(); | |||
| else | |||
| originalAspectRatio = 1.0; | |||
| } | |||
| void PaintElement::resizeEnd() | |||
| { | |||
| } | |||
| void PaintElement::checkBounds (Rectangle<int>& bounds, | |||
| const Rectangle<int>& previousBounds, | |||
| const Rectangle<int>& limits, | |||
| const bool isStretchingTop, | |||
| const bool isStretchingLeft, | |||
| const bool isStretchingBottom, | |||
| const bool isStretchingRight) | |||
| { | |||
| if (ModifierKeys::getCurrentModifiers().isShiftDown()) | |||
| setFixedAspectRatio (originalAspectRatio); | |||
| else | |||
| setFixedAspectRatio (0.0); | |||
| ComponentBoundsConstrainer::checkBounds (bounds, previousBounds, limits, isStretchingTop, isStretchingLeft, isStretchingBottom, isStretchingRight); | |||
| JucerDocument* document = getDocument(); | |||
| if (document != nullptr && document->isSnapActive (true)) | |||
| { | |||
| jassert (getParentComponent() != nullptr); | |||
| const Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| int x = bounds.getX(); | |||
| int y = bounds.getY(); | |||
| int w = bounds.getWidth(); | |||
| int h = bounds.getHeight(); | |||
| x += borderThickness - area.getX(); | |||
| y += borderThickness - area.getY(); | |||
| w -= borderThickness * 2; | |||
| h -= borderThickness * 2; | |||
| int right = x + w; | |||
| int bottom = y + h; | |||
| if (isStretchingRight) | |||
| right = document->snapPosition (right); | |||
| if (isStretchingBottom) | |||
| bottom = document->snapPosition (bottom); | |||
| if (isStretchingLeft) | |||
| x = document->snapPosition (x); | |||
| if (isStretchingTop) | |||
| y = document->snapPosition (y); | |||
| w = (right - x) + borderThickness * 2; | |||
| h = (bottom - y) + borderThickness * 2; | |||
| x -= borderThickness - area.getX(); | |||
| y -= borderThickness - area.getY(); | |||
| bounds = Rectangle<int> (x, y, w, h); | |||
| } | |||
| } | |||
| void PaintElement::applyBoundsToComponent (Component*, const Rectangle<int>& bounds) | |||
| { | |||
| if (getBounds() != bounds) | |||
| { | |||
| getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| jassert (dynamic_cast <PaintRoutineEditor*> (getParentComponent()) != nullptr); | |||
| setCurrentBounds (bounds.expanded (-borderThickness, -borderThickness), | |||
| ((PaintRoutineEditor*) getParentComponent())->getComponentArea(), | |||
| true); | |||
| } | |||
| } | |||
| Rectangle<int> PaintElement::getCurrentAbsoluteBounds() const | |||
| { | |||
| jassert (dynamic_cast <PaintRoutineEditor*> (getParentComponent()) != nullptr); | |||
| const Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| return position.getRectangle (area, getDocument()->getComponentLayout()); | |||
| } | |||
| void PaintElement::getCurrentAbsoluteBoundsDouble (double& x, double& y, double& w, double& h) const | |||
| { | |||
| jassert (dynamic_cast <PaintRoutineEditor*> (getParentComponent()) != nullptr); | |||
| const Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| position.getRectangleDouble (x, y, w, h, area, getDocument()->getComponentLayout()); | |||
| } | |||
| void PaintElement::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| const bool nowSelected = owner != nullptr && owner->getSelectedElements().isSelected (this); | |||
| if (selected != nowSelected) | |||
| { | |||
| selected = nowSelected; | |||
| border->setVisible (nowSelected); | |||
| repaint(); | |||
| selectionChanged (nowSelected); | |||
| } | |||
| updateSiblingComps(); | |||
| } | |||
| void PaintElement::selectionChanged (const bool /*isSelected*/) | |||
| { | |||
| } | |||
| void PaintElement::createSiblingComponents() | |||
| { | |||
| } | |||
| void PaintElement::siblingComponentsChanged() | |||
| { | |||
| siblingComponents.clear(); | |||
| selfChangeListenerList.sendChangeMessage(); | |||
| } | |||
| void PaintElement::updateSiblingComps() | |||
| { | |||
| if (selected && getParentComponent() != nullptr && owner->getSelectedElements().getNumSelected() == 1) | |||
| { | |||
| if (siblingComponents.size() == 0) | |||
| createSiblingComponents(); | |||
| for (int i = siblingComponents.size(); --i >= 0;) | |||
| siblingComponents.getUnchecked(i)->updatePosition(); | |||
| } | |||
| else | |||
| { | |||
| siblingComponents.clear(); | |||
| } | |||
| } | |||
| void PaintElement::showPopupMenu() | |||
| { | |||
| PopupMenu m; | |||
| m.addCommandItem (commandManager, JucerCommandIDs::toFront); | |||
| m.addCommandItem (commandManager, JucerCommandIDs::toBack); | |||
| m.addSeparator(); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::cut); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::copy); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::paste); | |||
| m.addCommandItem (commandManager, StandardApplicationCommandIDs::del); | |||
| m.show(); | |||
| } | |||
| @@ -0,0 +1,137 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENT_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENT_JUCEHEADER__ | |||
| #include "../jucer_GeneratedCode.h" | |||
| #include "../ui/jucer_RelativePositionedRectangle.h" | |||
| class FillType; | |||
| class PaintRoutine; | |||
| class JucerDocument; | |||
| class ElementSiblingComponent; | |||
| //============================================================================== | |||
| /** | |||
| Base class for objects that can be used in a PaintRoutine. | |||
| */ | |||
| class PaintElement : public Component, | |||
| public ChangeListener, | |||
| public ComponentBoundsConstrainer | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| PaintElement (PaintRoutine* owner, const String& typeName); | |||
| virtual ~PaintElement(); | |||
| //============================================================================== | |||
| virtual void setInitialBounds (int parentWidth, int parentHeight); | |||
| virtual Rectangle<int> getCurrentBounds (const Rectangle<int>& activeArea) const; | |||
| virtual void setCurrentBounds (const Rectangle<int>& newBounds, const Rectangle<int>& activeArea, const bool undoable); | |||
| const RelativePositionedRectangle& getPosition() const; | |||
| void setPosition (const RelativePositionedRectangle& newPosition, const bool undoable); | |||
| void updateBounds (const Rectangle<int>& activeArea); | |||
| const String& getTypeName() const noexcept { return typeName; } | |||
| PaintRoutine* getOwner() const noexcept { return owner; } | |||
| //============================================================================== | |||
| virtual void draw (Graphics& g, | |||
| const ComponentLayout* layout, | |||
| const Rectangle<int>& parentArea) = 0; | |||
| virtual void drawExtraEditorGraphics (Graphics& g, const Rectangle<int>& relativeTo); | |||
| virtual void getEditableProperties (Array <PropertyComponent*>& properties); | |||
| virtual void showPopupMenu(); | |||
| //============================================================================== | |||
| virtual XmlElement* createXml() const = 0; | |||
| virtual bool loadFromXml (const XmlElement& xml) = 0; | |||
| //============================================================================== | |||
| virtual void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) = 0; | |||
| JucerDocument* getDocument() const; | |||
| virtual void changed(); | |||
| bool perform (UndoableAction* action, const String& actionName); | |||
| //============================================================================== | |||
| void paint (Graphics& g); | |||
| void resized(); | |||
| void mouseDown (const MouseEvent& e); | |||
| void mouseDrag (const MouseEvent& e); | |||
| void mouseUp (const MouseEvent& e); | |||
| void changeListenerCallback (ChangeBroadcaster*); | |||
| void parentHierarchyChanged(); | |||
| int borderThickness; | |||
| protected: | |||
| PaintRoutine* const owner; | |||
| RelativePositionedRectangle position; | |||
| void resizeStart(); | |||
| void resizeEnd(); | |||
| void checkBounds (Rectangle<int>& bounds, | |||
| const Rectangle<int>& previousBounds, | |||
| const Rectangle<int>& limits, | |||
| bool isStretchingTop, | |||
| bool isStretchingLeft, | |||
| bool isStretchingBottom, | |||
| bool isStretchingRight); | |||
| void applyBoundsToComponent (Component* component, const Rectangle<int>& bounds); | |||
| Rectangle<int> getCurrentAbsoluteBounds() const; | |||
| void getCurrentAbsoluteBoundsDouble (double& x, double& y, double& w, double& h) const; | |||
| virtual void selectionChanged (const bool isSelected); | |||
| virtual void createSiblingComponents(); | |||
| void siblingComponentsChanged(); | |||
| OwnedArray <ElementSiblingComponent> siblingComponents; | |||
| void updateSiblingComps(); | |||
| private: | |||
| ScopedPointer<ResizableBorderComponent> border; | |||
| String typeName; | |||
| bool selected, dragging, mouseDownSelectStatus; | |||
| double originalAspectRatio; | |||
| ChangeBroadcaster selfChangeListenerList; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENT_JUCEHEADER__ | |||
| @@ -0,0 +1,160 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTELLIPSE_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTELLIPSE_JUCEHEADER__ | |||
| #include "jucer_ColouredElement.h" | |||
| //============================================================================== | |||
| class PaintElementEllipse : public ColouredElement | |||
| { | |||
| public: | |||
| PaintElementEllipse (PaintRoutine* owner) | |||
| : ColouredElement (owner, "Ellipse", true, false) | |||
| { | |||
| } | |||
| void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) | |||
| { | |||
| fillType.setFillType (g, getDocument(), parentArea); | |||
| Rectangle<int> r (position.getRectangle (parentArea, layout)); | |||
| g.fillEllipse ((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight()); | |||
| if (isStrokePresent) | |||
| { | |||
| strokeType.fill.setFillType (g, getDocument(), parentArea); | |||
| g.drawEllipse ((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight(), | |||
| getStrokeType().stroke.getStrokeThickness()); | |||
| } | |||
| } | |||
| void getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| ColouredElement::getEditableProperties (properties); | |||
| properties.add (new ShapeToPathProperty (this)); | |||
| } | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) | |||
| { | |||
| if (! fillType.isInvisible()) | |||
| { | |||
| String x, y, w, h, s; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| fillType.fillInGeneratedCode (code, paintMethodCode); | |||
| s << "g.fillEllipse (" | |||
| << castToFloat (x) << ", " | |||
| << castToFloat (y) << ", " | |||
| << castToFloat (w) << ", " | |||
| << castToFloat (h) << ");\n\n"; | |||
| paintMethodCode += s; | |||
| } | |||
| if (isStrokePresent && ! strokeType.isInvisible()) | |||
| { | |||
| String x, y, w, h, s; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| strokeType.fill.fillInGeneratedCode (code, paintMethodCode); | |||
| s << "g.drawEllipse (" | |||
| << castToFloat (x) << ", " | |||
| << castToFloat (y) << ", " | |||
| << castToFloat (w) << ", " | |||
| << castToFloat (h) << ", " | |||
| << CodeHelpers::floatLiteral (strokeType.stroke.getStrokeThickness(), 3) << ");\n\n"; | |||
| paintMethodCode += s; | |||
| } | |||
| } | |||
| static const char* getTagName() noexcept { return "ELLIPSE"; } | |||
| XmlElement* createXml() const | |||
| { | |||
| XmlElement* e = new XmlElement (getTagName()); | |||
| position.applyToXml (*e); | |||
| addColourAttributes (e); | |||
| return e; | |||
| } | |||
| bool loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (getTagName())) | |||
| { | |||
| position.restoreFromXml (xml, position); | |||
| loadColourAttributes (xml); | |||
| return true; | |||
| } | |||
| jassertfalse; | |||
| return false; | |||
| } | |||
| void convertToPath() | |||
| { | |||
| double x, y, w, h; | |||
| getCurrentAbsoluteBoundsDouble (x, y, w, h); | |||
| Path path; | |||
| path.addEllipse ((float) x, (float) y, (float) w, (float) h); | |||
| convertToNewPathElement (path); | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| class ShapeToPathProperty : public ButtonPropertyComponent | |||
| { | |||
| public: | |||
| ShapeToPathProperty (PaintElementEllipse* const e) | |||
| : ButtonPropertyComponent ("path", false), | |||
| element (e) | |||
| { | |||
| } | |||
| void buttonClicked() | |||
| { | |||
| element->convertToPath(); | |||
| } | |||
| String getButtonText() const | |||
| { | |||
| return "convert to a path"; | |||
| } | |||
| private: | |||
| PaintElementEllipse* const element; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTELLIPSE_JUCEHEADER__ | |||
| @@ -0,0 +1,240 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTGROUP_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTGROUP_JUCEHEADER__ | |||
| #include "jucer_PaintElement.h" | |||
| #include "../jucer_ObjectTypes.h" | |||
| //============================================================================== | |||
| class PaintElementGroup : public PaintElement | |||
| { | |||
| public: | |||
| PaintElementGroup (PaintRoutine* owner) | |||
| : PaintElement (owner, "Group") | |||
| { | |||
| } | |||
| void ungroup (const bool undoable) | |||
| { | |||
| getOwner()->getSelectedElements().deselectAll(); | |||
| getOwner()->getSelectedPoints().deselectAll(); | |||
| const int index = getOwner()->indexOfElement (this); | |||
| for (int i = 0; i < subElements.size(); ++i) | |||
| { | |||
| ScopedPointer<XmlElement> xml (subElements.getUnchecked(i)->createXml()); | |||
| PaintElement* newOne = getOwner()->addElementFromXml (*xml, index, undoable); | |||
| getOwner()->getSelectedElements().addToSelection (newOne); | |||
| } | |||
| getOwner()->removeElement (this, undoable); | |||
| } | |||
| static void groupSelected (PaintRoutine* const routine) | |||
| { | |||
| if (routine->getSelectedElements().getNumSelected() > 1) | |||
| { | |||
| PaintElementGroup* newGroup = new PaintElementGroup (routine); | |||
| int frontIndex = -1; | |||
| for (int i = 0; i < routine->getNumElements(); ++i) | |||
| { | |||
| if (routine->getSelectedElements().isSelected (routine->getElement (i))) | |||
| { | |||
| ScopedPointer<XmlElement> xml (routine->getElement(i)->createXml()); | |||
| if (PaintElement* newOne = ObjectTypes::createElementForXml (xml, routine)) | |||
| newGroup->subElements.add (newOne); | |||
| if (i > frontIndex) | |||
| frontIndex = i; | |||
| } | |||
| } | |||
| routine->deleteSelected(); | |||
| PaintElement* const g = routine->addNewElement (newGroup, frontIndex, true); | |||
| routine->getSelectedElements().selectOnly (g); | |||
| } | |||
| } | |||
| int getNumElements() const noexcept { return subElements.size(); } | |||
| PaintElement* getElement (const int index) const noexcept { return subElements [index]; } | |||
| int indexOfElement (const PaintElement* element) const noexcept { return subElements.indexOf (element); } | |||
| bool containsElement (const PaintElement* element) const | |||
| { | |||
| if (subElements.contains (element)) | |||
| return true; | |||
| for (int i = subElements.size(); --i >= 0;) | |||
| if (PaintElementGroup* pg = dynamic_cast <PaintElementGroup*> (subElements.getUnchecked(i))) | |||
| if (pg->containsElement (element)) | |||
| return true; | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| void setInitialBounds (int /*parentWidth*/, int /*parentHeight*/) | |||
| { | |||
| } | |||
| Rectangle<int> getCurrentBounds (const Rectangle<int>& parentArea) const | |||
| { | |||
| Rectangle<int> r; | |||
| if (subElements.size() > 0) | |||
| { | |||
| r = subElements.getUnchecked(0)->getCurrentBounds (parentArea); | |||
| for (int i = 1; i < subElements.size(); ++i) | |||
| r = r.getUnion (subElements.getUnchecked(i)->getCurrentBounds (parentArea)); | |||
| } | |||
| return r; | |||
| } | |||
| void setCurrentBounds (const Rectangle<int>& b, const Rectangle<int>& parentArea, const bool undoable) | |||
| { | |||
| Rectangle<int> newBounds (b); | |||
| newBounds.setSize (jmax (1, newBounds.getWidth()), | |||
| jmax (1, newBounds.getHeight())); | |||
| const Rectangle<int> current (getCurrentBounds (parentArea)); | |||
| if (newBounds != current) | |||
| { | |||
| const int dx = newBounds.getX() - current.getX(); | |||
| const int dy = newBounds.getY() - current.getY(); | |||
| const double scaleStartX = current.getX(); | |||
| const double scaleStartY = current.getY(); | |||
| const double scaleX = newBounds.getWidth() / (double) current.getWidth(); | |||
| const double scaleY = newBounds.getHeight() / (double) current.getHeight(); | |||
| for (int i = 0; i < subElements.size(); ++i) | |||
| { | |||
| PaintElement* const e = subElements.getUnchecked(i); | |||
| Rectangle<int> pos (e->getCurrentBounds (parentArea)); | |||
| const int newX = roundToInt ((pos.getX() - scaleStartX) * scaleX + scaleStartX + dx); | |||
| const int newY = roundToInt ((pos.getY() - scaleStartY) * scaleY + scaleStartY + dy); | |||
| pos.setBounds (newX, newY, | |||
| roundToInt ((pos.getRight() - scaleStartX) * scaleX + scaleStartX + dx) - newX, | |||
| roundToInt ((pos.getBottom() - scaleStartY) * scaleY + scaleStartY + dy) - newY); | |||
| e->setCurrentBounds (pos, parentArea, undoable); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) | |||
| { | |||
| for (int i = 0; i < subElements.size(); ++i) | |||
| subElements.getUnchecked(i)->draw (g, layout, parentArea); | |||
| } | |||
| void getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| properties.add (new UngroupProperty (this)); | |||
| } | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) | |||
| { | |||
| for (int i = 0; i < subElements.size(); ++i) | |||
| subElements.getUnchecked(i)->fillInGeneratedCode (code, paintMethodCode); | |||
| } | |||
| static const char* getTagName() noexcept { return "GROUP"; } | |||
| XmlElement* createXml() const | |||
| { | |||
| XmlElement* e = new XmlElement (getTagName()); | |||
| for (int i = 0; i < subElements.size(); ++i) | |||
| { | |||
| XmlElement* const sub = subElements.getUnchecked(i)->createXml(); | |||
| e->addChildElement (sub); | |||
| } | |||
| return e; | |||
| } | |||
| bool loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (getTagName())) | |||
| { | |||
| forEachXmlChildElement (xml, e) | |||
| if (PaintElement* const pe = ObjectTypes::createElementForXml (e, owner)) | |||
| subElements.add (pe); | |||
| return true; | |||
| } | |||
| jassertfalse; | |||
| return false; | |||
| } | |||
| private: | |||
| OwnedArray <PaintElement> subElements; | |||
| class UngroupProperty : public ButtonPropertyComponent | |||
| { | |||
| public: | |||
| UngroupProperty (PaintElementGroup* const e) | |||
| : ButtonPropertyComponent ("ungroup", false), | |||
| element (e) | |||
| { | |||
| } | |||
| void buttonClicked() | |||
| { | |||
| element->ungroup (true); | |||
| } | |||
| String getButtonText() const | |||
| { | |||
| return "Ungroup"; | |||
| } | |||
| private: | |||
| PaintElementGroup* const element; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTGROUP_JUCEHEADER__ | |||
| @@ -0,0 +1,511 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTIMAGE_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTIMAGE_JUCEHEADER__ | |||
| #include "../jucer_PaintRoutine.h" | |||
| #include "../properties/jucer_FilePropertyComponent.h" | |||
| #include "jucer_ImageResourceProperty.h" | |||
| #include "jucer_PaintElementUndoableAction.h" | |||
| //============================================================================== | |||
| class PaintElementImage : public PaintElement | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| PaintElementImage (PaintRoutine* owner) | |||
| : PaintElement (owner, "Image"), | |||
| opacity (1.0), | |||
| mode (stretched) | |||
| { | |||
| } | |||
| enum StretchMode | |||
| { | |||
| stretched = 0, | |||
| proportional = 1, | |||
| proportionalReducingOnly = 2 | |||
| }; | |||
| const Drawable* getDrawable() | |||
| { | |||
| if (JucerDocument* const document = getDocument()) | |||
| return document->getResources().getDrawable (resourceName); | |||
| return nullptr; | |||
| } | |||
| void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) | |||
| { | |||
| const Rectangle<int> r (position.getRectangle (parentArea, layout)); | |||
| if (const Drawable* const image = getDrawable()) | |||
| { | |||
| image->drawWithin (g, r.toFloat(), | |||
| mode == stretched ? RectanglePlacement::stretchToFit | |||
| : (mode == proportionalReducingOnly ? (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize) | |||
| : RectanglePlacement::centred), | |||
| (float) opacity); | |||
| } | |||
| else | |||
| { | |||
| g.setColour (Colours::grey.withAlpha (0.5f)); | |||
| g.fillRect (r); | |||
| g.setColour (Colours::black); | |||
| g.drawText ("(image missing)", | |||
| r.getX(), r.getY(), r.getWidth(), r.getHeight(), | |||
| Justification::centred, true); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| PaintElement::getEditableProperties (properties); | |||
| properties.add (new ImageElementResourceProperty (this)); | |||
| properties.add (new StretchModeProperty (this)); | |||
| properties.add (new OpacityProperty (this)); | |||
| properties.add (new ResetSizeProperty (this)); | |||
| } | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) | |||
| { | |||
| String r; | |||
| if (opacity > 0) | |||
| { | |||
| if (dynamic_cast <const DrawableImage*> (getDrawable()) != 0) | |||
| { | |||
| const String imageVariable ("cachedImage_" + resourceName); | |||
| code.addImageResourceLoader (imageVariable, resourceName); | |||
| if (opacity >= 254.0 / 255.0) | |||
| r << "g.setColour (Colours::black);\n"; | |||
| else | |||
| r << "g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n"; | |||
| String x, y, w, h; | |||
| positionToCode (position, getDocument()->getComponentLayout(), x, y, w, h); | |||
| if (mode == stretched) | |||
| { | |||
| r << "g.drawImage (" << imageVariable << ",\n " | |||
| << x << ", " << y << ", " << w << ", " << h | |||
| << ",\n 0, 0, " | |||
| << imageVariable << ".getWidth(), " | |||
| << imageVariable << ".getHeight());\n\n"; | |||
| } | |||
| else | |||
| { | |||
| r << "g.drawImageWithin (" << imageVariable << ",\n " | |||
| << x << ", " << y << ", " << w << ", " << h | |||
| << ",\n "; | |||
| if (mode == proportionalReducingOnly) | |||
| r << "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize"; | |||
| else | |||
| r << "RectanglePlacement::centred"; | |||
| r << ",\n false);\n\n"; | |||
| } | |||
| paintMethodCode += r; | |||
| } | |||
| else | |||
| { | |||
| if (resourceName.isNotEmpty()) | |||
| { | |||
| const String imageVariable ("drawable" + String (code.getUniqueSuffix())); | |||
| code.privateMemberDeclarations | |||
| << "Drawable* " << imageVariable << ";\n"; | |||
| code.constructorCode | |||
| << imageVariable << " = Drawable::createFromImageData (" | |||
| << resourceName << ", " << resourceName << "Size);\n"; | |||
| code.destructorCode | |||
| << "deleteAndZero (" << imageVariable << ");\n"; | |||
| if (opacity >= 254.0 / 255.0) | |||
| r << "g.setColour (Colours::black);\n"; | |||
| else | |||
| r << "g.setColour (Colours::black.withAlpha (" << CodeHelpers::floatLiteral (opacity, 3) << "));\n"; | |||
| String x, y, w, h; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| r << "jassert (" << imageVariable << " != 0);\n" | |||
| << "if (" << imageVariable << " != 0)\n " | |||
| << imageVariable << "->drawWithin (g, Rectangle<float> (" | |||
| << x << ", " << y << ", " << w << ", " << h | |||
| << "),\n" | |||
| << String::repeatedString (" ", imageVariable.length() + 18) | |||
| << (mode == stretched ? "RectanglePlacement::stretchToFit" | |||
| : (mode == proportionalReducingOnly ? "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize" | |||
| : "RectanglePlacement::centred")) | |||
| << ", " << CodeHelpers::floatLiteral (opacity, 3) | |||
| << ");\n\n"; | |||
| paintMethodCode += r; | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // this resource isn't valid! | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class SetResourceAction : public PaintElementUndoableAction <PaintElementImage> | |||
| { | |||
| public: | |||
| SetResourceAction (PaintElementImage* const element, const String& newResource_) | |||
| : PaintElementUndoableAction <PaintElementImage> (element), | |||
| newResource (newResource_) | |||
| { | |||
| oldResource = element->getResource(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setResource (newResource, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setResource (oldResource, false); | |||
| return true; | |||
| } | |||
| private: | |||
| String newResource, oldResource; | |||
| }; | |||
| void setResource (const String& newName, const bool undoable) | |||
| { | |||
| if (resourceName != newName) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetResourceAction (this, newName), | |||
| "Change image resource"); | |||
| } | |||
| else | |||
| { | |||
| resourceName = newName; | |||
| changed(); | |||
| } | |||
| } | |||
| repaint(); | |||
| } | |||
| String getResource() const | |||
| { | |||
| return resourceName; | |||
| } | |||
| //============================================================================== | |||
| class SetOpacityAction : public PaintElementUndoableAction <PaintElementImage> | |||
| { | |||
| public: | |||
| SetOpacityAction (PaintElementImage* const element, const double newOpacity_) | |||
| : PaintElementUndoableAction <PaintElementImage> (element), | |||
| newOpacity (newOpacity_) | |||
| { | |||
| oldOpacity = element->getOpacity(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setOpacity (newOpacity, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setOpacity (oldOpacity, false); | |||
| return true; | |||
| } | |||
| private: | |||
| double newOpacity, oldOpacity; | |||
| }; | |||
| void setOpacity (double newOpacity, const bool undoable) | |||
| { | |||
| newOpacity = jlimit (0.0, 1.0, newOpacity); | |||
| if (opacity != newOpacity) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetOpacityAction (this, newOpacity), | |||
| "Change image opacity"); | |||
| } | |||
| else | |||
| { | |||
| opacity = newOpacity; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| double getOpacity() const noexcept { return opacity; } | |||
| //============================================================================== | |||
| static const char* getTagName() noexcept { return "IMAGE"; } | |||
| void resetToImageSize() | |||
| { | |||
| const Drawable* const image = getDrawable(); | |||
| if (image != nullptr && getParentComponent() != nullptr) | |||
| { | |||
| const Rectangle<int> parentArea (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| Rectangle<int> r (getCurrentBounds (parentArea)); | |||
| Rectangle<float> bounds (image->getDrawableBounds()); | |||
| r.setSize ((int) (bounds.getWidth() + 0.999f), (int) (bounds.getHeight() + 0.999f)); | |||
| setCurrentBounds (r, parentArea, true); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class SetStretchModeAction : public PaintElementUndoableAction <PaintElementImage> | |||
| { | |||
| public: | |||
| SetStretchModeAction (PaintElementImage* const element, const StretchMode newValue_) | |||
| : PaintElementUndoableAction <PaintElementImage> (element), | |||
| newValue (newValue_) | |||
| { | |||
| oldValue = element->getStretchMode(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setStretchMode (newValue, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setStretchMode (oldValue, false); | |||
| return true; | |||
| } | |||
| private: | |||
| StretchMode newValue, oldValue; | |||
| }; | |||
| StretchMode getStretchMode() const noexcept { return mode; } | |||
| void setStretchMode (const StretchMode newMode, const bool undoable) | |||
| { | |||
| if (mode != newMode) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetStretchModeAction (this, newMode), | |||
| "Change image mode"); | |||
| } | |||
| else | |||
| { | |||
| mode = newMode; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| XmlElement* createXml() const | |||
| { | |||
| XmlElement* e = new XmlElement (getTagName()); | |||
| position.applyToXml (*e); | |||
| e->setAttribute ("resource", resourceName); | |||
| e->setAttribute ("opacity", opacity); | |||
| e->setAttribute ("mode", (int) mode); | |||
| return e; | |||
| } | |||
| bool loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (getTagName())) | |||
| { | |||
| position.restoreFromXml (xml, position); | |||
| resourceName = xml.getStringAttribute ("resource", String::empty); | |||
| opacity = xml.getDoubleAttribute ("opacity", 1.0); | |||
| mode = (StretchMode) xml.getIntAttribute ("mode", (int) stretched); | |||
| repaint(); | |||
| return true; | |||
| } | |||
| jassertfalse; | |||
| return false; | |||
| } | |||
| private: | |||
| String resourceName; | |||
| double opacity; | |||
| StretchMode mode; | |||
| //============================================================================== | |||
| class ImageElementResourceProperty : public ImageResourceProperty <PaintElementImage> | |||
| { | |||
| public: | |||
| ImageElementResourceProperty (PaintElementImage* const e) | |||
| : ImageResourceProperty <PaintElementImage> (e, "image source") | |||
| { | |||
| } | |||
| void setResource (const String& newName) | |||
| { | |||
| element->setResource (newName, true); | |||
| } | |||
| String getResource() const | |||
| { | |||
| return element->getResource(); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| class OpacityProperty : public SliderPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| OpacityProperty (PaintElementImage* const e) | |||
| : SliderPropertyComponent ("opacity", 0.0, 1.0, 0.001), | |||
| element (e) | |||
| { | |||
| element->getDocument()->addChangeListener (this); | |||
| } | |||
| ~OpacityProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| element->getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| element->setOpacity (newValue, true); | |||
| } | |||
| double getValue() const | |||
| { | |||
| return element->getOpacity(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| PaintElementImage* const element; | |||
| }; | |||
| class StretchModeProperty : public ChoicePropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| StretchModeProperty (PaintElementImage* const e) | |||
| : ChoicePropertyComponent ("stretch mode"), | |||
| element (e) | |||
| { | |||
| choices.add ("Stretched to fit"); | |||
| choices.add ("Maintain aspect ratio"); | |||
| choices.add ("Maintain aspect ratio, only reduce in size"); | |||
| element->getDocument()->addChangeListener (this); | |||
| } | |||
| ~StretchModeProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| element->setStretchMode ((StretchMode) newIndex, true); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| return (int) element->getStretchMode(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| private: | |||
| PaintElementImage* const element; | |||
| }; | |||
| class ResetSizeProperty : public ButtonPropertyComponent | |||
| { | |||
| public: | |||
| ResetSizeProperty (PaintElementImage* const e) | |||
| : ButtonPropertyComponent ("reset", false), | |||
| element (e) | |||
| { | |||
| } | |||
| void buttonClicked() | |||
| { | |||
| element->resetToImageSize(); | |||
| } | |||
| String getButtonText() const { return "reset to image size"; } | |||
| private: | |||
| PaintElementImage* const element; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTIMAGE_JUCEHEADER__ | |||
| @@ -0,0 +1,177 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTPATH_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTPATH_JUCEHEADER__ | |||
| #include "jucer_ColouredElement.h" | |||
| #include "jucer_ElementSiblingComponent.h" | |||
| class PathPointComponent; | |||
| class PaintElementPath; | |||
| //============================================================================== | |||
| class PathPoint | |||
| { | |||
| public: | |||
| PathPoint (PaintElementPath* const owner); | |||
| PathPoint (const PathPoint& other); | |||
| PathPoint& operator= (const PathPoint& other); | |||
| ~PathPoint(); | |||
| PaintElementPath* owner; | |||
| Path::Iterator::PathElementType type; | |||
| RelativePositionedRectangle pos [3]; | |||
| int getNumPoints() const; | |||
| void changePointType (const Path::Iterator::PathElementType newType, | |||
| const Rectangle<int>& parentArea, | |||
| const bool undoable); | |||
| void deleteFromPath(); | |||
| void getEditableProperties (Array <PropertyComponent*>& properties); | |||
| private: | |||
| PathPoint withChangedPointType (const Path::Iterator::PathElementType newType, | |||
| const Rectangle<int>& parentArea) const; | |||
| }; | |||
| //============================================================================== | |||
| class PaintElementPath : public ColouredElement | |||
| { | |||
| public: | |||
| PaintElementPath (PaintRoutine* owner); | |||
| ~PaintElementPath(); | |||
| //============================================================================== | |||
| void setInitialBounds (int parentWidth, int parentHeight); | |||
| Rectangle<int> getCurrentBounds (const Rectangle<int>& parentArea) const; | |||
| void setCurrentBounds (const Rectangle<int>& b, const Rectangle<int>& parentArea, const bool undoable); | |||
| //============================================================================== | |||
| bool getPoint (int index, int pointNumber, double& x, double& y, const Rectangle<int>& parentArea) const; | |||
| void movePoint (int index, int pointNumber, double newX, double newY, const Rectangle<int>& parentArea, const bool undoable); | |||
| RelativePositionedRectangle getPoint (int index, int pointNumber) const; | |||
| void setPoint (int index, int pointNumber, const RelativePositionedRectangle& newPoint, const bool undoable); | |||
| int getNumPoints() const noexcept { return points.size(); } | |||
| PathPoint* getPoint (int index) const noexcept { return points [index]; } | |||
| int indexOfPoint (PathPoint* const p) const noexcept { return points.indexOf (p); } | |||
| PathPoint* addPoint (int pointIndexToAddItAfter, const bool undoable); | |||
| void deletePoint (int pointIndex, const bool undoable); | |||
| void pointListChanged(); | |||
| int findSegmentAtXY (int x, int y) const; | |||
| //============================================================================== | |||
| bool isSubpathClosed (int pointIndex) const; | |||
| void setSubpathClosed (int pointIndex, const bool closed, const bool undoable); | |||
| bool isNonZeroWinding() const noexcept { return nonZeroWinding; } | |||
| void setNonZeroWinding (const bool nonZero, const bool undoable); | |||
| //============================================================================== | |||
| void getEditableProperties (Array <PropertyComponent*>& properties); | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode); | |||
| //============================================================================== | |||
| static const char* getTagName() noexcept { return "PATH"; } | |||
| XmlElement* createXml() const; | |||
| bool loadFromXml (const XmlElement& xml); | |||
| void setToPath (const Path& p); | |||
| //============================================================================== | |||
| void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea); | |||
| void drawExtraEditorGraphics (Graphics& g, const Rectangle<int>& relativeTo); | |||
| void resized(); | |||
| void parentSizeChanged(); | |||
| void mouseDown (const MouseEvent& e); | |||
| void mouseDrag (const MouseEvent& e); | |||
| void mouseUp (const MouseEvent& e); | |||
| void createSiblingComponents(); | |||
| void changed(); | |||
| private: | |||
| friend class PathPoint; | |||
| friend class PathPointComponent; | |||
| OwnedArray <PathPoint> points; | |||
| bool nonZeroWinding; | |||
| mutable Path path; | |||
| mutable Rectangle<int> lastPathBounds; | |||
| int mouseDownOnSegment; | |||
| bool mouseDownSelectSegmentStatus; | |||
| String pathToString() const; | |||
| void restorePathFromString (const String& s); | |||
| void updateStoredPath (const ComponentLayout* layout, const Rectangle<int>& parentArea) const; | |||
| int getBorderSize() const; | |||
| void rescalePoint (RelativePositionedRectangle& pos, int dx, int dy, | |||
| double scaleX, double scaleY, | |||
| double scaleStartX, double scaleStartY, | |||
| const Rectangle<int>& parentArea) const; | |||
| }; | |||
| //============================================================================== | |||
| class PathPointComponent : public ElementSiblingComponent | |||
| { | |||
| public: | |||
| PathPointComponent (PaintElementPath* const path_, | |||
| const int index, const int pointNumber); | |||
| ~PathPointComponent(); | |||
| void updatePosition(); | |||
| void showPopupMenu(); | |||
| void paint (Graphics& g); | |||
| void mouseDown (const MouseEvent& e); | |||
| void mouseDrag (const MouseEvent& e); | |||
| void mouseUp (const MouseEvent& e); | |||
| void changeListenerCallback (ChangeBroadcaster*); | |||
| private: | |||
| PaintElementPath* const path; | |||
| PaintRoutine* const routine; | |||
| const int index; | |||
| const int pointNumber; | |||
| int dragX, dragY; | |||
| bool selected, dragging, mouseDownSelectStatus; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTPATH_JUCEHEADER__ | |||
| @@ -0,0 +1,165 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTRECTANGLE_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTRECTANGLE_JUCEHEADER__ | |||
| #include "jucer_ColouredElement.h" | |||
| //============================================================================== | |||
| class PaintElementRectangle : public ColouredElement | |||
| { | |||
| public: | |||
| PaintElementRectangle (PaintRoutine* owner) | |||
| : ColouredElement (owner, "Rectangle", true, false) | |||
| { | |||
| } | |||
| Rectangle<int> getCurrentBounds (const Rectangle<int>& parentArea) const | |||
| { | |||
| return PaintElement::getCurrentBounds (parentArea); // bypass the ColouredElement implementation | |||
| } | |||
| void setCurrentBounds (const Rectangle<int>& newBounds, const Rectangle<int>& parentArea, const bool undoable) | |||
| { | |||
| PaintElement::setCurrentBounds (newBounds, parentArea, undoable); // bypass the ColouredElement implementation | |||
| } | |||
| void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) | |||
| { | |||
| Component parentComponent; | |||
| parentComponent.setBounds (parentArea); | |||
| fillType.setFillType (g, getDocument(), parentArea); | |||
| const Rectangle<int> r (position.getRectangle (parentArea, layout)); | |||
| g.fillRect (r); | |||
| if (isStrokePresent) | |||
| { | |||
| strokeType.fill.setFillType (g, getDocument(), parentArea); | |||
| g.drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight(), | |||
| roundToInt (getStrokeType().stroke.getStrokeThickness())); | |||
| } | |||
| } | |||
| void getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| ColouredElement::getEditableProperties (properties); | |||
| properties.add (new ShapeToPathProperty (this)); | |||
| } | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) | |||
| { | |||
| if (! fillType.isInvisible()) | |||
| { | |||
| String x, y, w, h, s; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| fillType.fillInGeneratedCode (code, paintMethodCode); | |||
| s << "g.fillRect (" << x << ", " << y << ", " << w << ", " << h << ");\n\n"; | |||
| paintMethodCode += s; | |||
| } | |||
| if (isStrokePresent && ! strokeType.isInvisible()) | |||
| { | |||
| String x, y, w, h, s; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| strokeType.fill.fillInGeneratedCode (code, paintMethodCode); | |||
| s << "g.drawRect (" << x << ", " << y << ", " << w << ", " << h << ", " | |||
| << roundToInt (strokeType.stroke.getStrokeThickness()) << ");\n\n"; | |||
| paintMethodCode += s; | |||
| } | |||
| } | |||
| static const char* getTagName() noexcept { return "RECT"; } | |||
| XmlElement* createXml() const | |||
| { | |||
| XmlElement* e = new XmlElement (getTagName()); | |||
| position.applyToXml (*e); | |||
| addColourAttributes (e); | |||
| return e; | |||
| } | |||
| bool loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (getTagName())) | |||
| { | |||
| position.restoreFromXml (xml, position); | |||
| loadColourAttributes (xml); | |||
| return true; | |||
| } | |||
| jassertfalse; | |||
| return false; | |||
| } | |||
| void convertToPath() | |||
| { | |||
| const Rectangle<int> r (getCurrentAbsoluteBounds()); | |||
| Path path; | |||
| path.addRectangle ((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight()); | |||
| convertToNewPathElement (path); | |||
| } | |||
| private: | |||
| class ShapeToPathProperty : public ButtonPropertyComponent | |||
| { | |||
| public: | |||
| ShapeToPathProperty (PaintElementRectangle* const e) | |||
| : ButtonPropertyComponent ("path", false), | |||
| element (e) | |||
| { | |||
| } | |||
| void buttonClicked() | |||
| { | |||
| element->convertToPath(); | |||
| } | |||
| String getButtonText() const | |||
| { | |||
| return "convert to a path"; | |||
| } | |||
| private: | |||
| PaintElementRectangle* const element; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTRECTANGLE_JUCEHEADER__ | |||
| @@ -0,0 +1,253 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTROUNDEDRECTANGLE_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTROUNDEDRECTANGLE_JUCEHEADER__ | |||
| #include "jucer_ColouredElement.h" | |||
| #include "../jucer_UtilityFunctions.h" | |||
| //============================================================================== | |||
| class PaintElementRoundedRectangle : public ColouredElement | |||
| { | |||
| public: | |||
| PaintElementRoundedRectangle (PaintRoutine* owner) | |||
| : ColouredElement (owner, "Rounded Rectangle", true, false) | |||
| { | |||
| cornerSize = 10.0; | |||
| } | |||
| void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) | |||
| { | |||
| double x, y, w, h; | |||
| position.getRectangleDouble (x, y, w, h, parentArea, layout); | |||
| fillType.setFillType (g, getDocument(), parentArea); | |||
| g.fillRoundedRectangle ((float) x, (float) y, (float) w, (float) h, (float) cornerSize); | |||
| if (isStrokePresent) | |||
| { | |||
| strokeType.fill.setFillType (g, getDocument(), parentArea); | |||
| g.drawRoundedRectangle ((float) x, (float) y, (float) w, (float) h, (float) cornerSize, | |||
| getStrokeType().stroke.getStrokeThickness()); | |||
| } | |||
| } | |||
| void getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| properties.add (new CornerSizeProperty (this)); | |||
| ColouredElement::getEditableProperties (properties); | |||
| properties.add (new ShapeToPathProperty (this)); | |||
| } | |||
| //============================================================================== | |||
| class SetCornerSizeAction : public PaintElementUndoableAction <PaintElementRoundedRectangle> | |||
| { | |||
| public: | |||
| SetCornerSizeAction (PaintElementRoundedRectangle* const element, const double newSize_) | |||
| : PaintElementUndoableAction <PaintElementRoundedRectangle> (element), | |||
| newSize (newSize_) | |||
| { | |||
| oldSize = element->getCornerSize(); | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setCornerSize (newSize, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setCornerSize (oldSize, false); | |||
| return true; | |||
| } | |||
| private: | |||
| double newSize, oldSize; | |||
| }; | |||
| void setCornerSize (const double newSize, const bool undoable) | |||
| { | |||
| if (newSize != cornerSize) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetCornerSizeAction (this, newSize), | |||
| "Change rounded rectangle corner size"); | |||
| } | |||
| else | |||
| { | |||
| cornerSize = newSize; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| double getCornerSize() const noexcept { return cornerSize; } | |||
| //============================================================================== | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) | |||
| { | |||
| if (! fillType.isInvisible()) | |||
| { | |||
| String x, y, w, h, s; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| fillType.fillInGeneratedCode (code, paintMethodCode); | |||
| s << "g.fillRoundedRectangle (" | |||
| << castToFloat (x) << ", " | |||
| << castToFloat (y) << ", " | |||
| << castToFloat (w) << ", " | |||
| << castToFloat (h) << ", " | |||
| << CodeHelpers::floatLiteral (cornerSize, 3) << ");\n\n"; | |||
| paintMethodCode += s; | |||
| } | |||
| if (isStrokePresent && ! strokeType.isInvisible()) | |||
| { | |||
| String x, y, w, h, s; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| strokeType.fill.fillInGeneratedCode (code, paintMethodCode); | |||
| s << "g.drawRoundedRectangle (" | |||
| << castToFloat (x) << ", " | |||
| << castToFloat (y) << ", " | |||
| << castToFloat (w) << ", " | |||
| << castToFloat (h) << ", " | |||
| << CodeHelpers::floatLiteral (cornerSize, 3) << ", " | |||
| << CodeHelpers::floatLiteral (strokeType.stroke.getStrokeThickness(), 3) << ");\n\n"; | |||
| paintMethodCode += s; | |||
| } | |||
| } | |||
| static const char* getTagName() noexcept { return "ROUNDRECT"; } | |||
| XmlElement* createXml() const | |||
| { | |||
| XmlElement* const e = new XmlElement (getTagName()); | |||
| position.applyToXml (*e); | |||
| e->setAttribute ("cornerSize", cornerSize); | |||
| addColourAttributes (e); | |||
| return e; | |||
| } | |||
| bool loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (getTagName())) | |||
| { | |||
| position.restoreFromXml (xml, position); | |||
| cornerSize = xml.getDoubleAttribute ("cornerSize", 10.0); | |||
| loadColourAttributes (xml); | |||
| return true; | |||
| } | |||
| jassertfalse; | |||
| return false; | |||
| } | |||
| void convertToPath() | |||
| { | |||
| double x, y, w, h; | |||
| getCurrentAbsoluteBoundsDouble (x, y, w, h); | |||
| Path path; | |||
| path.addRoundedRectangle ((float) x, (float) y, (float) w, (float) h, (float) cornerSize); | |||
| convertToNewPathElement (path); | |||
| } | |||
| private: | |||
| double cornerSize; | |||
| //============================================================================== | |||
| class CornerSizeProperty : public SliderPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| CornerSizeProperty (PaintElementRoundedRectangle* const owner_) | |||
| : SliderPropertyComponent ("corner size", 1.0, 200.0, 0.5, 0.4), | |||
| owner (owner_) | |||
| { | |||
| owner->getDocument()->addChangeListener (this); | |||
| } | |||
| ~CornerSizeProperty() | |||
| { | |||
| owner->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| owner->getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| owner->setCornerSize (newValue, true); | |||
| } | |||
| double getValue() const { return owner->getCornerSize(); } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| PaintElementRoundedRectangle* const owner; | |||
| }; | |||
| //============================================================================== | |||
| class ShapeToPathProperty : public ButtonPropertyComponent | |||
| { | |||
| public: | |||
| ShapeToPathProperty (PaintElementRoundedRectangle* const e) | |||
| : ButtonPropertyComponent ("path", false), | |||
| element (e) | |||
| { | |||
| } | |||
| void buttonClicked() | |||
| { | |||
| element->convertToPath(); | |||
| } | |||
| String getButtonText() const | |||
| { | |||
| return "convert to a path"; | |||
| } | |||
| private: | |||
| PaintElementRoundedRectangle* const element; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTROUNDEDRECTANGLE_JUCEHEADER__ | |||
| @@ -0,0 +1,562 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTTEXT_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTTEXT_JUCEHEADER__ | |||
| #include "jucer_ColouredElement.h" | |||
| #include "../properties/jucer_FontPropertyComponent.h" | |||
| #include "../properties/jucer_JustificationProperty.h" | |||
| //============================================================================== | |||
| class PaintElementText : public ColouredElement | |||
| { | |||
| public: | |||
| PaintElementText (PaintRoutine* owner) | |||
| : ColouredElement (owner, "Text", false, false), | |||
| text ("Your text goes here"), | |||
| font (15.0f), | |||
| typefaceName (FontPropertyComponent::getDefaultFont()), | |||
| justification (Justification::centred) | |||
| { | |||
| fillType.colour = Colours::black; | |||
| position.rect.setWidth (200); | |||
| position.rect.setHeight (30); | |||
| } | |||
| //============================================================================== | |||
| void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) | |||
| { | |||
| fillType.setFillType (g, getDocument(), parentArea); | |||
| font = FontPropertyComponent::applyNameToFont (typefaceName, font); | |||
| g.setFont (font); | |||
| g.drawText (replaceStringTranslations (text, owner->getDocument()), | |||
| position.getRectangle (parentArea, layout), justification, true); | |||
| } | |||
| static String replaceStringTranslations (String s, JucerDocument* document) | |||
| { | |||
| s = s.replace ("%%getName()%%", document->getComponentName()); | |||
| s = s.replace ("%%getButtonText()%%", document->getComponentName()); | |||
| return s; | |||
| } | |||
| void getEditableProperties (Array <PropertyComponent*>& properties) | |||
| { | |||
| ColouredElement::getEditableProperties (properties); | |||
| properties.add (new TextProperty (this)); | |||
| properties.add (new FontNameProperty (this)); | |||
| properties.add (new FontStyleProperty (this)); | |||
| properties.add (new FontSizeProperty (this)); | |||
| properties.add (new TextJustificationProperty (this)); | |||
| properties.add (new TextToPathProperty (this)); | |||
| } | |||
| void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) | |||
| { | |||
| if (! fillType.isInvisible()) | |||
| { | |||
| String r; | |||
| fillType.fillInGeneratedCode (code, paintMethodCode); | |||
| String x, y, w, h; | |||
| positionToCode (position, code.document->getComponentLayout(), x, y, w, h); | |||
| r << "g.setFont (" | |||
| << FontPropertyComponent::getCompleteFontCode (font, typefaceName) | |||
| << ");\ng.drawText (" | |||
| << quotedString (text) | |||
| << ",\n " | |||
| << x << ", " << y << ", " << w << ", " << h | |||
| << ",\n " | |||
| << CodeHelpers::justificationToCode (justification) | |||
| << ", true);\n\n"; | |||
| paintMethodCode += r; | |||
| } | |||
| } | |||
| static const char* getTagName() noexcept { return "TEXT"; } | |||
| XmlElement* createXml() const | |||
| { | |||
| XmlElement* e = new XmlElement (getTagName()); | |||
| position.applyToXml (*e); | |||
| addColourAttributes (e); | |||
| e->setAttribute ("text", text); | |||
| e->setAttribute ("fontname", typefaceName); | |||
| e->setAttribute ("fontsize", roundToInt (font.getHeight() * 100.0) / 100.0); | |||
| e->setAttribute ("bold", font.isBold()); | |||
| e->setAttribute ("italic", font.isItalic()); | |||
| e->setAttribute ("justification", justification.getFlags()); | |||
| return e; | |||
| } | |||
| bool loadFromXml (const XmlElement& xml) | |||
| { | |||
| if (xml.hasTagName (getTagName())) | |||
| { | |||
| position.restoreFromXml (xml, position); | |||
| loadColourAttributes (xml); | |||
| text = xml.getStringAttribute ("text", "Hello World"); | |||
| typefaceName = xml.getStringAttribute ("fontname", FontPropertyComponent::getDefaultFont()); | |||
| font.setHeight ((float) xml.getDoubleAttribute ("fontsize", 15.0)); | |||
| font.setBold (xml.getBoolAttribute ("bold", false)); | |||
| font.setItalic (xml.getBoolAttribute ("italic", false)); | |||
| justification = Justification (xml.getIntAttribute ("justification", Justification::centred)); | |||
| return true; | |||
| } | |||
| jassertfalse; | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| const String& getText() const noexcept { return text; } | |||
| class SetTextAction : public PaintElementUndoableAction <PaintElementText> | |||
| { | |||
| public: | |||
| SetTextAction (PaintElementText* const element, const String& newText_) | |||
| : PaintElementUndoableAction <PaintElementText> (element), | |||
| newText (newText_), | |||
| oldText (element->getText()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setText (newText, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setText (oldText, false); | |||
| return true; | |||
| } | |||
| private: | |||
| String newText, oldText; | |||
| }; | |||
| void setText (const String& t, const bool undoable) | |||
| { | |||
| if (t != text) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetTextAction (this, t), | |||
| "Change text element text"); | |||
| } | |||
| else | |||
| { | |||
| text = t; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| const Font& getFont() const { return font; } | |||
| class SetFontAction : public PaintElementUndoableAction <PaintElementText> | |||
| { | |||
| public: | |||
| SetFontAction (PaintElementText* const element, const Font& newFont_) | |||
| : PaintElementUndoableAction <PaintElementText> (element), | |||
| newFont (newFont_), | |||
| oldFont (element->getFont()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setFont (newFont, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setFont (oldFont, false); | |||
| return true; | |||
| } | |||
| private: | |||
| Font newFont, oldFont; | |||
| }; | |||
| void setFont (const Font& newFont, const bool undoable) | |||
| { | |||
| if (font != newFont) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetFontAction (this, newFont), | |||
| "Change text element font"); | |||
| } | |||
| else | |||
| { | |||
| font = newFont; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class SetTypefaceAction : public PaintElementUndoableAction <PaintElementText> | |||
| { | |||
| public: | |||
| SetTypefaceAction (PaintElementText* const element, const String& newValue_) | |||
| : PaintElementUndoableAction <PaintElementText> (element), | |||
| newValue (newValue_), | |||
| oldValue (element->getTypefaceName()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setTypefaceName (newValue, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setTypefaceName (oldValue, false); | |||
| return true; | |||
| } | |||
| private: | |||
| String newValue, oldValue; | |||
| }; | |||
| void setTypefaceName (const String& newFontName, const bool undoable) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetTypefaceAction (this, newFontName), | |||
| "Change text element typeface"); | |||
| } | |||
| else | |||
| { | |||
| typefaceName = newFontName; | |||
| changed(); | |||
| } | |||
| } | |||
| String getTypefaceName() const noexcept { return typefaceName; } | |||
| //============================================================================== | |||
| const Justification& getJustification() const noexcept { return justification; } | |||
| class SetJustifyAction : public PaintElementUndoableAction <PaintElementText> | |||
| { | |||
| public: | |||
| SetJustifyAction (PaintElementText* const element, const Justification& newValue_) | |||
| : PaintElementUndoableAction <PaintElementText> (element), | |||
| newValue (newValue_), | |||
| oldValue (element->getJustification()) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setJustification (newValue, false); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| getElement()->setJustification (oldValue, false); | |||
| return true; | |||
| } | |||
| private: | |||
| Justification newValue, oldValue; | |||
| }; | |||
| void setJustification (const Justification& j, const bool undoable) | |||
| { | |||
| if (justification.getFlags() != j.getFlags()) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new SetJustifyAction (this, j), | |||
| "Change text element justification"); | |||
| } | |||
| else | |||
| { | |||
| justification = j; | |||
| changed(); | |||
| } | |||
| } | |||
| } | |||
| void convertToPath() | |||
| { | |||
| font = FontPropertyComponent::applyNameToFont (typefaceName, font); | |||
| const Rectangle<int> r (getCurrentAbsoluteBounds()); | |||
| GlyphArrangement arr; | |||
| arr.addCurtailedLineOfText (font, text, | |||
| 0.0f, 0.0f, (float) r.getWidth(), | |||
| true); | |||
| arr.justifyGlyphs (0, arr.getNumGlyphs(), | |||
| (float) r.getX(), (float) r.getY(), | |||
| (float) r.getWidth(), (float) r.getHeight(), | |||
| justification); | |||
| Path path; | |||
| arr.createPath (path); | |||
| convertToNewPathElement (path); | |||
| } | |||
| private: | |||
| String text; | |||
| Font font; | |||
| String typefaceName; | |||
| Justification justification; | |||
| Array <Justification> justificationTypes; | |||
| //============================================================================== | |||
| class TextProperty : public TextPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| TextProperty (PaintElementText* const e) | |||
| : TextPropertyComponent ("text", 2048, false), | |||
| element (e) | |||
| { | |||
| element->getDocument()->addChangeListener (this); | |||
| } | |||
| ~TextProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setText (const String& newText) { element->setText (newText, true); } | |||
| String getText() const { return element->getText(); } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| PaintElementText* const element; | |||
| }; | |||
| //============================================================================== | |||
| class FontNameProperty : public FontPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| FontNameProperty (PaintElementText* const e) | |||
| : FontPropertyComponent ("font"), | |||
| element (e) | |||
| { | |||
| element->getDocument()->addChangeListener (this); | |||
| } | |||
| ~FontNameProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setTypefaceName (const String& newFontName) { element->setTypefaceName (newFontName, true); } | |||
| String getTypefaceName() const { return element->getTypefaceName(); } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| PaintElementText* const element; | |||
| }; | |||
| //============================================================================== | |||
| class FontStyleProperty : public ChoicePropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| FontStyleProperty (PaintElementText* const e) | |||
| : ChoicePropertyComponent ("style"), | |||
| element (e) | |||
| { | |||
| element->getDocument()->addChangeListener (this); | |||
| choices.add ("normal"); | |||
| choices.add ("bold"); | |||
| choices.add ("italic"); | |||
| choices.add ("bold + italic"); | |||
| } | |||
| ~FontStyleProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setIndex (int newIndex) | |||
| { | |||
| Font f (element->getFont()); | |||
| f.setBold (newIndex == 1 || newIndex == 3); | |||
| f.setItalic (newIndex == 2 || newIndex == 3); | |||
| element->setFont (f, true); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| if (element->getFont().isBold() && element->getFont().isItalic()) | |||
| return 3; | |||
| else if (element->getFont().isBold()) | |||
| return 1; | |||
| else if (element->getFont().isItalic()) | |||
| return 2; | |||
| return 0; | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| PaintElementText* const element; | |||
| }; | |||
| //============================================================================== | |||
| class FontSizeProperty : public SliderPropertyComponent, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| FontSizeProperty (PaintElementText* const e) | |||
| : SliderPropertyComponent ("size", 1.0, 250.0, 0.1, 0.3), | |||
| element (e) | |||
| { | |||
| element->getDocument()->addChangeListener (this); | |||
| } | |||
| ~FontSizeProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setValue (double newValue) | |||
| { | |||
| element->getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| Font f (element->getFont()); | |||
| f.setHeight ((float) newValue); | |||
| element->setFont (f, true); | |||
| } | |||
| double getValue() const | |||
| { | |||
| return element->getFont().getHeight(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| PaintElementText* const element; | |||
| }; | |||
| //============================================================================== | |||
| class TextJustificationProperty : public JustificationProperty, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| TextJustificationProperty (PaintElementText* const e) | |||
| : JustificationProperty ("layout", false), | |||
| element (e) | |||
| { | |||
| element->getDocument()->addChangeListener (this); | |||
| } | |||
| ~TextJustificationProperty() | |||
| { | |||
| element->getDocument()->removeChangeListener (this); | |||
| } | |||
| void setJustification (const Justification& newJustification) | |||
| { | |||
| element->setJustification (newJustification, true); | |||
| } | |||
| const Justification getJustification() const | |||
| { | |||
| return element->getJustification(); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) { refresh(); } | |||
| private: | |||
| PaintElementText* const element; | |||
| }; | |||
| //============================================================================== | |||
| class TextToPathProperty : public ButtonPropertyComponent | |||
| { | |||
| public: | |||
| TextToPathProperty (PaintElementText* const e) | |||
| : ButtonPropertyComponent ("path", false), | |||
| element (e) | |||
| { | |||
| } | |||
| void buttonClicked() | |||
| { | |||
| element->convertToPath(); | |||
| } | |||
| String getButtonText() const | |||
| { | |||
| return "convert text to a path"; | |||
| } | |||
| private: | |||
| PaintElementText* const element; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTTEXT_JUCEHEADER__ | |||
| @@ -0,0 +1,143 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTELEMENTUNDOABLEACTION_JUCEHEADER__ | |||
| #define __JUCER_PAINTELEMENTUNDOABLEACTION_JUCEHEADER__ | |||
| #include "../ui/jucer_JucerDocumentEditor.h" | |||
| #include "jucer_PaintElementGroup.h" | |||
| //============================================================================== | |||
| template <class ElementType> | |||
| class PaintElementUndoableAction : public UndoableAction | |||
| { | |||
| public: | |||
| PaintElementUndoableAction (ElementType* const element) | |||
| : routine (*element->getOwner()), | |||
| elementIndex (element->getOwner()->indexOfElement (element)) | |||
| { | |||
| jassert (element != 0); | |||
| if (elementIndex < 0) | |||
| findGroupIndices (element->getOwner(), element); | |||
| jassert (elementIndex >= 0); | |||
| } | |||
| ElementType* getElement() const | |||
| { | |||
| if (containerGroups.size() > 0) | |||
| { | |||
| PaintElementGroup* group = 0; | |||
| group = dynamic_cast <PaintElementGroup*> (routine.getElement (containerGroups.getFirst())); | |||
| if (group == 0) | |||
| return 0; | |||
| for (int i = 1; i < containerGroups.size(); ++i) | |||
| { | |||
| group = dynamic_cast <PaintElementGroup*> (group->getElement (containerGroups.getUnchecked(i))); | |||
| if (group == 0) | |||
| return 0; | |||
| } | |||
| ElementType* const e = dynamic_cast <ElementType*> (group->getElement (elementIndex)); | |||
| jassert (e != 0); | |||
| return e; | |||
| } | |||
| else | |||
| { | |||
| ElementType* const e = dynamic_cast <ElementType*> (routine.getElement (elementIndex)); | |||
| jassert (e != 0); | |||
| return e; | |||
| } | |||
| } | |||
| int getSizeInUnits() { return 2; } | |||
| protected: | |||
| PaintRoutine& routine; | |||
| int elementIndex; | |||
| Array <int> containerGroups; | |||
| void changed() const | |||
| { | |||
| jassert (routine.getDocument() != 0); | |||
| routine.getDocument()->changed(); | |||
| } | |||
| void showCorrectTab() const | |||
| { | |||
| if (JucerDocumentEditor* const docHolder = JucerDocumentEditor::getActiveDocumentHolder()) | |||
| docHolder->showGraphics (&routine); | |||
| if (routine.getSelectedElements().getNumSelected() == 0) | |||
| if (ElementType* const e = dynamic_cast <ElementType*> (routine.getElement (elementIndex))) | |||
| routine.getSelectedElements().selectOnly (e); | |||
| } | |||
| private: | |||
| void findGroupIndices (PaintRoutine* const pr, PaintElement* const element) | |||
| { | |||
| for (int i = pr->getNumElements(); --i >= 0;) | |||
| { | |||
| PaintElementGroup* const pg = dynamic_cast <PaintElementGroup*> (pr->getElement (i)); | |||
| if (pg != 0 && pg->containsElement (element)) | |||
| { | |||
| containerGroups.add (i); | |||
| findGroupIndices (pg, element); | |||
| } | |||
| } | |||
| } | |||
| void findGroupIndices (PaintElementGroup* const group, PaintElement* const element) | |||
| { | |||
| elementIndex = group->indexOfElement (element); | |||
| if (elementIndex < 0) | |||
| { | |||
| for (int i = group->getNumElements(); --i >= 0;) | |||
| { | |||
| PaintElementGroup* pg = dynamic_cast <PaintElementGroup*> (group->getElement (i)); | |||
| if (pg != 0 && pg->containsElement (element)) | |||
| { | |||
| containerGroups.add (i); | |||
| findGroupIndices (pg, element); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| PaintElementUndoableAction (const PaintElementUndoableAction&); | |||
| PaintElementUndoableAction& operator= (const PaintElementUndoableAction&); | |||
| }; | |||
| #endif // __JUCER_PAINTELEMENTUNDOABLEACTION_JUCEHEADER__ | |||
| @@ -0,0 +1,112 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_POINTCOMPONENT_JUCEHEADER__ | |||
| #define __JUCER_POINTCOMPONENT_JUCEHEADER__ | |||
| #include "jucer_ElementSiblingComponent.h" | |||
| #include "../ui/jucer_PaintRoutineEditor.h" | |||
| //============================================================================== | |||
| class PointComponent : public ElementSiblingComponent | |||
| { | |||
| public: | |||
| PointComponent (PaintElement* const e) | |||
| : ElementSiblingComponent (e) | |||
| { | |||
| setSize (11, 11); | |||
| setMouseCursor (MouseCursor::UpDownLeftRightResizeCursor); | |||
| } | |||
| virtual RelativePositionedRectangle getPosition() = 0; | |||
| virtual void setPosition (const RelativePositionedRectangle& newPos) = 0; | |||
| virtual void updatePosition() | |||
| { | |||
| if (dynamic_cast <PaintRoutineEditor*> (getParentComponent()) != 0) | |||
| { | |||
| const Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| const Rectangle<int> r (getPosition().getRectangle (area, owner->getDocument()->getComponentLayout())); | |||
| setCentrePosition (r.getX(), r.getY()); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| void paint (Graphics& g) | |||
| { | |||
| g.setColour (Colours::white); | |||
| g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 2.0f); | |||
| g.setColour (Colours::black); | |||
| g.drawEllipse (1.0f, 1.0f, getWidth() - 2.0f, getHeight() - 2.0f, 2.0f); | |||
| } | |||
| //============================================================================== | |||
| void mouseDown (const MouseEvent&) | |||
| { | |||
| const Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| dragX = getX() + getWidth() / 2 - area.getX(); | |||
| dragY = getY() + getHeight() / 2 - area.getY(); | |||
| } | |||
| void mouseDrag (const MouseEvent& e) | |||
| { | |||
| const Rectangle<int> area (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); | |||
| int x = dragX + e.getDistanceFromDragStartX(); | |||
| int y = dragY + e.getDistanceFromDragStartY(); | |||
| if (JucerDocument* const document = owner->getDocument()) | |||
| { | |||
| x = document->snapPosition (x); | |||
| y = document->snapPosition (y); | |||
| const RelativePositionedRectangle original (getPosition()); | |||
| RelativePositionedRectangle pr (original); | |||
| Rectangle<int> r (pr.getRectangle (Rectangle<int> (0, 0, area.getWidth(), area.getHeight()), | |||
| document->getComponentLayout())); | |||
| r.setPosition (x, y); | |||
| pr.updateFrom (r.getX(), r.getY(), r.getWidth(), r.getHeight(), | |||
| Rectangle<int> (0, 0, area.getWidth(), area.getHeight()), | |||
| document->getComponentLayout()); | |||
| if (pr != original) | |||
| setPosition (pr); | |||
| } | |||
| } | |||
| void mouseUp (const MouseEvent&) | |||
| { | |||
| } | |||
| private: | |||
| int dragX, dragY; | |||
| }; | |||
| #endif // __JUCER_POINTCOMPONENT_JUCEHEADER__ | |||
| @@ -0,0 +1,162 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_STROKETYPE_JUCEHEADER__ | |||
| #define __JUCER_STROKETYPE_JUCEHEADER__ | |||
| #include "jucer_FillType.h" | |||
| //============================================================================== | |||
| class StrokeType | |||
| { | |||
| public: | |||
| StrokeType() : stroke (1.0f) | |||
| { | |||
| reset(); | |||
| } | |||
| String getPathStrokeCode() const | |||
| { | |||
| PathStrokeType defaultStroke (1.0f); | |||
| String s; | |||
| s << "PathStrokeType (" << CodeHelpers::floatLiteral (stroke.getStrokeThickness(), 3); | |||
| if (stroke.getJointStyle() != defaultStroke.getJointStyle() | |||
| || stroke.getEndStyle() != defaultStroke.getEndStyle()) | |||
| { | |||
| s << ", "; | |||
| switch (stroke.getJointStyle()) | |||
| { | |||
| case PathStrokeType::mitered: s << "PathStrokeType::mitered"; break; | |||
| case PathStrokeType::curved: s << "PathStrokeType::curved"; break; | |||
| case PathStrokeType::beveled: s << "PathStrokeType::beveled"; break; | |||
| default: jassertfalse; break; | |||
| } | |||
| if (stroke.getEndStyle() != defaultStroke.getEndStyle()) | |||
| { | |||
| s << ", "; | |||
| switch (stroke.getEndStyle()) | |||
| { | |||
| case PathStrokeType::butt: s << "PathStrokeType::butt"; break; | |||
| case PathStrokeType::square: s << "PathStrokeType::square"; break; | |||
| case PathStrokeType::rounded: s << "PathStrokeType::rounded"; break; | |||
| default: jassertfalse; break; | |||
| } | |||
| } | |||
| } | |||
| s << ")"; | |||
| return s; | |||
| } | |||
| String toString() const | |||
| { | |||
| String s; | |||
| s << stroke.getStrokeThickness(); | |||
| switch (stroke.getJointStyle()) | |||
| { | |||
| case PathStrokeType::mitered: s << ", mitered"; break; | |||
| case PathStrokeType::curved: s << ", curved"; break; | |||
| case PathStrokeType::beveled: s << ", beveled"; break; | |||
| default: jassertfalse; break; | |||
| } | |||
| switch (stroke.getEndStyle()) | |||
| { | |||
| case PathStrokeType::butt: s << ", butt"; break; | |||
| case PathStrokeType::square: s << ", square"; break; | |||
| case PathStrokeType::rounded: s << ", rounded"; break; | |||
| default: jassertfalse; break; | |||
| } | |||
| return s; | |||
| } | |||
| void restoreFromString (const String& s) | |||
| { | |||
| reset(); | |||
| if (s.isNotEmpty()) | |||
| { | |||
| const float thickness = (float) s.upToFirstOccurrenceOf (",", false, false).getDoubleValue(); | |||
| PathStrokeType::JointStyle joint = stroke.getJointStyle(); | |||
| if (s.containsIgnoreCase ("miter")) joint = PathStrokeType::mitered; | |||
| else if (s.containsIgnoreCase ("curve")) joint = PathStrokeType::curved; | |||
| else if (s.containsIgnoreCase ("bevel")) joint = PathStrokeType::beveled; | |||
| PathStrokeType::EndCapStyle end = stroke.getEndStyle(); | |||
| if (s.containsIgnoreCase ("butt")) end = PathStrokeType::butt; | |||
| else if (s.containsIgnoreCase ("square")) end = PathStrokeType::square; | |||
| else if (s.containsIgnoreCase ("round")) end = PathStrokeType::rounded; | |||
| stroke = PathStrokeType (thickness, joint, end); | |||
| } | |||
| } | |||
| bool isOpaque() const | |||
| { | |||
| return fill.isOpaque(); | |||
| } | |||
| bool isInvisible() const | |||
| { | |||
| return fill.isInvisible() || stroke.getStrokeThickness() <= 0.0f; | |||
| } | |||
| bool operator== (const StrokeType& other) const noexcept | |||
| { | |||
| return stroke == other.stroke && fill == other.fill; | |||
| } | |||
| bool operator!= (const StrokeType& other) const noexcept | |||
| { | |||
| return ! operator== (other); | |||
| } | |||
| //============================================================================== | |||
| PathStrokeType stroke; | |||
| JucerFillType fill; | |||
| private: | |||
| void reset() | |||
| { | |||
| stroke = PathStrokeType (5.0f); | |||
| fill = JucerFillType(); | |||
| fill.colour = Colours::black; | |||
| } | |||
| }; | |||
| #endif // __JUCER_STROKETYPE_JUCEHEADER__ | |||
| @@ -0,0 +1,217 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COLOURPROPERTYCOMPONENT_JUCEHEADER__ | |||
| #define __JUCER_COLOURPROPERTYCOMPONENT_JUCEHEADER__ | |||
| #include "../../Application/jucer_Application.h" | |||
| class JucerColourPropertyComponent : public PropertyComponent | |||
| { | |||
| public: | |||
| JucerColourPropertyComponent (const String& name, | |||
| const bool canReset) | |||
| : PropertyComponent (name) | |||
| { | |||
| colourPropEditor = new ColourPropEditorComponent (this, canReset); | |||
| addAndMakeVisible (colourPropEditor); | |||
| } | |||
| virtual void setColour (const Colour& newColour) = 0; | |||
| virtual Colour getColour() const = 0; | |||
| virtual void resetToDefault() = 0; | |||
| void refresh() | |||
| { | |||
| ((ColourPropEditorComponent*) getChildComponent (0))->refresh(); | |||
| } | |||
| private: | |||
| class ColourEditorComponent : public Component, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| ColourEditorComponent (const bool canReset) | |||
| : canResetToDefault (canReset) | |||
| { | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.fillAll (Colours::grey); | |||
| g.fillCheckerBoard (getLocalBounds().reduced (2, 2), | |||
| 10, 10, | |||
| Colour (0xffdddddd).overlaidWith (colour), | |||
| Colour (0xffffffff).overlaidWith (colour)); | |||
| g.setColour (Colours::white.overlaidWith (colour).contrasting()); | |||
| g.setFont (Font (getHeight() * 0.6f, Font::bold)); | |||
| g.drawFittedText (colour.toDisplayString (true), | |||
| 2, 1, getWidth() - 4, getHeight() - 1, | |||
| Justification::centred, 1); | |||
| } | |||
| virtual void setColour (const Colour& newColour) = 0; | |||
| virtual void resetToDefault() = 0; | |||
| virtual Colour getColour() const = 0; | |||
| void refresh() | |||
| { | |||
| const Colour col (getColour()); | |||
| if (col != colour) | |||
| { | |||
| colour = col; | |||
| repaint(); | |||
| } | |||
| } | |||
| void mouseDown (const MouseEvent&) | |||
| { | |||
| ColourSelectorComp colourSelector (this, canResetToDefault); | |||
| PopupMenu m; | |||
| m.addCustomItem (1234, &colourSelector, 300, 400, false); | |||
| m.showAt (this); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster* source) | |||
| { | |||
| const ColourSelector* const cs = (const ColourSelector*) source; | |||
| if (cs->getCurrentColour() != getColour()) | |||
| setColour (cs->getCurrentColour()); | |||
| } | |||
| private: | |||
| Colour colour; | |||
| bool canResetToDefault; | |||
| class ColourSelectorComp : public Component, | |||
| public ButtonListener | |||
| { | |||
| public: | |||
| ColourSelectorComp (ColourEditorComponent* owner_, | |||
| const bool canReset) | |||
| : owner (owner_), | |||
| defaultButton ("Reset to Default") | |||
| { | |||
| addAndMakeVisible (&selector); | |||
| selector.setName ("Colour"); | |||
| selector.setCurrentColour (owner->getColour()); | |||
| selector.addChangeListener (owner); | |||
| if (canReset) | |||
| { | |||
| addAndMakeVisible (&defaultButton); | |||
| defaultButton.addListener (this); | |||
| } | |||
| } | |||
| void resized() | |||
| { | |||
| if (defaultButton.isVisible()) | |||
| { | |||
| selector.setBounds (0, 0, getWidth(), getHeight() - 30); | |||
| defaultButton.changeWidthToFitText (22); | |||
| defaultButton.setTopLeftPosition (10, getHeight() - 26); | |||
| } | |||
| else | |||
| { | |||
| selector.setBounds (getLocalBounds()); | |||
| } | |||
| } | |||
| void buttonClicked (Button*) | |||
| { | |||
| owner->resetToDefault(); | |||
| owner->refresh(); | |||
| selector.setCurrentColour (owner->getColour()); | |||
| } | |||
| private: | |||
| class ColourSelectorWithSwatches : public ColourSelector | |||
| { | |||
| public: | |||
| ColourSelectorWithSwatches() | |||
| { | |||
| } | |||
| int getNumSwatches() const | |||
| { | |||
| return getAppSettings().swatchColours.size(); | |||
| } | |||
| Colour getSwatchColour (int index) const | |||
| { | |||
| return getAppSettings().swatchColours [index]; | |||
| } | |||
| void setSwatchColour (int index, const Colour& newColour) const | |||
| { | |||
| getAppSettings().swatchColours.set (index, newColour); | |||
| } | |||
| }; | |||
| ColourEditorComponent* owner; | |||
| ColourSelectorWithSwatches selector; | |||
| TextButton defaultButton; | |||
| }; | |||
| }; | |||
| class ColourPropEditorComponent : public ColourEditorComponent | |||
| { | |||
| JucerColourPropertyComponent* const owner; | |||
| public: | |||
| ColourPropEditorComponent (JucerColourPropertyComponent* const owner_, | |||
| const bool canReset) | |||
| : ColourEditorComponent (canReset), | |||
| owner (owner_) | |||
| {} | |||
| void setColour (const Colour& newColour) | |||
| { | |||
| owner->setColour (newColour); | |||
| } | |||
| Colour getColour() const | |||
| { | |||
| return owner->getColour(); | |||
| } | |||
| void resetToDefault() | |||
| { | |||
| owner->resetToDefault(); | |||
| } | |||
| }; | |||
| ScopedPointer<ColourPropEditorComponent> colourPropEditor; | |||
| }; | |||
| #endif // __JUCER_COLOURPROPERTYCOMPONENT_JUCEHEADER__ | |||
| @@ -0,0 +1,63 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTBOOLEANPROPERTY_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTBOOLEANPROPERTY_JUCEHEADER__ | |||
| template <class ComponentType> | |||
| class ComponentBooleanProperty : public BooleanPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ComponentBooleanProperty (const String& name, | |||
| const String& onText, | |||
| const String& offText, | |||
| ComponentType* comp, | |||
| JucerDocument& doc) | |||
| : BooleanPropertyComponent (name, onText, offText), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ComponentBooleanProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| protected: | |||
| ComponentType* component; | |||
| JucerDocument& document; | |||
| }; | |||
| #endif // __JUCER_COMPONENTBOOLEANPROPERTY_JUCEHEADER__ | |||
| @@ -0,0 +1,61 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTCHOICEPROPERTY_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTCHOICEPROPERTY_JUCEHEADER__ | |||
| template <class ComponentType> | |||
| class ComponentChoiceProperty : public ChoicePropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ComponentChoiceProperty (const String& name, | |||
| ComponentType* comp, | |||
| JucerDocument& doc) | |||
| : ChoicePropertyComponent (name), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ComponentChoiceProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| protected: | |||
| ComponentType* component; | |||
| JucerDocument& document; | |||
| }; | |||
| #endif // __JUCER_COMPONENTCHOICEPROPERTY_JUCEHEADER__ | |||
| @@ -0,0 +1,178 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTCOLOURPROPERTY_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTCOLOURPROPERTY_JUCEHEADER__ | |||
| #include "jucer_ColourPropertyComponent.h" | |||
| //============================================================================== | |||
| /** | |||
| */ | |||
| template <class ComponentType> | |||
| class ComponentColourProperty : public JucerColourPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ComponentColourProperty (const String& name, | |||
| ComponentType* comp, | |||
| JucerDocument& doc, | |||
| const bool canResetToDefault) | |||
| : JucerColourPropertyComponent (name, canResetToDefault), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ComponentColourProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| protected: | |||
| ComponentType* component; | |||
| JucerDocument& document; | |||
| }; | |||
| //============================================================================== | |||
| /** | |||
| */ | |||
| class ComponentColourIdProperty : public ComponentColourProperty <Component> | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentColourIdProperty (Component* const comp, | |||
| JucerDocument& doc, | |||
| const int colourId_, | |||
| const String& name, | |||
| const bool canResetToDefault) | |||
| : ComponentColourProperty <Component> (name, comp, doc, canResetToDefault), | |||
| colourId (colourId_) | |||
| { | |||
| } | |||
| ~ComponentColourIdProperty() | |||
| { | |||
| } | |||
| //============================================================================== | |||
| Colour getColour() const | |||
| { | |||
| return component->findColour (colourId); | |||
| } | |||
| void setColour (const Colour& newColour) | |||
| { | |||
| if (component->findColour (colourId) != newColour) | |||
| { | |||
| document.getUndoManager().undoCurrentTransactionOnly(); | |||
| document.perform (new ColourChangeAction (component, | |||
| *document.getComponentLayout(), | |||
| colourId, | |||
| newColour, | |||
| false), | |||
| "Change colour"); | |||
| } | |||
| } | |||
| void resetToDefault() | |||
| { | |||
| document.getUndoManager().undoCurrentTransactionOnly(); | |||
| document.perform (new ColourChangeAction (component, | |||
| *document.getComponentLayout(), | |||
| colourId, | |||
| Colours::black, | |||
| true), | |||
| "Reset colour"); | |||
| } | |||
| private: | |||
| const int colourId; | |||
| class ColourChangeAction : public ComponentUndoableAction <Component> | |||
| { | |||
| public: | |||
| ColourChangeAction (Component* const comp, | |||
| ComponentLayout& layout, | |||
| const int colourId_, | |||
| const Colour& newColour_, | |||
| const bool newColourIsDefault) | |||
| : ComponentUndoableAction <Component> (comp, layout), | |||
| colourId (colourId_), | |||
| newColour (newColour_), | |||
| isDefault (newColourIsDefault) | |||
| { | |||
| } | |||
| bool perform() | |||
| { | |||
| showCorrectTab(); | |||
| wasSpecified = getComponent()->isColourSpecified (colourId); | |||
| oldColour = getComponent()->findColour (colourId); | |||
| if (isDefault) | |||
| getComponent()->removeColour (colourId); | |||
| else | |||
| getComponent()->setColour (colourId, newColour); | |||
| changed(); | |||
| return true; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| if (wasSpecified) | |||
| getComponent()->setColour (colourId, oldColour); | |||
| else | |||
| getComponent()->removeColour (colourId); | |||
| if (TextEditor* const te = dynamic_cast <TextEditor*> (getComponent())) | |||
| te->applyFontToAllText (te->getFont()); | |||
| changed(); | |||
| return true; | |||
| } | |||
| int colourId; | |||
| Colour newColour, oldColour; | |||
| bool isDefault, wasSpecified; | |||
| }; | |||
| }; | |||
| #endif // __JUCER_COMPONENTCOLOURPROPERTY_JUCEHEADER__ | |||
| @@ -0,0 +1,63 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTTEXTPROPERTY_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTTEXTPROPERTY_JUCEHEADER__ | |||
| template <class ComponentType> | |||
| class ComponentTextProperty : public TextPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ComponentTextProperty (const String& name, | |||
| const int maxNumChars_, | |||
| const bool isMultiLine_, | |||
| ComponentType* const comp, | |||
| JucerDocument& doc) | |||
| : TextPropertyComponent (name, maxNumChars_, isMultiLine_), | |||
| component (comp), | |||
| document (doc) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ComponentTextProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| protected: | |||
| ComponentType* component; | |||
| JucerDocument& document; | |||
| }; | |||
| #endif // __JUCER_COMPONENTTEXTPROPERTY_JUCEHEADER__ | |||
| @@ -0,0 +1,66 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_FILEPROPERTYCOMPONENT_JUCEHEADER__ | |||
| #define __JUCER_FILEPROPERTYCOMPONENT_JUCEHEADER__ | |||
| class FilePropertyComponent : public PropertyComponent, | |||
| public FilenameComponentListener | |||
| { | |||
| public: | |||
| FilePropertyComponent (const String& name, | |||
| const bool isDirectory, | |||
| const bool allowEditingOfFilename, | |||
| const String& fileBrowserWildcard = "*") | |||
| : PropertyComponent (name), | |||
| filenameComp (name, File::nonexistent, allowEditingOfFilename, | |||
| isDirectory, false, fileBrowserWildcard, | |||
| String::empty, String::empty) | |||
| { | |||
| addAndMakeVisible (&filenameComp); | |||
| filenameComp.addListener (this); | |||
| } | |||
| virtual void setFile (const File& newFile) = 0; | |||
| virtual File getFile() const = 0; | |||
| void refresh() | |||
| { | |||
| filenameComp.setCurrentFile (getFile(), false); | |||
| } | |||
| void filenameComponentChanged (FilenameComponent*) | |||
| { | |||
| if (getFile() != filenameComp.getCurrentFile()) | |||
| setFile (filenameComp.getCurrentFile()); | |||
| } | |||
| private: | |||
| FilenameComponent filenameComp; | |||
| }; | |||
| #endif // __JUCER_FILEPROPERTYCOMPONENT_JUCEHEADER__ | |||
| @@ -0,0 +1,123 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_FONTPROPERTYCOMPONENT_JUCEHEADER__ | |||
| #define __JUCER_FONTPROPERTYCOMPONENT_JUCEHEADER__ | |||
| class FontPropertyComponent : public ChoicePropertyComponent | |||
| { | |||
| public: | |||
| FontPropertyComponent (const String& name) | |||
| : ChoicePropertyComponent (name) | |||
| { | |||
| choices.add (getDefaultFont()); | |||
| choices.add (getDefaultSans()); | |||
| choices.add (getDefaultSans()); | |||
| choices.add (getDefaultMono()); | |||
| choices.add (String::empty); | |||
| static StringArray fontNames; | |||
| if (fontNames.size() == 0) | |||
| { | |||
| Array<Font> fonts; | |||
| Font::findFonts (fonts); | |||
| for (int i = 0; i < fonts.size(); ++i) | |||
| fontNames.add (fonts[i].getTypefaceName()); | |||
| } | |||
| choices.addArray (fontNames); | |||
| } | |||
| static String getDefaultFont() { return "Default font"; } | |||
| static String getDefaultSans() { return "Default sans-serif font"; } | |||
| static String getDefaultSerif() { return "Default serif font"; } | |||
| static String getDefaultMono() { return "Default monospaced font"; } | |||
| //============================================================================== | |||
| virtual void setTypefaceName (const String& newFontName) = 0; | |||
| virtual String getTypefaceName() const = 0; | |||
| //============================================================================== | |||
| void setIndex (int newIndex) | |||
| { | |||
| String type (choices [newIndex]); | |||
| if (type.isEmpty()) | |||
| type = getDefaultFont(); | |||
| if (getTypefaceName() != type) | |||
| setTypefaceName (type); | |||
| } | |||
| int getIndex() const | |||
| { | |||
| return choices.indexOf (getTypefaceName()); | |||
| } | |||
| static Font applyNameToFont (const String& typefaceName, const Font& font) | |||
| { | |||
| if (typefaceName == getDefaultFont()) return Font (font.getHeight(), font.getStyleFlags()); | |||
| if (typefaceName == getDefaultSans()) return Font (Font::getDefaultSansSerifFontName(), font.getHeight(), font.getStyleFlags()); | |||
| if (typefaceName == getDefaultSans()) return Font (Font::getDefaultSerifFontName(), font.getHeight(), font.getStyleFlags()); | |||
| if (typefaceName == getDefaultMono()) return Font (Font::getDefaultMonospacedFontName(), font.getHeight(), font.getStyleFlags()); | |||
| return Font (typefaceName, font.getHeight(), font.getStyleFlags()); | |||
| } | |||
| static String getTypefaceNameCode (const String& typefaceName) | |||
| { | |||
| if (typefaceName == getDefaultFont()) return String::empty; | |||
| if (typefaceName == getDefaultSans()) return "Font::getDefaultSansSerifFontName(), "; | |||
| if (typefaceName == getDefaultSans()) return "Font::getDefaultSerifFontName(), "; | |||
| if (typefaceName == getDefaultMono()) return "Font::getDefaultMonospacedFontName(), "; | |||
| return "\"" + typefaceName + "\", "; | |||
| } | |||
| static String getFontStyleCode (const Font& font) | |||
| { | |||
| if (font.isBold() && font.isItalic()) return "Font::bold | Font::italic"; | |||
| if (font.isBold()) return "Font::bold"; | |||
| if (font.isItalic()) return "Font::italic"; | |||
| return "Font::plain"; | |||
| } | |||
| static String getCompleteFontCode (const Font& font, const String& typefaceName) | |||
| { | |||
| return "Font (" | |||
| + getTypefaceNameCode (typefaceName) | |||
| + CodeHelpers::floatLiteral (font.getHeight(), 2) | |||
| + ", " | |||
| + getFontStyleCode (font) | |||
| + ")"; | |||
| } | |||
| }; | |||
| #endif // __JUCER_FONTPROPERTYCOMPONENT_JUCEHEADER__ | |||
| @@ -0,0 +1,104 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_JUSTIFICATIONPROPERTY_JUCEHEADER__ | |||
| #define __JUCER_JUSTIFICATIONPROPERTY_JUCEHEADER__ | |||
| class JustificationProperty : public ChoicePropertyComponent | |||
| { | |||
| public: | |||
| JustificationProperty (const String& name, const bool onlyHorizontalOptions) | |||
| : ChoicePropertyComponent (name) | |||
| { | |||
| if (onlyHorizontalOptions) | |||
| { | |||
| choices.add ("centre"); | |||
| choices.add ("left"); | |||
| choices.add ("right"); | |||
| } | |||
| else | |||
| { | |||
| choices.add ("centred"); | |||
| choices.add ("centred left"); | |||
| choices.add ("centred right"); | |||
| choices.add ("centred top"); | |||
| choices.add ("centred bottom"); | |||
| choices.add ("top left"); | |||
| choices.add ("top right"); | |||
| choices.add ("bottom left"); | |||
| choices.add ("bottom right"); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| virtual void setJustification (const Justification& newJustification) = 0; | |||
| virtual const Justification getJustification() const = 0; | |||
| //============================================================================== | |||
| void setIndex (int newIndex) | |||
| { | |||
| const int types[] = { Justification::centred, | |||
| Justification::centredLeft, | |||
| Justification::centredRight, | |||
| Justification::centredTop, | |||
| Justification::centredBottom, | |||
| Justification::topLeft, | |||
| Justification::topRight, | |||
| Justification::bottomLeft, | |||
| Justification::bottomRight }; | |||
| if (((unsigned int) newIndex) < (unsigned int) numElementsInArray (types) | |||
| && types [newIndex] != getJustification().getFlags()) | |||
| { | |||
| setJustification (Justification (types [newIndex])); | |||
| } | |||
| } | |||
| int getIndex() const | |||
| { | |||
| const int types[] = { Justification::centred, | |||
| Justification::centredLeft, | |||
| Justification::centredRight, | |||
| Justification::centredTop, | |||
| Justification::centredBottom, | |||
| Justification::topLeft, | |||
| Justification::topRight, | |||
| Justification::bottomLeft, | |||
| Justification::bottomRight }; | |||
| const int flags = getJustification().getFlags(); | |||
| for (int i = numElementsInArray (types); --i >= 0;) | |||
| if (types[i] == flags) | |||
| return i; | |||
| return -1; | |||
| } | |||
| }; | |||
| #endif // __JUCER_JUSTIFICATIONPROPERTY_JUCEHEADER__ | |||
| @@ -0,0 +1,456 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_POSITIONPROPERTYBASE_JUCEHEADER__ | |||
| #define __JUCER_POSITIONPROPERTYBASE_JUCEHEADER__ | |||
| #include "../ui/jucer_PaintRoutineEditor.h" | |||
| #include "../ui/jucer_ComponentLayoutEditor.h" | |||
| //============================================================================== | |||
| /** | |||
| Base class for a property that edits the x, y, w, or h of a PositionedRectangle. | |||
| */ | |||
| class PositionPropertyBase : public PropertyComponent, | |||
| protected ChangeListener, | |||
| private ButtonListener | |||
| { | |||
| public: | |||
| enum ComponentPositionDimension | |||
| { | |||
| componentX = 0, | |||
| componentY = 1, | |||
| componentWidth = 2, | |||
| componentHeight = 3 | |||
| }; | |||
| PositionPropertyBase (Component* comp, | |||
| const String& name, | |||
| ComponentPositionDimension dimension_, | |||
| const bool includeAnchorOptions_, | |||
| const bool allowRelativeOptions_, | |||
| ComponentLayout* layout_) | |||
| : PropertyComponent (name), | |||
| layout (layout_), | |||
| button ("mode"), | |||
| component (comp), | |||
| dimension (dimension_), | |||
| includeAnchorOptions (includeAnchorOptions_), | |||
| allowRelativeOptions (allowRelativeOptions_) | |||
| { | |||
| addAndMakeVisible (&button); | |||
| button.addListener (this); | |||
| button.setTriggeredOnMouseDown (true); | |||
| button.setConnectedEdges (TextButton::ConnectedOnLeft | TextButton::ConnectedOnRight); | |||
| addAndMakeVisible (textEditor = new PositionPropLabel (*this)); | |||
| } | |||
| String getText() const | |||
| { | |||
| RelativePositionedRectangle rpr (getPosition()); | |||
| PositionedRectangle& p = rpr.rect; | |||
| String s; | |||
| switch (dimension) | |||
| { | |||
| case componentX: | |||
| if (p.getPositionModeX() == PositionedRectangle::proportionOfParentSize) | |||
| s << valueToString (p.getX() * 100.0) << '%'; | |||
| else | |||
| s << valueToString (p.getX()); | |||
| break; | |||
| case componentY: | |||
| if (p.getPositionModeY() == PositionedRectangle::proportionOfParentSize) | |||
| s << valueToString (p.getY() * 100.0) << '%'; | |||
| else | |||
| s << valueToString (p.getY()); | |||
| break; | |||
| case componentWidth: | |||
| if (p.getWidthMode() == PositionedRectangle::proportionalSize) | |||
| s << valueToString (p.getWidth() * 100.0) << '%'; | |||
| else | |||
| s << valueToString (p.getWidth()); | |||
| break; | |||
| case componentHeight: | |||
| if (p.getHeightMode() == PositionedRectangle::proportionalSize) | |||
| s << valueToString (p.getHeight() * 100.0) << '%'; | |||
| else | |||
| s << valueToString (p.getHeight()); | |||
| break; | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| }; | |||
| return s; | |||
| } | |||
| static String valueToString (const double n) | |||
| { | |||
| return String (roundToInt (n * 1000.0) / 1000.0); | |||
| } | |||
| void setText (const String& newText) | |||
| { | |||
| RelativePositionedRectangle rpr (getPosition()); | |||
| PositionedRectangle p (rpr.rect); | |||
| const double value = newText.getDoubleValue(); | |||
| switch (dimension) | |||
| { | |||
| case componentX: | |||
| if (p.getPositionModeX() == PositionedRectangle::proportionOfParentSize) | |||
| p.setX (value / 100.0); | |||
| else | |||
| p.setX (value); | |||
| break; | |||
| case componentY: | |||
| if (p.getPositionModeY() == PositionedRectangle::proportionOfParentSize) | |||
| p.setY (value / 100.0); | |||
| else | |||
| p.setY (value); | |||
| break; | |||
| case componentWidth: | |||
| if (p.getWidthMode() == PositionedRectangle::proportionalSize) | |||
| p.setWidth (value / 100.0); | |||
| else | |||
| p.setWidth (value); | |||
| break; | |||
| case componentHeight: | |||
| if (p.getHeightMode() == PositionedRectangle::proportionalSize) | |||
| p.setHeight (value / 100.0); | |||
| else | |||
| p.setHeight (value); | |||
| break; | |||
| default: | |||
| jassertfalse; | |||
| break; | |||
| }; | |||
| if (p != rpr.rect) | |||
| { | |||
| rpr.rect = p; | |||
| setPosition (rpr); | |||
| } | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| bool showMenu (ComponentLayout* compLayout) | |||
| { | |||
| RelativePositionedRectangle rpr (getPosition()); | |||
| PositionedRectangle p (rpr.rect); | |||
| PositionedRectangle::AnchorPoint xAnchor = p.getAnchorPointX(); | |||
| PositionedRectangle::AnchorPoint yAnchor = p.getAnchorPointY(); | |||
| PositionedRectangle::PositionMode xMode = p.getPositionModeX(); | |||
| PositionedRectangle::PositionMode yMode = p.getPositionModeY(); | |||
| PositionedRectangle::SizeMode sizeW = p.getWidthMode(); | |||
| PositionedRectangle::SizeMode sizeH = p.getHeightMode(); | |||
| String relCompName ("parent"); | |||
| if (Component* const relComp = compLayout != nullptr ? compLayout->getComponentRelativePosTarget (component, (int) dimension) | |||
| : nullptr) | |||
| relCompName = compLayout->getComponentMemberVariableName (relComp); | |||
| jassert (relCompName.isNotEmpty()); | |||
| PopupMenu m; | |||
| if (dimension == componentX || dimension == componentY) | |||
| { | |||
| const PositionedRectangle::PositionMode posMode = (dimension == componentX) ? xMode : yMode; | |||
| m.addItem (10, ((dimension == componentX) ? "Absolute distance from left of " | |||
| : "Absolute distance from top of ") + relCompName, | |||
| true, posMode == PositionedRectangle::absoluteFromParentTopLeft); | |||
| m.addItem (11, ((dimension == componentX) ? "Absolute distance from right of " | |||
| : "Absolute distance from bottom of ") + relCompName, | |||
| true, posMode == PositionedRectangle::absoluteFromParentBottomRight); | |||
| m.addItem (12, "Absolute distance from centre of " + relCompName, | |||
| true, posMode == PositionedRectangle::absoluteFromParentCentre); | |||
| m.addItem (13, ((dimension == componentX) ? "Percentage of width of " | |||
| : "Percentage of height of ") + relCompName, | |||
| true, posMode == PositionedRectangle::proportionOfParentSize); | |||
| m.addSeparator(); | |||
| if (includeAnchorOptions) | |||
| { | |||
| const PositionedRectangle::AnchorPoint anchor = (dimension == componentX) ? xAnchor : yAnchor; | |||
| m.addItem (14, (dimension == componentX) ? "Anchored at left of component" | |||
| : "Anchored at top of component", | |||
| true, anchor == PositionedRectangle::anchorAtLeftOrTop); | |||
| m.addItem (15, "Anchored at centre of component", true, anchor == PositionedRectangle::anchorAtCentre); | |||
| m.addItem (16, (dimension == componentX) ? "Anchored at right of component" | |||
| : "Anchored at bottom of component", | |||
| true, anchor == PositionedRectangle::anchorAtRightOrBottom); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| const PositionedRectangle::SizeMode sizeMode = (dimension == componentWidth) ? sizeW : sizeH; | |||
| m.addItem (20, (dimension == componentWidth) ? "Absolute width" | |||
| : "Absolute height", | |||
| true, sizeMode == PositionedRectangle::absoluteSize); | |||
| m.addItem (21, ((dimension == componentWidth) ? "Percentage of width of " | |||
| : "Percentage of height of ") + relCompName, | |||
| true, sizeMode == PositionedRectangle::proportionalSize); | |||
| m.addItem (22, ((dimension == componentWidth) ? "Subtracted from width of " | |||
| : "Subtracted from height of ") + relCompName, | |||
| true, sizeMode == PositionedRectangle::parentSizeMinusAbsolute); | |||
| } | |||
| if (allowRelativeOptions && compLayout != nullptr) | |||
| { | |||
| m.addSeparator(); | |||
| m.addSubMenu ("Relative to", compLayout->getRelativeTargetMenu (component, (int) dimension)); | |||
| } | |||
| WeakReference<Component> ref (this); | |||
| const int menuResult = m.showAt (&button); | |||
| if (menuResult == 0 || ref == nullptr) | |||
| return false; | |||
| switch (menuResult) | |||
| { | |||
| case 10: | |||
| if (dimension == componentX) | |||
| xMode = PositionedRectangle::absoluteFromParentTopLeft; | |||
| else | |||
| yMode = PositionedRectangle::absoluteFromParentTopLeft; | |||
| break; | |||
| case 11: | |||
| if (dimension == componentX) | |||
| xMode = PositionedRectangle::absoluteFromParentBottomRight; | |||
| else | |||
| yMode = PositionedRectangle::absoluteFromParentBottomRight; | |||
| break; | |||
| case 12: | |||
| if (dimension == componentX) | |||
| xMode = PositionedRectangle::absoluteFromParentCentre; | |||
| else | |||
| yMode = PositionedRectangle::absoluteFromParentCentre; | |||
| break; | |||
| case 13: | |||
| if (dimension == componentX) | |||
| xMode = PositionedRectangle::proportionOfParentSize; | |||
| else | |||
| yMode = PositionedRectangle::proportionOfParentSize; | |||
| break; | |||
| case 14: | |||
| if (dimension == componentX) | |||
| xAnchor = PositionedRectangle::anchorAtLeftOrTop; | |||
| else | |||
| yAnchor = PositionedRectangle::anchorAtLeftOrTop; | |||
| break; | |||
| case 15: | |||
| if (dimension == componentX) | |||
| xAnchor = PositionedRectangle::anchorAtCentre; | |||
| else | |||
| yAnchor = PositionedRectangle::anchorAtCentre; | |||
| break; | |||
| case 16: | |||
| if (dimension == componentX) | |||
| xAnchor = PositionedRectangle::anchorAtRightOrBottom; | |||
| else | |||
| yAnchor = PositionedRectangle::anchorAtRightOrBottom; | |||
| break; | |||
| case 20: | |||
| if (dimension == componentWidth) | |||
| sizeW = PositionedRectangle::absoluteSize; | |||
| else | |||
| sizeH = PositionedRectangle::absoluteSize; | |||
| break; | |||
| case 21: | |||
| if (dimension == componentWidth) | |||
| sizeW = PositionedRectangle::proportionalSize; | |||
| else | |||
| sizeH = PositionedRectangle::proportionalSize; | |||
| break; | |||
| case 22: | |||
| if (dimension == componentWidth) | |||
| sizeW = PositionedRectangle::parentSizeMinusAbsolute; | |||
| else | |||
| sizeH = PositionedRectangle::parentSizeMinusAbsolute; | |||
| break; | |||
| default: | |||
| if (allowRelativeOptions && compLayout != nullptr) | |||
| compLayout->processRelativeTargetMenuResult (component, (int) dimension, menuResult); | |||
| break; | |||
| } | |||
| Rectangle<int> parentArea; | |||
| if (component->findParentComponentOfClass<ComponentLayoutEditor>() != 0) | |||
| parentArea.setSize (component->getParentWidth(), component->getParentHeight()); | |||
| else if (dynamic_cast <PaintRoutineEditor*> (component->getParentComponent()) != 0) | |||
| parentArea = dynamic_cast <PaintRoutineEditor*> (component->getParentComponent())->getComponentArea(); | |||
| else | |||
| jassertfalse; | |||
| int x, xw, y, yh, w, h; | |||
| rpr.getRelativeTargetBounds (parentArea, compLayout, x, xw, y, yh, w, h); | |||
| PositionedRectangle xyRect (p); | |||
| PositionedRectangle whRect (p); | |||
| xyRect.setModes (xAnchor, xMode, yAnchor, yMode, sizeW, sizeH, | |||
| Rectangle<int> (x, y, xw, yh)); | |||
| whRect.setModes (xAnchor, xMode, yAnchor, yMode, sizeW, sizeH, | |||
| Rectangle<int> (x, y, w, h)); | |||
| p.setModes (xAnchor, xMode, yAnchor, yMode, sizeW, sizeH, | |||
| Rectangle<int> (x, y, xw, yh)); | |||
| p.setX (xyRect.getX()); | |||
| p.setY (xyRect.getY()); | |||
| p.setWidth (whRect.getWidth()); | |||
| p.setHeight (whRect.getHeight()); | |||
| if (p != rpr.rect) | |||
| { | |||
| rpr.rect = p; | |||
| setPosition (rpr); | |||
| } | |||
| return true; | |||
| } | |||
| void resized() | |||
| { | |||
| const Rectangle<int> r (getLookAndFeel().getPropertyComponentContentPosition (*this)); | |||
| button.changeWidthToFitText (r.getHeight()); | |||
| button.setTopRightPosition (r.getRight(), r.getY()); | |||
| textEditor->setBounds (r.getX(), r.getY(), button.getX() - r.getX(), r.getHeight()); | |||
| } | |||
| void refresh() | |||
| { | |||
| textEditor->setText (getText(), false); | |||
| } | |||
| void buttonClicked (Button*) | |||
| { | |||
| if (showMenu (layout)) | |||
| refresh(); // (to clear the text editor if it's got focus) | |||
| } | |||
| void textWasEdited() | |||
| { | |||
| const String newText (textEditor->getText()); | |||
| if (getText() != newText) | |||
| setText (newText); | |||
| } | |||
| //============================================================================== | |||
| virtual void setPosition (const RelativePositionedRectangle& newPos) = 0; | |||
| virtual RelativePositionedRectangle getPosition() const = 0; | |||
| protected: | |||
| class PositionPropLabel : public Label | |||
| { | |||
| PositionPropertyBase& owner; | |||
| public: | |||
| PositionPropLabel (PositionPropertyBase& owner_) | |||
| : Label (String::empty, String::empty), | |||
| owner (owner_) | |||
| { | |||
| setEditable (true, true, false); | |||
| setColour (backgroundColourId, Colours::white); | |||
| setColour (textColourId, Colours::black); | |||
| setColour (outlineColourId, findColour (ComboBox::outlineColourId)); | |||
| setColour (TextEditor::textColourId, Colours::black); | |||
| setColour (TextEditor::backgroundColourId, Colours::white); | |||
| setColour (TextEditor::outlineColourId, findColour (ComboBox::outlineColourId)); | |||
| } | |||
| TextEditor* createEditorComponent() | |||
| { | |||
| TextEditor* ed = Label::createEditorComponent(); | |||
| ed->setInputRestrictions (14, "0123456789.-%"); | |||
| return ed; | |||
| } | |||
| void textWasEdited() | |||
| { | |||
| owner.textWasEdited(); | |||
| } | |||
| }; | |||
| ComponentLayout* layout; | |||
| ScopedPointer<PositionPropLabel> textEditor; | |||
| TextButton button; | |||
| Component* component; | |||
| ComponentPositionDimension dimension; | |||
| const bool includeAnchorOptions, allowRelativeOptions; | |||
| }; | |||
| #endif // __JUCER_POSITIONPROPERTYBASE_JUCEHEADER__ | |||
| @@ -0,0 +1,397 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_ComponentLayoutEditor.h" | |||
| #include "../ui/jucer_JucerCommandIDs.h" | |||
| #include "../jucer_ObjectTypes.h" | |||
| #include "../components/jucer_JucerComponentHandler.h" | |||
| //============================================================================== | |||
| class SubComponentHolderComp : public Component | |||
| { | |||
| public: | |||
| SubComponentHolderComp (JucerDocument& doc, | |||
| SnapGridPainter& g) | |||
| : document (doc), grid (g), | |||
| dontFillBackground (false) | |||
| { | |||
| setInterceptsMouseClicks (false, false); | |||
| setWantsKeyboardFocus (false); | |||
| setFocusContainer (true); | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| if (! dontFillBackground) | |||
| { | |||
| if (PaintRoutine* const background = document.getPaintRoutine (0)) | |||
| { | |||
| background->fillWithBackground (g, false); | |||
| background->drawElements (g, getLocalBounds()); | |||
| grid.draw (g, background); | |||
| } | |||
| else | |||
| grid.draw (g, nullptr); | |||
| } | |||
| } | |||
| void resized() | |||
| { | |||
| if (! getBounds().isEmpty()) | |||
| { | |||
| int numTimesToTry = 10; | |||
| while (--numTimesToTry >= 0) | |||
| { | |||
| bool anyCompsMoved = false; | |||
| for (int i = 0; i < getNumChildComponents(); ++i) | |||
| { | |||
| Component* comp = getChildComponent (i); | |||
| if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp)) | |||
| { | |||
| const Rectangle<int> newBounds (type->getComponentPosition (comp) | |||
| .getRectangle (getLocalBounds(), | |||
| document.getComponentLayout())); | |||
| anyCompsMoved = anyCompsMoved || (comp->getBounds() != newBounds); | |||
| comp->setBounds (newBounds); | |||
| } | |||
| } | |||
| // repeat this loop until they've all stopped shuffling (might require a few | |||
| // loops for all the relative positioned comps to settle down) | |||
| if (! anyCompsMoved) | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| void moved() | |||
| { | |||
| ((ComponentLayoutEditor*) getParentComponent())->updateOverlayPositions(); | |||
| } | |||
| JucerDocument& document; | |||
| SnapGridPainter& grid; | |||
| bool dontFillBackground; | |||
| }; | |||
| //============================================================================== | |||
| ComponentLayoutEditor::ComponentLayoutEditor (JucerDocument& doc, ComponentLayout& cl) | |||
| : document (doc), layout (cl), firstResize (true) | |||
| { | |||
| setWantsKeyboardFocus (true); | |||
| addAndMakeVisible (subCompHolder = new SubComponentHolderComp (document, grid)); | |||
| refreshAllComponents(); | |||
| setSize (document.getInitialWidth(), | |||
| document.getInitialHeight()); | |||
| } | |||
| ComponentLayoutEditor::~ComponentLayoutEditor() | |||
| { | |||
| document.removeChangeListener (this); | |||
| removeChildComponent (&lassoComp); | |||
| deleteAllChildren(); | |||
| } | |||
| //============================================================================== | |||
| void ComponentLayoutEditor::visibilityChanged() | |||
| { | |||
| document.beginTransaction(); | |||
| if (isVisible()) | |||
| { | |||
| refreshAllComponents(); | |||
| document.addChangeListener (this); | |||
| } | |||
| else | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| } | |||
| void ComponentLayoutEditor::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refreshAllComponents(); | |||
| } | |||
| void ComponentLayoutEditor::paint (Graphics&) | |||
| { | |||
| } | |||
| void ComponentLayoutEditor::resized() | |||
| { | |||
| if (firstResize && getWidth() > 0 && getHeight() > 0) | |||
| { | |||
| firstResize = false; | |||
| refreshAllComponents(); | |||
| } | |||
| subCompHolder->setBounds (getComponentArea()); | |||
| updateOverlayPositions(); | |||
| } | |||
| Rectangle<int> ComponentLayoutEditor::getComponentArea() const | |||
| { | |||
| const int editorEdgeGap = 4; | |||
| if (document.isFixedSize()) | |||
| return Rectangle<int> ((getWidth() - document.getInitialWidth()) / 2, | |||
| (getHeight() - document.getInitialHeight()) / 2, | |||
| document.getInitialWidth(), | |||
| document.getInitialHeight()); | |||
| return Rectangle<int> (editorEdgeGap, editorEdgeGap, | |||
| getWidth() - editorEdgeGap * 2, | |||
| getHeight() - editorEdgeGap * 2); | |||
| } | |||
| Image ComponentLayoutEditor::createComponentLayerSnapshot() const | |||
| { | |||
| ((SubComponentHolderComp*) subCompHolder)->dontFillBackground = true; | |||
| Image im = subCompHolder->createComponentSnapshot (Rectangle<int> (0, 0, subCompHolder->getWidth(), subCompHolder->getHeight())); | |||
| ((SubComponentHolderComp*) subCompHolder)->dontFillBackground = false; | |||
| return im; | |||
| } | |||
| void ComponentLayoutEditor::updateOverlayPositions() | |||
| { | |||
| for (int i = getNumChildComponents(); --i >= 0;) | |||
| if (ComponentOverlayComponent* const overlay = dynamic_cast <ComponentOverlayComponent*> (getChildComponent (i))) | |||
| overlay->updateBoundsToMatchTarget(); | |||
| } | |||
| void ComponentLayoutEditor::refreshAllComponents() | |||
| { | |||
| for (int i = getNumChildComponents(); --i >= 0;) | |||
| { | |||
| ScopedPointer<ComponentOverlayComponent> overlay (dynamic_cast <ComponentOverlayComponent*> (getChildComponent (i))); | |||
| if (overlay != nullptr && layout.containsComponent (overlay->target)) | |||
| overlay.release(); | |||
| } | |||
| for (int i = subCompHolder->getNumChildComponents(); --i >= 0;) | |||
| { | |||
| Component* const comp = subCompHolder->getChildComponent (i); | |||
| if (! layout.containsComponent (comp)) | |||
| subCompHolder->removeChildComponent (comp); | |||
| } | |||
| Component* lastComp = nullptr; | |||
| Component* lastOverlay = nullptr; | |||
| for (int i = layout.getNumComponents(); --i >= 0;) | |||
| { | |||
| Component* const c = layout.getComponent (i); | |||
| ComponentOverlayComponent* overlay = getOverlayCompFor (c); | |||
| bool isNewOverlay = false; | |||
| if (overlay == 0) | |||
| { | |||
| ComponentTypeHandler* const handler = ComponentTypeHandler::getHandlerFor (*c); | |||
| jassert (handler != nullptr); | |||
| overlay = handler->createOverlayComponent (c, layout); | |||
| addAndMakeVisible (overlay); | |||
| isNewOverlay = true; | |||
| } | |||
| if (lastOverlay != nullptr) | |||
| overlay->toBehind (lastOverlay); | |||
| else | |||
| overlay->toFront (false); | |||
| lastOverlay = overlay; | |||
| subCompHolder->addAndMakeVisible (c); | |||
| if (lastComp != nullptr) | |||
| c->toBehind (lastComp); | |||
| else | |||
| c->toFront (false); | |||
| lastComp = c; | |||
| c->setWantsKeyboardFocus (false); | |||
| c->setFocusContainer (true); | |||
| if (isNewOverlay) | |||
| overlay->updateBoundsToMatchTarget(); | |||
| } | |||
| if (grid.updateFromDesign (document)) | |||
| subCompHolder->repaint(); | |||
| subCompHolder->setBounds (getComponentArea()); | |||
| subCompHolder->resized(); | |||
| } | |||
| void ComponentLayoutEditor::mouseDown (const MouseEvent& e) | |||
| { | |||
| if (e.mods.isPopupMenu()) | |||
| { | |||
| PopupMenu m; | |||
| m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout); | |||
| m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics); | |||
| m.addSeparator(); | |||
| for (int i = 0; i < ObjectTypes::numComponentTypes; ++i) | |||
| m.addCommandItem (commandManager, JucerCommandIDs::newComponentBase + i); | |||
| m.show(); | |||
| } | |||
| else | |||
| { | |||
| addChildComponent (&lassoComp); | |||
| lassoComp.beginLasso (e, this); | |||
| } | |||
| } | |||
| void ComponentLayoutEditor::mouseDrag (const MouseEvent& e) | |||
| { | |||
| lassoComp.toFront (false); | |||
| lassoComp.dragLasso (e); | |||
| } | |||
| void ComponentLayoutEditor::mouseUp (const MouseEvent& e) | |||
| { | |||
| lassoComp.endLasso(); | |||
| removeChildComponent (&lassoComp); | |||
| if (e.mouseWasClicked() && ! e.mods.isAnyModifierKeyDown()) | |||
| layout.getSelectedSet().deselectAll(); | |||
| } | |||
| static void moveOrStretch (ComponentLayout& layout, int x, int y, bool snap, bool stretch) | |||
| { | |||
| if (stretch) | |||
| layout.stretchSelectedComps (x, y, snap); | |||
| else | |||
| layout.moveSelectedComps (x, y, snap); | |||
| } | |||
| bool ComponentLayoutEditor::keyPressed (const KeyPress& key) | |||
| { | |||
| const bool snap = key.getModifiers().isAltDown(); | |||
| const bool stretch = key.getModifiers().isShiftDown(); | |||
| const int amount = snap ? document.getSnappingGridSize() + 1 | |||
| : 1; | |||
| if (key.isKeyCode (KeyPress::rightKey)) | |||
| { | |||
| moveOrStretch (layout, amount, 0, snap, stretch); | |||
| } | |||
| else if (key.isKeyCode (KeyPress::downKey)) | |||
| { | |||
| moveOrStretch (layout, 0,amount, snap, stretch); | |||
| } | |||
| else if (key.isKeyCode (KeyPress::leftKey)) | |||
| { | |||
| moveOrStretch (layout, -amount, 0, snap, stretch); | |||
| } | |||
| else if (key.isKeyCode (KeyPress::upKey)) | |||
| { | |||
| moveOrStretch (layout, 0, -amount, snap, stretch); | |||
| } | |||
| else | |||
| { | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| bool ComponentLayoutEditor::isInterestedInFileDrag (const StringArray& filenames) | |||
| { | |||
| const File f (filenames [0]); | |||
| return f.hasFileExtension (".cpp"); | |||
| } | |||
| void ComponentLayoutEditor::filesDropped (const StringArray& filenames, int x, int y) | |||
| { | |||
| const File f (filenames [0]); | |||
| if (JucerDocument::isValidJucerCppFile (f)) | |||
| { | |||
| JucerComponentHandler jucerDocHandler; | |||
| layout.getDocument()->beginTransaction(); | |||
| if (TestComponent* newOne = dynamic_cast <TestComponent*> (layout.addNewComponent (&jucerDocHandler, | |||
| x - subCompHolder->getX(), | |||
| y - subCompHolder->getY()))) | |||
| { | |||
| JucerComponentHandler::setJucerComponentFile (*layout.getDocument(), newOne, | |||
| f.getRelativePathFrom (document.getCppFile().getParentDirectory())); | |||
| layout.getSelectedSet().selectOnly (newOne); | |||
| } | |||
| layout.getDocument()->beginTransaction(); | |||
| } | |||
| } | |||
| ComponentOverlayComponent* ComponentLayoutEditor::getOverlayCompFor (Component* compToFind) const | |||
| { | |||
| for (int i = getNumChildComponents(); --i >= 0;) | |||
| { | |||
| if (ComponentOverlayComponent* const overlay = dynamic_cast <ComponentOverlayComponent*> (getChildComponent (i))) | |||
| if (overlay->target == compToFind) | |||
| return overlay; | |||
| } | |||
| return nullptr; | |||
| } | |||
| void ComponentLayoutEditor::findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area) | |||
| { | |||
| const Rectangle<int> lasso (area - subCompHolder->getPosition()); | |||
| for (int i = 0; i < subCompHolder->getNumChildComponents(); ++i) | |||
| { | |||
| Component* c = subCompHolder->getChildComponent (i); | |||
| if (c->getBounds().intersects (lasso)) | |||
| results.add (c); | |||
| } | |||
| } | |||
| SelectedItemSet <Component*>& ComponentLayoutEditor::getLassoSelection() | |||
| { | |||
| return layout.getSelectedSet(); | |||
| } | |||
| @@ -0,0 +1,87 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTLAYOUTEDITOR_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTLAYOUTEDITOR_JUCEHEADER__ | |||
| #include "jucer_ComponentOverlayComponent.h" | |||
| #include "../jucer_JucerDocument.h" | |||
| #include "jucer_SnapGridPainter.h" | |||
| //============================================================================== | |||
| /** | |||
| */ | |||
| class ComponentLayoutEditor : public Component, | |||
| public ChangeListener, | |||
| public FileDragAndDropTarget, | |||
| public LassoSource <Component*> | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentLayoutEditor (JucerDocument& document, ComponentLayout& layout); | |||
| ~ComponentLayoutEditor(); | |||
| //============================================================================== | |||
| void paint (Graphics& g); | |||
| void resized(); | |||
| void visibilityChanged(); | |||
| void changeListenerCallback (ChangeBroadcaster*); | |||
| void mouseDown (const MouseEvent& e); | |||
| void mouseDrag (const MouseEvent& e); | |||
| void mouseUp (const MouseEvent& e); | |||
| bool keyPressed (const KeyPress& key); | |||
| bool isInterestedInFileDrag (const StringArray& files); | |||
| void filesDropped (const StringArray& filenames, int x, int y); | |||
| ComponentLayout& getLayout() const noexcept { return layout; } | |||
| void findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area); | |||
| SelectedItemSet <Component*>& getLassoSelection(); | |||
| //============================================================================== | |||
| void refreshAllComponents(); | |||
| void updateOverlayPositions(); | |||
| ComponentOverlayComponent* getOverlayCompFor (Component*) const; | |||
| Rectangle<int> getComponentArea() const; | |||
| Image createComponentLayerSnapshot() const; | |||
| private: | |||
| JucerDocument& document; | |||
| ComponentLayout& layout; | |||
| Component* subCompHolder; | |||
| LassoComponent <Component*> lassoComp; | |||
| SnapGridPainter grid; | |||
| bool firstResize; | |||
| }; | |||
| #endif // __JUCER_COMPONENTLAYOUTEDITOR_JUCEHEADER__ | |||
| @@ -0,0 +1,124 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTLAYOUTPANEL_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTLAYOUTPANEL_JUCEHEADER__ | |||
| #include "jucer_ComponentLayoutEditor.h" | |||
| #include "jucer_EditingPanelBase.h" | |||
| //============================================================================== | |||
| class ComponentLayoutPanel : public EditingPanelBase | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentLayoutPanel (JucerDocument& doc, ComponentLayout& l) | |||
| : EditingPanelBase (doc, | |||
| new LayoutPropsPanel (doc, l), | |||
| new ComponentLayoutEditor (doc, l)), | |||
| layout (l) | |||
| { | |||
| } | |||
| ~ComponentLayoutPanel() | |||
| { | |||
| deleteAllChildren(); | |||
| } | |||
| void updatePropertiesList() | |||
| { | |||
| ((LayoutPropsPanel*) propsPanel)->updateList(); | |||
| } | |||
| Rectangle<int> getComponentArea() const | |||
| { | |||
| return ((ComponentLayoutEditor*) editor)->getComponentArea(); | |||
| } | |||
| Image createComponentSnapshot() const | |||
| { | |||
| return ((ComponentLayoutEditor*) editor)->createComponentLayerSnapshot(); | |||
| } | |||
| ComponentLayout& getLayout() const noexcept { return layout;} | |||
| private: | |||
| class LayoutPropsPanel : public Component, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| LayoutPropsPanel (JucerDocument& doc, ComponentLayout& l) | |||
| : document (doc), layout (l) | |||
| { | |||
| layout.getSelectedSet().addChangeListener (this); | |||
| addAndMakeVisible (&propsPanel); | |||
| } | |||
| ~LayoutPropsPanel() | |||
| { | |||
| layout.getSelectedSet().removeChangeListener (this); | |||
| clear(); | |||
| } | |||
| void resized() | |||
| { | |||
| propsPanel.setBounds (4, 4, getWidth() - 8, getHeight() - 8); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| updateList(); | |||
| } | |||
| void clear() | |||
| { | |||
| propsPanel.clear(); | |||
| } | |||
| void updateList() | |||
| { | |||
| clear(); | |||
| if (layout.getSelectedSet().getNumSelected() == 1) // xxx need to cope with multiple | |||
| { | |||
| if (Component* comp = layout.getSelectedSet().getSelectedItem (0)) | |||
| if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp)) | |||
| type->addPropertiesToPropertyPanel (comp, document, propsPanel); | |||
| } | |||
| } | |||
| private: | |||
| JucerDocument& document; | |||
| ComponentLayout& layout; | |||
| PropertyPanel propsPanel; | |||
| }; | |||
| ComponentLayout& layout; | |||
| }; | |||
| #endif // __JUCER_COMPONENTLAYOUTPANEL_JUCEHEADER__ | |||
| @@ -0,0 +1,254 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_ComponentLayoutEditor.h" | |||
| #include "../jucer_UtilityFunctions.h" | |||
| //============================================================================== | |||
| ComponentOverlayComponent::ComponentOverlayComponent (Component* const target_, | |||
| ComponentLayout& layout_) | |||
| : target (target_), | |||
| borderThickness (4), | |||
| layout (layout_), | |||
| selected (false), | |||
| dragging (false), | |||
| originalAspectRatio (1.0) | |||
| { | |||
| setMinimumOnscreenAmounts (0, 0, 0, 0); | |||
| setSizeLimits (borderThickness * 2 + 2, borderThickness * 2 + 2, 8192, 8192); | |||
| addChildComponent (border = new ResizableBorderComponent (this, this)); | |||
| border->setBorderThickness (BorderSize<int> (borderThickness)); | |||
| target->addComponentListener (this); | |||
| changeListenerCallback (nullptr); | |||
| layout.getSelectedSet().addChangeListener (this); | |||
| setRepaintsOnMouseActivity (true); | |||
| border->setRepaintsOnMouseActivity (true); | |||
| } | |||
| ComponentOverlayComponent::~ComponentOverlayComponent() | |||
| { | |||
| layout.getSelectedSet().removeChangeListener (this); | |||
| if (target != nullptr) | |||
| target->removeComponentListener (this); | |||
| } | |||
| void ComponentOverlayComponent::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| const bool nowSelected = layout.getSelectedSet().isSelected (target); | |||
| if (selected != nowSelected) | |||
| { | |||
| selected = nowSelected; | |||
| border->setVisible (nowSelected); | |||
| repaint(); | |||
| } | |||
| } | |||
| void ComponentOverlayComponent::paint (Graphics& g) | |||
| { | |||
| jassert (target != nullptr); | |||
| if (selected) | |||
| { | |||
| const BorderSize<int> borderSize (border->getBorderThickness()); | |||
| drawResizableBorder (g, getWidth(), getHeight(), borderSize, (isMouseOverOrDragging() || border->isMouseOverOrDragging())); | |||
| } | |||
| else if (isMouseOverOrDragging()) | |||
| { | |||
| drawMouseOverCorners (g, getWidth(), getHeight()); | |||
| } | |||
| } | |||
| void ComponentOverlayComponent::resized() | |||
| { | |||
| jassert (target != nullptr); | |||
| border->setBounds (getLocalBounds()); | |||
| } | |||
| void ComponentOverlayComponent::mouseDown (const MouseEvent& e) | |||
| { | |||
| dragging = false; | |||
| mouseDownSelectStatus = layout.getSelectedSet().addToSelectionOnMouseDown (target, e.mods); | |||
| if (e.mods.isPopupMenu()) | |||
| { | |||
| showPopupMenu(); | |||
| return; // this may be deleted now.. | |||
| } | |||
| } | |||
| void ComponentOverlayComponent::mouseDrag (const MouseEvent& e) | |||
| { | |||
| if (! e.mods.isPopupMenu()) | |||
| { | |||
| if (selected && ! dragging) | |||
| { | |||
| dragging = ! e.mouseWasClicked(); | |||
| if (dragging) | |||
| layout.startDragging(); | |||
| } | |||
| if (dragging) | |||
| { | |||
| layout.dragSelectedComps (e.getDistanceFromDragStartX(), | |||
| e.getDistanceFromDragStartY()); | |||
| } | |||
| } | |||
| } | |||
| void ComponentOverlayComponent::mouseUp (const MouseEvent& e) | |||
| { | |||
| if (dragging) | |||
| layout.endDragging(); | |||
| layout.getSelectedSet().addToSelectionOnMouseUp (target, e.mods, dragging, mouseDownSelectStatus); | |||
| } | |||
| void ComponentOverlayComponent::componentMovedOrResized (Component&, bool /*wasMoved*/, bool /*wasResized*/) | |||
| { | |||
| updateBoundsToMatchTarget(); | |||
| } | |||
| void ComponentOverlayComponent::updateBoundsToMatchTarget() | |||
| { | |||
| if (Component* const parent = target->getParentComponent()) | |||
| { | |||
| const int dx = parent->getX(); | |||
| const int dy = parent->getY(); | |||
| setBounds (dx + target->getX() - borderThickness, | |||
| dy + target->getY() - borderThickness, | |||
| target->getWidth() + borderThickness * 2, | |||
| target->getHeight() + borderThickness * 2); | |||
| } | |||
| if (border->isMouseButtonDown()) | |||
| layout.changed(); | |||
| } | |||
| void ComponentOverlayComponent::resizeStart() | |||
| { | |||
| if (getHeight() > 0) | |||
| originalAspectRatio = getWidth() / (double) getHeight(); | |||
| else | |||
| originalAspectRatio = 1.0; | |||
| layout.getDocument()->beginTransaction ("Resize components"); | |||
| } | |||
| void ComponentOverlayComponent::resizeEnd() | |||
| { | |||
| layout.getDocument()->beginTransaction(); | |||
| } | |||
| void ComponentOverlayComponent::checkBounds (Rectangle<int>& bounds, | |||
| const Rectangle<int>& previousBounds, | |||
| const Rectangle<int>& limits, | |||
| const bool isStretchingTop, | |||
| const bool isStretchingLeft, | |||
| const bool isStretchingBottom, | |||
| const bool isStretchingRight) | |||
| { | |||
| if (ModifierKeys::getCurrentModifiers().isShiftDown()) | |||
| setFixedAspectRatio (originalAspectRatio); | |||
| else | |||
| setFixedAspectRatio (0.0); | |||
| ComponentBoundsConstrainer::checkBounds (bounds, previousBounds, limits, isStretchingTop, isStretchingLeft, isStretchingBottom, isStretchingRight); | |||
| if (layout.getDocument()->isSnapActive (true)) | |||
| { | |||
| if (Component* const parent = target->getParentComponent()) | |||
| { | |||
| const int dx = parent->getX(); | |||
| const int dy = parent->getY(); | |||
| int x = bounds.getX(); | |||
| int y = bounds.getY(); | |||
| int w = bounds.getWidth(); | |||
| int h = bounds.getHeight(); | |||
| x += borderThickness - dx; | |||
| y += borderThickness - dy; | |||
| w -= borderThickness * 2; | |||
| h -= borderThickness * 2; | |||
| int right = x + w; | |||
| int bottom = y + h; | |||
| if (isStretchingRight) | |||
| right = layout.getDocument()->snapPosition (right); | |||
| if (isStretchingBottom) | |||
| bottom = layout.getDocument()->snapPosition (bottom); | |||
| if (isStretchingLeft) | |||
| x = layout.getDocument()->snapPosition (x); | |||
| if (isStretchingTop) | |||
| y = layout.getDocument()->snapPosition (y); | |||
| w = (right - x) + borderThickness * 2; | |||
| h = (bottom - y) + borderThickness * 2; | |||
| x -= borderThickness - dx; | |||
| y -= borderThickness - dy; | |||
| bounds = Rectangle<int> (x, y, w, h); | |||
| } | |||
| } | |||
| } | |||
| void ComponentOverlayComponent::applyBoundsToComponent (Component* component, const Rectangle<int>& bounds) | |||
| { | |||
| if (component->getBounds() != bounds) | |||
| { | |||
| layout.getDocument()->getUndoManager().undoCurrentTransactionOnly(); | |||
| component->setBounds (bounds); | |||
| if (Component* const parent = target->getParentComponent()) | |||
| target->setBounds (bounds.getX() + borderThickness - parent->getX(), | |||
| bounds.getY() + borderThickness - parent->getY(), | |||
| bounds.getWidth() - borderThickness * 2, | |||
| bounds.getHeight() - borderThickness * 2); | |||
| layout.updateStoredComponentPosition (target, true); | |||
| } | |||
| } | |||
| void ComponentOverlayComponent::showPopupMenu() | |||
| { | |||
| ComponentTypeHandler::getHandlerFor (*target)->showPopupMenu (target, layout); | |||
| } | |||
| @@ -0,0 +1,92 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_COMPONENTOVERLAYCOMPONENT_JUCEHEADER__ | |||
| #define __JUCER_COMPONENTOVERLAYCOMPONENT_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| //============================================================================== | |||
| /** | |||
| */ | |||
| class ComponentOverlayComponent : public Component, | |||
| public ComponentListener, | |||
| public ChangeListener, | |||
| public ComponentBoundsConstrainer | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentOverlayComponent (Component* const targetComponent, | |||
| ComponentLayout& layout); | |||
| ~ComponentOverlayComponent(); | |||
| //============================================================================== | |||
| virtual void showPopupMenu(); | |||
| //============================================================================== | |||
| void paint (Graphics& g); | |||
| void resized(); | |||
| void mouseDown (const MouseEvent& e); | |||
| void mouseDrag (const MouseEvent& e); | |||
| void mouseUp (const MouseEvent& e); | |||
| void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); | |||
| void changeListenerCallback (ChangeBroadcaster*); | |||
| void resizeStart(); | |||
| void resizeEnd(); | |||
| void updateBoundsToMatchTarget(); | |||
| void checkBounds (Rectangle<int>& bounds, | |||
| const Rectangle<int>& previousBounds, | |||
| const Rectangle<int>& limits, | |||
| bool isStretchingTop, | |||
| bool isStretchingLeft, | |||
| bool isStretchingBottom, | |||
| bool isStretchingRight); | |||
| void applyBoundsToComponent (Component* component, const Rectangle<int>& bounds); | |||
| //============================================================================== | |||
| Component::SafePointer<Component> target; | |||
| const int borderThickness; | |||
| private: | |||
| ScopedPointer<ResizableBorderComponent> border; | |||
| ComponentLayout& layout; | |||
| bool selected, dragging, mouseDownSelectStatus; | |||
| double originalAspectRatio; | |||
| }; | |||
| #endif // __JUCER_COMPONENTOVERLAYCOMPONENT_JUCEHEADER__ | |||
| @@ -0,0 +1,241 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_EditingPanelBase.h" | |||
| #include "jucer_JucerDocumentEditor.h" | |||
| //============================================================================== | |||
| class EditingPanelBase::MagnifierComponent : public Component | |||
| { | |||
| public: | |||
| MagnifierComponent (Component* comp) | |||
| : scaleFactor (1.0), content (comp) | |||
| { | |||
| addAndMakeVisible (content); | |||
| childBoundsChanged (content); | |||
| } | |||
| void childBoundsChanged (Component* child) | |||
| { | |||
| const Rectangle<int> childArea (getLocalArea (child, child->getLocalBounds())); | |||
| setSize (childArea.getWidth(), childArea.getHeight()); | |||
| } | |||
| double getScaleFactor() const { return scaleFactor; } | |||
| void setScaleFactor (double newScale) | |||
| { | |||
| scaleFactor = newScale; | |||
| content->setTransform (AffineTransform::scale ((float) scaleFactor, | |||
| (float) scaleFactor)); | |||
| } | |||
| private: | |||
| double scaleFactor; | |||
| ScopedPointer<Component> content; | |||
| }; | |||
| //============================================================================== | |||
| class ZoomingViewport : public Viewport | |||
| { | |||
| public: | |||
| ZoomingViewport (EditingPanelBase* const p) | |||
| : panel (p), isSpaceDown (false) | |||
| { | |||
| } | |||
| void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) | |||
| { | |||
| if (e.mods.isCtrlDown() || e.mods.isAltDown() || e.mods.isCommandDown()) | |||
| { | |||
| const double factor = 1.0f / (1.0f - wheel.deltaY); | |||
| panel->setZoom (panel->getZoom() * factor, e.x, e.y); | |||
| } | |||
| else | |||
| { | |||
| Viewport::mouseWheelMove (e, wheel); | |||
| } | |||
| } | |||
| void dragKeyHeldDown (const bool isKeyDown) | |||
| { | |||
| if (isSpaceDown != isKeyDown) | |||
| { | |||
| isSpaceDown = isKeyDown; | |||
| if (isSpaceDown) | |||
| { | |||
| DraggerOverlayComp* const dc = new DraggerOverlayComp(); | |||
| addAndMakeVisible (dc); | |||
| dc->setBounds (getLocalBounds()); | |||
| } | |||
| else | |||
| { | |||
| for (int i = getNumChildComponents(); --i >= 0;) | |||
| ScopedPointer<DraggerOverlayComp> deleter (dynamic_cast <DraggerOverlayComp*> (getChildComponent (i))); | |||
| } | |||
| } | |||
| } | |||
| private: | |||
| EditingPanelBase* const panel; | |||
| bool isSpaceDown; | |||
| //============================================================================== | |||
| class DraggerOverlayComp : public Component | |||
| { | |||
| public: | |||
| DraggerOverlayComp() | |||
| { | |||
| setMouseCursor (MouseCursor::DraggingHandCursor); | |||
| setAlwaysOnTop (true); | |||
| } | |||
| void mouseDown (const MouseEvent&) | |||
| { | |||
| if (Viewport* viewport = findParentComponentOfClass<Viewport>()) | |||
| { | |||
| startX = viewport->getViewPositionX(); | |||
| startY = viewport->getViewPositionY(); | |||
| } | |||
| } | |||
| void mouseDrag (const MouseEvent& e) | |||
| { | |||
| if (Viewport* viewport = findParentComponentOfClass<Viewport>()) | |||
| viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()), | |||
| startX - e.getDistanceFromDragStartX()), | |||
| jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()), | |||
| startY - e.getDistanceFromDragStartY())); | |||
| } | |||
| private: | |||
| int startX, startY; | |||
| }; | |||
| }; | |||
| //============================================================================== | |||
| EditingPanelBase::EditingPanelBase (JucerDocument& doc, Component* props, Component* editorComp) | |||
| : document (doc), | |||
| editor (editorComp), | |||
| propsPanel (props) | |||
| { | |||
| addAndMakeVisible (viewport = new ZoomingViewport (this)); | |||
| addAndMakeVisible (propsPanel); | |||
| viewport->setViewedComponent (magnifier = new MagnifierComponent (editor)); | |||
| magnifier->setLookAndFeel (&lookAndFeel); | |||
| } | |||
| EditingPanelBase::~EditingPanelBase() | |||
| { | |||
| deleteAllChildren(); | |||
| } | |||
| void EditingPanelBase::resized() | |||
| { | |||
| const int contentW = jmax (1, getWidth() - 260); | |||
| propsPanel->setBounds (contentW + 4, 4, jmax (100, getWidth() - contentW - 8), getHeight() - 8); | |||
| viewport->setBounds (4, 4, contentW - 8, getHeight() - 8); | |||
| if (document.isFixedSize()) | |||
| editor->setSize (jmax (document.getInitialWidth(), | |||
| roundToInt ((viewport->getWidth() - viewport->getScrollBarThickness()) / getZoom())), | |||
| jmax (document.getInitialHeight(), | |||
| roundToInt ((viewport->getHeight() - viewport->getScrollBarThickness()) / getZoom()))); | |||
| else | |||
| editor->setSize (viewport->getWidth(), | |||
| viewport->getHeight()); | |||
| } | |||
| void EditingPanelBase::visibilityChanged() | |||
| { | |||
| if (isVisible()) | |||
| { | |||
| updatePropertiesList(); | |||
| if (Component* p = getParentComponent()) | |||
| { | |||
| resized(); | |||
| if (JucerDocumentEditor* const cdh = dynamic_cast <JucerDocumentEditor*> (p->getParentComponent())) | |||
| cdh->setViewportToLastPos (viewport, *this); | |||
| resized(); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (Component* p = getParentComponent()) | |||
| if (JucerDocumentEditor* const cdh = dynamic_cast <JucerDocumentEditor*> (p->getParentComponent())) | |||
| cdh->storeLastViewportPos (viewport, *this); | |||
| } | |||
| editor->setVisible (isVisible()); | |||
| } | |||
| double EditingPanelBase::getZoom() const | |||
| { | |||
| return magnifier->getScaleFactor(); | |||
| } | |||
| void EditingPanelBase::setZoom (double newScale) | |||
| { | |||
| setZoom (jlimit (1.0 / 8.0, 16.0, newScale), | |||
| viewport->getWidth() / 2, | |||
| viewport->getHeight() / 2); | |||
| } | |||
| void EditingPanelBase::setZoom (double newScale, int anchorX, int anchorY) | |||
| { | |||
| Point<int> anchor (editor->getLocalPoint (viewport, Point<int> (anchorX, anchorY))); | |||
| magnifier->setScaleFactor (newScale); | |||
| resized(); | |||
| anchor = viewport->getLocalPoint (editor, anchor); | |||
| viewport->setViewPosition (jlimit (0, jmax (0, viewport->getViewedComponent()->getWidth() - viewport->getViewWidth()), | |||
| viewport->getViewPositionX() + anchor.getX() - anchorX), | |||
| jlimit (0, jmax (0, viewport->getViewedComponent()->getHeight() - viewport->getViewHeight()), | |||
| viewport->getViewPositionY() + anchor.getY() - anchorY)); | |||
| } | |||
| void EditingPanelBase::xyToTargetXY (int& x, int& y) const | |||
| { | |||
| Point<int> pos (editor->getLocalPoint (this, Point<int> (x, y))); | |||
| x = pos.getX(); | |||
| y = pos.getY(); | |||
| } | |||
| void EditingPanelBase::dragKeyHeldDown (bool isKeyDown) | |||
| { | |||
| ((ZoomingViewport*) viewport)->dragKeyHeldDown (isKeyDown); | |||
| } | |||
| @@ -0,0 +1,80 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_EDITINGPANELBASE_JUCEHEADER__ | |||
| #define __JUCER_EDITINGPANELBASE_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| #include "jucer_ComponentLayoutEditor.h" | |||
| class LayoutPropsPanel; | |||
| //============================================================================== | |||
| /** | |||
| Base class for the layout and graphics panels - this takes care of arranging | |||
| the properties panel and managing the viewport for the content. | |||
| */ | |||
| class EditingPanelBase : public Component | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| EditingPanelBase (JucerDocument& document, | |||
| Component* propsPanel, | |||
| Component* editorComp); | |||
| ~EditingPanelBase(); | |||
| //============================================================================== | |||
| void resized(); | |||
| void visibilityChanged(); | |||
| virtual void updatePropertiesList() = 0; | |||
| virtual Rectangle<int> getComponentArea() const = 0; | |||
| double getZoom() const; | |||
| void setZoom (double newScale); | |||
| void setZoom (double newScale, int anchorX, int anchorY); | |||
| // convert a pos relative to this component into a pos on the editor | |||
| void xyToTargetXY (int& x, int& y) const; | |||
| void dragKeyHeldDown (bool isKeyDown); | |||
| class MagnifierComponent; | |||
| protected: | |||
| JucerDocument& document; | |||
| LookAndFeel lookAndFeel; | |||
| Viewport* viewport; | |||
| MagnifierComponent* magnifier; | |||
| Component* editor; | |||
| Component* propsPanel; | |||
| }; | |||
| #endif // __JUCER_EDITINGPANELBASE_JUCEHEADER__ | |||
| @@ -0,0 +1,59 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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. | |||
| ============================================================================== | |||
| */ | |||
| /** | |||
| A namespace to hold all the possible command IDs. | |||
| */ | |||
| namespace JucerCommandIDs | |||
| { | |||
| static const int test = 0xf20009; | |||
| static const int toFront = 0xf2000a; | |||
| static const int toBack = 0xf2000b; | |||
| static const int group = 0xf20017; | |||
| static const int ungroup = 0xf20018; | |||
| static const int showGrid = 0xf2000e; | |||
| static const int enableSnapToGrid = 0xf2000f; | |||
| static const int editCompLayout = 0xf20010; | |||
| static const int editCompGraphics = 0xf20011; | |||
| static const int bringBackLostItems = 0xf20012; | |||
| static const int zoomIn = 0xf20013; | |||
| static const int zoomOut = 0xf20014; | |||
| static const int zoomNormal = 0xf20015; | |||
| static const int spaceBarDrag = 0xf20016; | |||
| static const int compOverlay0 = 0xf20020; | |||
| static const int compOverlay33 = 0xf20021; | |||
| static const int compOverlay66 = 0xf20022; | |||
| static const int compOverlay100 = 0xf20023; | |||
| static const int newDocumentBase = 0xf32001; | |||
| static const int newComponentBase = 0xf30001; | |||
| static const int newElementBase = 0xf31001; | |||
| } | |||
| @@ -0,0 +1,97 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_JUCERDOCUMENTHOLDER_JUCEHEADER__ | |||
| #define __JUCER_JUCERDOCUMENTHOLDER_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| #include "jucer_ComponentLayoutEditor.h" | |||
| #include "jucer_PaintRoutineEditor.h" | |||
| #include "jucer_ComponentLayoutPanel.h" | |||
| //============================================================================== | |||
| /** | |||
| */ | |||
| class JucerDocumentEditor : public Component, | |||
| public ApplicationCommandTarget, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| JucerDocumentEditor (JucerDocument* const document); | |||
| ~JucerDocumentEditor(); | |||
| JucerDocument* getDocument() const noexcept { return document; } | |||
| void refreshPropertiesPanel() const; | |||
| void updateTabs(); | |||
| void showLayout(); | |||
| void showGraphics (PaintRoutine* routine); | |||
| void setViewportToLastPos (Viewport* vp, EditingPanelBase& editor); | |||
| void storeLastViewportPos (Viewport* vp, EditingPanelBase& editor); | |||
| Image createComponentLayerSnapshot() const; | |||
| //============================================================================== | |||
| void paint (Graphics& g); | |||
| void resized(); | |||
| void changeListenerCallback (ChangeBroadcaster*); | |||
| bool keyPressed (const KeyPress&); | |||
| //============================================================================== | |||
| ApplicationCommandTarget* getNextCommandTarget(); | |||
| void getAllCommands (Array <CommandID>&); | |||
| void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result); | |||
| bool perform (const InvocationInfo&); | |||
| static JucerDocumentEditor* getActiveDocumentHolder(); | |||
| private: | |||
| ScopedPointer<JucerDocument> document; | |||
| TabbedComponent tabbedComponent; | |||
| ComponentLayoutPanel* compLayoutPanel; | |||
| bool isSomethingSelected() const; | |||
| int lastViewportX, lastViewportY; | |||
| double currentZoomLevel; | |||
| // only non-zero if a layout tab is selected | |||
| ComponentLayout* getCurrentLayout() const; | |||
| // only non-zero if a graphics tab is selected | |||
| PaintRoutine* getCurrentPaintRoutine() const; | |||
| void setZoom (double scale); | |||
| double getZoom() const; | |||
| void addElement (const int index); | |||
| void addComponent (const int index); | |||
| }; | |||
| #endif // __JUCER_JUCERDOCUMENTHOLDER_JUCEHEADER__ | |||
| @@ -0,0 +1,280 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "../ui/jucer_JucerCommandIDs.h" | |||
| #include "jucer_PaintRoutineEditor.h" | |||
| #include "../jucer_ObjectTypes.h" | |||
| #include "jucer_JucerDocumentEditor.h" | |||
| //============================================================================== | |||
| PaintRoutineEditor::PaintRoutineEditor (PaintRoutine& pr, JucerDocument& doc, | |||
| JucerDocumentEditor* docHolder) | |||
| : graphics (pr), | |||
| document (doc), | |||
| documentHolder (docHolder), | |||
| componentOverlay (nullptr), | |||
| componentOverlayOpacity (0.0f) | |||
| { | |||
| refreshAllElements(); | |||
| setSize (document.getInitialWidth(), | |||
| document.getInitialHeight()); | |||
| } | |||
| PaintRoutineEditor::~PaintRoutineEditor() | |||
| { | |||
| document.removeChangeListener (this); | |||
| removeAllElementComps(); | |||
| removeChildComponent (&lassoComp); | |||
| deleteAllChildren(); | |||
| } | |||
| void PaintRoutineEditor::removeAllElementComps() | |||
| { | |||
| for (int i = getNumChildComponents(); --i >= 0;) | |||
| if (PaintElement* const e = dynamic_cast <PaintElement*> (getChildComponent (i))) | |||
| removeChildComponent (e); | |||
| } | |||
| Rectangle<int> PaintRoutineEditor::getComponentArea() const | |||
| { | |||
| if (document.isFixedSize()) | |||
| return Rectangle<int> ((getWidth() - document.getInitialWidth()) / 2, | |||
| (getHeight() - document.getInitialHeight()) / 2, | |||
| document.getInitialWidth(), | |||
| document.getInitialHeight()); | |||
| return getLocalBounds().reduced (4); | |||
| } | |||
| //============================================================================== | |||
| void PaintRoutineEditor::paint (Graphics& g) | |||
| { | |||
| const Rectangle<int> clip (getComponentArea()); | |||
| g.setOrigin (clip.getX(), clip.getY()); | |||
| g.reduceClipRegion (0, 0, clip.getWidth(), clip.getHeight()); | |||
| graphics.fillWithBackground (g, true); | |||
| grid.draw (g, &graphics); | |||
| } | |||
| void PaintRoutineEditor::paintOverChildren (Graphics& g) | |||
| { | |||
| if (componentOverlay.isNull() && document.getComponentOverlayOpacity() > 0.0f) | |||
| updateComponentOverlay(); | |||
| if (componentOverlay.isValid()) | |||
| { | |||
| const Rectangle<int> clip (getComponentArea()); | |||
| g.drawImageAt (componentOverlay, clip.getX(), clip.getY()); | |||
| } | |||
| } | |||
| void PaintRoutineEditor::resized() | |||
| { | |||
| if (getWidth() > 0 && getHeight() > 0) | |||
| { | |||
| componentOverlay = Image(); | |||
| refreshAllElements(); | |||
| } | |||
| } | |||
| void PaintRoutineEditor::updateChildBounds() | |||
| { | |||
| const Rectangle<int> clip (getComponentArea()); | |||
| for (int i = 0; i < getNumChildComponents(); ++i) | |||
| if (PaintElement* const e = dynamic_cast <PaintElement*> (getChildComponent (i))) | |||
| e->updateBounds (clip); | |||
| } | |||
| void PaintRoutineEditor::updateComponentOverlay() | |||
| { | |||
| if (componentOverlay.isValid()) | |||
| repaint(); | |||
| componentOverlay = Image(); | |||
| componentOverlayOpacity = document.getComponentOverlayOpacity(); | |||
| if (componentOverlayOpacity > 0.0f) | |||
| { | |||
| if (documentHolder != nullptr) | |||
| componentOverlay = documentHolder->createComponentLayerSnapshot(); | |||
| if (componentOverlay.isValid()) | |||
| { | |||
| componentOverlay.multiplyAllAlphas (componentOverlayOpacity); | |||
| repaint(); | |||
| } | |||
| } | |||
| } | |||
| void PaintRoutineEditor::visibilityChanged() | |||
| { | |||
| document.beginTransaction(); | |||
| if (isVisible()) | |||
| { | |||
| refreshAllElements(); | |||
| document.addChangeListener (this); | |||
| } | |||
| else | |||
| { | |||
| document.removeChangeListener (this); | |||
| componentOverlay = Image(); | |||
| } | |||
| } | |||
| void PaintRoutineEditor::refreshAllElements() | |||
| { | |||
| for (int i = getNumChildComponents(); --i >= 0;) | |||
| if (PaintElement* const e = dynamic_cast <PaintElement*> (getChildComponent (i))) | |||
| if (! graphics.containsElement (e)) | |||
| removeChildComponent (e); | |||
| Component* last = nullptr; | |||
| for (int i = graphics.getNumElements(); --i >= 0;) | |||
| { | |||
| PaintElement* const e = graphics.getElement (i); | |||
| addAndMakeVisible (e); | |||
| if (last != nullptr) | |||
| e->toBehind (last); | |||
| else | |||
| e->toFront (false); | |||
| last = e; | |||
| } | |||
| updateChildBounds(); | |||
| if (grid.updateFromDesign (document)) | |||
| repaint(); | |||
| if (currentBackgroundColour != graphics.getBackgroundColour()) | |||
| { | |||
| currentBackgroundColour = graphics.getBackgroundColour(); | |||
| grid.updateColour(); | |||
| repaint(); | |||
| } | |||
| if (componentOverlayOpacity != document.getComponentOverlayOpacity()) | |||
| { | |||
| componentOverlay = Image(); | |||
| componentOverlayOpacity = document.getComponentOverlayOpacity(); | |||
| repaint(); | |||
| } | |||
| } | |||
| void PaintRoutineEditor::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refreshAllElements(); | |||
| } | |||
| void PaintRoutineEditor::mouseDown (const MouseEvent& e) | |||
| { | |||
| if (e.mods.isPopupMenu()) | |||
| { | |||
| PopupMenu m; | |||
| m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout); | |||
| m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics); | |||
| m.addSeparator(); | |||
| for (int i = 0; i < ObjectTypes::numElementTypes; ++i) | |||
| m.addCommandItem (commandManager, JucerCommandIDs::newElementBase + i); | |||
| m.show(); | |||
| } | |||
| else | |||
| { | |||
| addChildComponent (&lassoComp); | |||
| lassoComp.beginLasso (e, this); | |||
| } | |||
| } | |||
| void PaintRoutineEditor::mouseDrag (const MouseEvent& e) | |||
| { | |||
| lassoComp.toFront (false); | |||
| lassoComp.dragLasso (e); | |||
| } | |||
| void PaintRoutineEditor::mouseUp (const MouseEvent& e) | |||
| { | |||
| lassoComp.endLasso(); | |||
| if (e.mouseWasClicked() && ! e.mods.isAnyModifierKeyDown()) | |||
| { | |||
| graphics.getSelectedElements().deselectAll(); | |||
| graphics.getSelectedPoints().deselectAll(); | |||
| } | |||
| } | |||
| void PaintRoutineEditor::findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& lasso) | |||
| { | |||
| for (int i = 0; i < getNumChildComponents(); ++i) | |||
| if (PaintElement* const e = dynamic_cast <PaintElement*> (getChildComponent (i))) | |||
| if (e->getBounds().expanded (-e->borderThickness, -e->borderThickness).intersects (lasso)) | |||
| results.add (e); | |||
| } | |||
| SelectedItemSet <PaintElement*>& PaintRoutineEditor::getLassoSelection() | |||
| { | |||
| return graphics.getSelectedElements(); | |||
| } | |||
| bool PaintRoutineEditor::isInterestedInFileDrag (const StringArray& files) | |||
| { | |||
| return File::createFileWithoutCheckingPath (files[0]) | |||
| .hasFileExtension ("jpg;jpeg;png;gif;svg"); | |||
| } | |||
| void PaintRoutineEditor::filesDropped (const StringArray& filenames, int x, int y) | |||
| { | |||
| const File f (filenames [0]); | |||
| if (f.existsAsFile()) | |||
| { | |||
| ScopedPointer<Drawable> d (Drawable::createFromImageFile (f)); | |||
| if (d != nullptr) | |||
| { | |||
| d = nullptr; | |||
| document.beginTransaction(); | |||
| graphics.dropImageAt (f, | |||
| jlimit (10, getWidth() - 10, x), | |||
| jlimit (10, getHeight() - 10, y)); | |||
| document.beginTransaction(); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,90 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTROUTINEEDITOR_JUCEHEADER__ | |||
| #define __JUCER_PAINTROUTINEEDITOR_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| #include "../jucer_PaintRoutine.h" | |||
| #include "jucer_SnapGridPainter.h" | |||
| class JucerDocumentEditor; | |||
| //============================================================================== | |||
| /** | |||
| */ | |||
| class PaintRoutineEditor : public Component, | |||
| public ChangeListener, | |||
| public LassoSource <PaintElement*>, | |||
| public FileDragAndDropTarget | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| PaintRoutineEditor (PaintRoutine& graphics, | |||
| JucerDocument& document, | |||
| JucerDocumentEditor* const docHolder); | |||
| ~PaintRoutineEditor(); | |||
| //============================================================================== | |||
| void paint (Graphics& g); | |||
| void paintOverChildren (Graphics& g); | |||
| void resized(); | |||
| void changeListenerCallback (ChangeBroadcaster*); | |||
| void mouseDown (const MouseEvent& e); | |||
| void mouseDrag (const MouseEvent& e); | |||
| void mouseUp (const MouseEvent& e); | |||
| void visibilityChanged(); | |||
| void findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& area); | |||
| SelectedItemSet <PaintElement*>& getLassoSelection(); | |||
| bool isInterestedInFileDrag (const StringArray& files); | |||
| void filesDropped (const StringArray& filenames, int x, int y); | |||
| Rectangle<int> getComponentArea() const; | |||
| //============================================================================== | |||
| void refreshAllElements(); | |||
| private: | |||
| PaintRoutine& graphics; | |||
| JucerDocument& document; | |||
| JucerDocumentEditor* const documentHolder; | |||
| LassoComponent <PaintElement*> lassoComp; | |||
| SnapGridPainter grid; | |||
| Image componentOverlay; | |||
| float componentOverlayOpacity; | |||
| Colour currentBackgroundColour; | |||
| void removeAllElementComps(); | |||
| void updateComponentOverlay(); | |||
| void updateChildBounds(); | |||
| }; | |||
| #endif // __JUCER_PAINTROUTINEEDITOR_JUCEHEADER__ | |||
| @@ -0,0 +1,181 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_PaintRoutinePanel.h" | |||
| #include "../properties/jucer_ColourPropertyComponent.h" | |||
| #include "../paintelements/jucer_PaintElementPath.h" | |||
| //============================================================================== | |||
| class ComponentBackgroundColourProperty : public JucerColourPropertyComponent, | |||
| private ChangeListener | |||
| { | |||
| public: | |||
| ComponentBackgroundColourProperty (JucerDocument& doc, | |||
| PaintRoutine& routine_) | |||
| : JucerColourPropertyComponent ("background", false), | |||
| document (doc), | |||
| routine (routine_) | |||
| { | |||
| document.addChangeListener (this); | |||
| } | |||
| ~ComponentBackgroundColourProperty() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| refresh(); | |||
| } | |||
| void setColour (const Colour& newColour) { routine.setBackgroundColour (newColour); } | |||
| Colour getColour() const { return routine.getBackgroundColour(); } | |||
| void resetToDefault() | |||
| { | |||
| jassertfalse; // option shouldn't be visible | |||
| } | |||
| protected: | |||
| JucerDocument& document; | |||
| PaintRoutine& routine; | |||
| }; | |||
| //============================================================================== | |||
| class GraphicsPropsPanel : public Component, | |||
| public ChangeListener | |||
| { | |||
| public: | |||
| GraphicsPropsPanel (PaintRoutine& paintRoutine_, | |||
| JucerDocument* doc) | |||
| : paintRoutine (paintRoutine_), | |||
| document (doc) | |||
| { | |||
| paintRoutine.getSelectedElements().addChangeListener (this); | |||
| paintRoutine.getSelectedPoints().addChangeListener (this); | |||
| addAndMakeVisible (propsPanel = new PropertyPanel()); | |||
| } | |||
| ~GraphicsPropsPanel() | |||
| { | |||
| paintRoutine.getSelectedPoints().removeChangeListener (this); | |||
| paintRoutine.getSelectedElements().removeChangeListener (this); | |||
| clear(); | |||
| deleteAllChildren(); | |||
| } | |||
| void resized() | |||
| { | |||
| propsPanel->setBounds (4, 4, getWidth() - 8, getHeight() - 8); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| updateList(); | |||
| } | |||
| void clear() | |||
| { | |||
| propsPanel->clear(); | |||
| } | |||
| void updateList() | |||
| { | |||
| ScopedPointer<XmlElement> state (propsPanel->getOpennessState()); | |||
| clear(); | |||
| if (document != nullptr) | |||
| { | |||
| Array <PropertyComponent*> props; | |||
| props.add (new ComponentBackgroundColourProperty (*document, paintRoutine)); | |||
| propsPanel->addSection ("Class Properties", props); | |||
| } | |||
| if (state != nullptr) | |||
| propsPanel->restoreOpennessState (*state); | |||
| if (paintRoutine.getSelectedElements().getNumSelected() == 1) // xxx need to cope with multiple | |||
| { | |||
| if (PaintElement* const pe = paintRoutine.getSelectedElements().getSelectedItem (0)) | |||
| { | |||
| Array <PropertyComponent*> props; | |||
| pe->getEditableProperties (props); | |||
| propsPanel->addSection (pe->getTypeName(), props); | |||
| } | |||
| } | |||
| if (paintRoutine.getSelectedPoints().getNumSelected() == 1) // xxx need to cope with multiple | |||
| { | |||
| if (PathPoint* const point = paintRoutine.getSelectedPoints().getSelectedItem (0)) | |||
| { | |||
| Array <PropertyComponent*> props; | |||
| point->getEditableProperties (props); | |||
| propsPanel->addSection ("Path segment", props); | |||
| } | |||
| } | |||
| } | |||
| private: | |||
| PaintRoutine& paintRoutine; | |||
| JucerDocument* document; | |||
| PropertyPanel* propsPanel; | |||
| }; | |||
| //============================================================================== | |||
| PaintRoutinePanel::PaintRoutinePanel (JucerDocument& doc, PaintRoutine& pr, | |||
| JucerDocumentEditor* documentHolder) | |||
| : EditingPanelBase (doc, | |||
| new GraphicsPropsPanel (pr, &doc), | |||
| new PaintRoutineEditor (pr, doc, documentHolder)), | |||
| routine (pr) | |||
| { | |||
| } | |||
| PaintRoutinePanel::~PaintRoutinePanel() | |||
| { | |||
| deleteAllChildren(); | |||
| } | |||
| void PaintRoutinePanel::updatePropertiesList() | |||
| { | |||
| ((GraphicsPropsPanel*) propsPanel)->updateList(); | |||
| } | |||
| Rectangle<int> PaintRoutinePanel::getComponentArea() const | |||
| { | |||
| return ((PaintRoutineEditor*) editor)->getComponentArea(); | |||
| } | |||
| @@ -0,0 +1,50 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_PAINTROUTINEPANEL_JUCEHEADER__ | |||
| #define __JUCER_PAINTROUTINEPANEL_JUCEHEADER__ | |||
| #include "jucer_PaintRoutineEditor.h" | |||
| #include "jucer_EditingPanelBase.h" | |||
| //============================================================================== | |||
| class PaintRoutinePanel : public EditingPanelBase | |||
| { | |||
| public: | |||
| PaintRoutinePanel (JucerDocument&, PaintRoutine&, JucerDocumentEditor*); | |||
| ~PaintRoutinePanel(); | |||
| PaintRoutine& getPaintRoutine() const noexcept { return routine; } | |||
| void updatePropertiesList(); | |||
| Rectangle<int> getComponentArea() const; | |||
| private: | |||
| PaintRoutine& routine; | |||
| }; | |||
| #endif // __JUCER_PAINTROUTINEPANEL_JUCEHEADER__ | |||
| @@ -0,0 +1,765 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_RELATIVEPOSITIONEDRECTANGLE_H_D07A846__ | |||
| #define __JUCER_RELATIVEPOSITIONEDRECTANGLE_H_D07A846__ | |||
| class ComponentLayout; | |||
| //============================================================================== | |||
| /** | |||
| A rectangle whose co-ordinates can be defined in terms of absolute or | |||
| proportional distances. | |||
| Designed mainly for storing component positions, this gives you a lot of | |||
| control over how each co-ordinate is stored, either as an absolute position, | |||
| or as a proportion of the size of a parent rectangle. | |||
| It also allows you to define the anchor points by which the rectangle is | |||
| positioned, so for example you could specify that the top right of the | |||
| rectangle should be an absolute distance from its parent's bottom-right corner. | |||
| This object can be stored as a string, which takes the form "x y w h", including | |||
| symbols like '%' and letters to indicate the anchor point. See its toString() | |||
| method for more info. | |||
| Example usage: | |||
| @code | |||
| class MyComponent | |||
| { | |||
| void resized() | |||
| { | |||
| // this will set the child component's x to be 20% of our width, its y | |||
| // to be 30, its width to be 150, and its height to be 50% of our | |||
| // height.. | |||
| const PositionedRectangle pos1 ("20% 30 150 50%"); | |||
| pos1.applyToComponent (*myChildComponent1); | |||
| // this will inset the child component with a gap of 10 pixels | |||
| // around each of its edges.. | |||
| const PositionedRectangle pos2 ("10 10 20M 20M"); | |||
| pos2.applyToComponent (*myChildComponent2); | |||
| } | |||
| }; | |||
| @endcode | |||
| */ | |||
| class PositionedRectangle | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an empty rectangle with all co-ordinates set to zero. | |||
| The default anchor point is top-left; the default | |||
| */ | |||
| PositionedRectangle() noexcept | |||
| : x (0.0), y (0.0), w (0.0), h (0.0), | |||
| xMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), | |||
| yMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), | |||
| wMode (absoluteSize), hMode (absoluteSize) | |||
| { | |||
| } | |||
| /** Initialises a PositionedRectangle from a saved string version. | |||
| The string must be in the format generated by toString(). | |||
| */ | |||
| PositionedRectangle (const String& stringVersion) noexcept | |||
| { | |||
| StringArray tokens; | |||
| tokens.addTokens (stringVersion, false); | |||
| decodePosString (tokens [0], xMode, x); | |||
| decodePosString (tokens [1], yMode, y); | |||
| decodeSizeString (tokens [2], wMode, w); | |||
| decodeSizeString (tokens [3], hMode, h); | |||
| } | |||
| /** Creates a copy of another PositionedRectangle. */ | |||
| PositionedRectangle (const PositionedRectangle& other) noexcept | |||
| : x (other.x), y (other.y), w (other.w), h (other.h), | |||
| xMode (other.xMode), yMode (other.yMode), | |||
| wMode (other.wMode), hMode (other.hMode) | |||
| { | |||
| } | |||
| /** Copies another PositionedRectangle. */ | |||
| PositionedRectangle& operator= (const PositionedRectangle& other) noexcept | |||
| { | |||
| x = other.x; | |||
| y = other.y; | |||
| w = other.w; | |||
| h = other.h; | |||
| xMode = other.xMode; | |||
| yMode = other.yMode; | |||
| wMode = other.wMode; | |||
| hMode = other.hMode; | |||
| return *this; | |||
| } | |||
| //============================================================================== | |||
| /** Returns a string version of this position, from which it can later be | |||
| re-generated. | |||
| The format is four co-ordinates, "x y w h". | |||
| - If a co-ordinate is absolute, it is stored as an integer, e.g. "100". | |||
| - If a co-ordinate is proportional to its parent's width or height, it is stored | |||
| as a percentage, e.g. "80%". | |||
| - If the X or Y co-ordinate is relative to the parent's right or bottom edge, the | |||
| number has "R" appended to it, e.g. "100R" means a distance of 100 pixels from | |||
| the parent's right-hand edge. | |||
| - If the X or Y co-ordinate is relative to the parent's centre, the number has "C" | |||
| appended to it, e.g. "-50C" would be 50 pixels left of the parent's centre. | |||
| - If the X or Y co-ordinate should be anchored at the component's right or bottom | |||
| edge, then it has "r" appended to it. So "-50Rr" would mean that this component's | |||
| right-hand edge should be 50 pixels left of the parent's right-hand edge. | |||
| - If the X or Y co-ordinate should be anchored at the component's centre, then it | |||
| has "c" appended to it. So "-50Rc" would mean that this component's | |||
| centre should be 50 pixels left of the parent's right-hand edge. "40%c" means that | |||
| this component's centre should be placed 40% across the parent's width. | |||
| - If it's a width or height that should use the parentSizeMinusAbsolute mode, then | |||
| the number has "M" appended to it. | |||
| To reload a stored string, use the constructor that takes a string parameter. | |||
| */ | |||
| String toString() const | |||
| { | |||
| String s; | |||
| s.preallocateBytes (32); | |||
| addPosDescription (s, xMode, x); s << ' '; | |||
| addPosDescription (s, yMode, y); s << ' '; | |||
| addSizeDescription (s, wMode, w); s << ' '; | |||
| addSizeDescription (s, hMode, h); | |||
| return s; | |||
| } | |||
| //============================================================================== | |||
| /** Calculates the absolute position, given the size of the space that | |||
| it should go in. | |||
| This will work out any proportional distances and sizes relative to the | |||
| target rectangle, and will return the absolute position. | |||
| @see applyToComponent | |||
| */ | |||
| Rectangle<int> getRectangle (const Rectangle<int>& target) const noexcept | |||
| { | |||
| jassert (! target.isEmpty()); | |||
| double x_, y_, w_, h_; | |||
| applyPosAndSize (x_, w_, x, w, xMode, wMode, target.getX(), target.getWidth()); | |||
| applyPosAndSize (y_, h_, y, h, yMode, hMode, target.getY(), target.getHeight()); | |||
| return Rectangle<int> (roundToInt (x_), roundToInt (y_), roundToInt (w_), roundToInt (h_)); | |||
| } | |||
| /** Same as getRectangle(), but returning the values as doubles rather than ints. */ | |||
| void getRectangleDouble (const Rectangle<int>& target, | |||
| double& x_, double& y_, double& w_, double& h_) const noexcept | |||
| { | |||
| jassert (! target.isEmpty()); | |||
| applyPosAndSize (x_, w_, x, w, xMode, wMode, target.getX(), target.getWidth()); | |||
| applyPosAndSize (y_, h_, y, h, yMode, hMode, target.getY(), target.getHeight()); | |||
| } | |||
| /** This sets the bounds of the given component to this position. | |||
| This is equivalent to writing: | |||
| @code | |||
| comp.setBounds (getRectangle (Rectangle<int> (0, 0, comp.getParentWidth(), comp.getParentHeight()))); | |||
| @endcode | |||
| @see getRectangle, updateFromComponent | |||
| */ | |||
| void applyToComponent (Component& comp) const noexcept | |||
| { | |||
| comp.setBounds (getRectangle (Rectangle<int> (comp.getParentWidth(), comp.getParentHeight()))); | |||
| } | |||
| //============================================================================== | |||
| /** Updates this object's co-ordinates to match the given rectangle. | |||
| This will set all co-ordinates based on the given rectangle, re-calculating | |||
| any proportional distances, and using the current anchor points. | |||
| So for example if the x co-ordinate mode is currently proportional, this will | |||
| re-calculate x based on the rectangle's relative position within the target | |||
| rectangle's width. | |||
| If the target rectangle's width or height are zero then it may not be possible | |||
| to re-calculate some proportional co-ordinates. In this case, those co-ordinates | |||
| will not be changed. | |||
| */ | |||
| void updateFrom (const Rectangle<int>& newPosition, | |||
| const Rectangle<int>& targetSpaceToBeRelativeTo) noexcept | |||
| { | |||
| updatePosAndSize (x, w, newPosition.getX(), newPosition.getWidth(), xMode, wMode, targetSpaceToBeRelativeTo.getX(), targetSpaceToBeRelativeTo.getWidth()); | |||
| updatePosAndSize (y, h, newPosition.getY(), newPosition.getHeight(), yMode, hMode, targetSpaceToBeRelativeTo.getY(), targetSpaceToBeRelativeTo.getHeight()); | |||
| } | |||
| /** Same functionality as updateFrom(), but taking doubles instead of ints. | |||
| */ | |||
| void updateFromDouble (const double newX, const double newY, | |||
| const double newW, const double newH, | |||
| const Rectangle<int>& target) noexcept | |||
| { | |||
| updatePosAndSize (x, w, newX, newW, xMode, wMode, target.getX(), target.getWidth()); | |||
| updatePosAndSize (y, h, newY, newH, yMode, hMode, target.getY(), target.getHeight()); | |||
| } | |||
| /** Updates this object's co-ordinates to match the bounds of this component. | |||
| This is equivalent to calling updateFrom() with the component's bounds and | |||
| it parent size. | |||
| If the component doesn't currently have a parent, then proportional co-ordinates | |||
| might not be updated because it would need to know the parent's size to do the | |||
| maths for this. | |||
| */ | |||
| void updateFromComponent (const Component& comp) noexcept | |||
| { | |||
| if (comp.getParentComponent() == 0 && ! comp.isOnDesktop()) | |||
| updateFrom (comp.getBounds(), Rectangle<int>()); | |||
| else | |||
| updateFrom (comp.getBounds(), Rectangle<int> (comp.getParentWidth(), comp.getParentHeight())); | |||
| } | |||
| //============================================================================== | |||
| /** Specifies the point within the rectangle, relative to which it should be positioned. */ | |||
| enum AnchorPoint | |||
| { | |||
| anchorAtLeftOrTop = 1 << 0, /**< The x or y co-ordinate specifies where the left or top edge of the rectangle should be. */ | |||
| anchorAtRightOrBottom = 1 << 1, /**< The x or y co-ordinate specifies where the right or bottom edge of the rectangle should be. */ | |||
| anchorAtCentre = 1 << 2 /**< The x or y co-ordinate specifies where the centre of the rectangle should be. */ | |||
| }; | |||
| /** Specifies how an x or y co-ordinate should be interpreted. */ | |||
| enum PositionMode | |||
| { | |||
| absoluteFromParentTopLeft = 1 << 3, /**< The x or y co-ordinate specifies an absolute distance from the parent's top or left edge. */ | |||
| absoluteFromParentBottomRight = 1 << 4, /**< The x or y co-ordinate specifies an absolute distance from the parent's bottom or right edge. */ | |||
| absoluteFromParentCentre = 1 << 5, /**< The x or y co-ordinate specifies an absolute distance from the parent's centre. */ | |||
| proportionOfParentSize = 1 << 6 /**< The x or y co-ordinate specifies a proportion of the parent's width or height, measured from the parent's top or left. */ | |||
| }; | |||
| /** Specifies how the width or height should be interpreted. */ | |||
| enum SizeMode | |||
| { | |||
| absoluteSize = 1 << 0, /**< The width or height specifies an absolute size. */ | |||
| parentSizeMinusAbsolute = 1 << 1, /**< The width or height is an amount that should be subtracted from the parent's width or height. */ | |||
| proportionalSize = 1 << 2, /**< The width or height specifies a proportion of the parent's width or height. */ | |||
| }; | |||
| //============================================================================== | |||
| /** Sets all options for all co-ordinates. | |||
| This requires a reference rectangle to be specified, because if you're changing any | |||
| of the modes from proportional to absolute or vice-versa, then it'll need to convert | |||
| the co-ordinates, and will need to know the parent size so it can calculate this. | |||
| */ | |||
| void setModes (const AnchorPoint xAnchor, const PositionMode xMode_, | |||
| const AnchorPoint yAnchor, const PositionMode yMode_, | |||
| const SizeMode widthMode, const SizeMode heightMode, | |||
| const Rectangle<int>& target) noexcept | |||
| { | |||
| if (xMode != (xAnchor | xMode_) || wMode != widthMode) | |||
| { | |||
| double tx, tw; | |||
| applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth()); | |||
| xMode = (uint8) (xAnchor | xMode_); | |||
| wMode = (uint8) widthMode; | |||
| updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth()); | |||
| } | |||
| if (yMode != (yAnchor | yMode_) || hMode != heightMode) | |||
| { | |||
| double ty, th; | |||
| applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight()); | |||
| yMode = (uint8) (yAnchor | yMode_); | |||
| hMode = (uint8) heightMode; | |||
| updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight()); | |||
| } | |||
| } | |||
| /** Returns the anchoring mode for the x co-ordinate. | |||
| To change any of the modes, use setModes(). | |||
| */ | |||
| AnchorPoint getAnchorPointX() const noexcept | |||
| { | |||
| return (AnchorPoint) (xMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); | |||
| } | |||
| /** Returns the positioning mode for the x co-ordinate. | |||
| To change any of the modes, use setModes(). | |||
| */ | |||
| PositionMode getPositionModeX() const noexcept | |||
| { | |||
| return (PositionMode) (xMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight | |||
| | absoluteFromParentCentre | proportionOfParentSize)); | |||
| } | |||
| /** Returns the raw x co-ordinate. | |||
| If the x position mode is absolute, then this will be the absolute value. If it's | |||
| proportional, then this will be a fractional proportion, where 1.0 means the full | |||
| width of the parent space. | |||
| */ | |||
| double getX() const noexcept { return x; } | |||
| /** Sets the raw value of the x co-ordinate. | |||
| See getX() for the meaning of this value. | |||
| */ | |||
| void setX (const double newX) noexcept { x = newX; } | |||
| /** Returns the anchoring mode for the y co-ordinate. | |||
| To change any of the modes, use setModes(). | |||
| */ | |||
| AnchorPoint getAnchorPointY() const noexcept | |||
| { | |||
| return (AnchorPoint) (yMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); | |||
| } | |||
| /** Returns the positioning mode for the y co-ordinate. | |||
| To change any of the modes, use setModes(). | |||
| */ | |||
| PositionMode getPositionModeY() const noexcept | |||
| { | |||
| return (PositionMode) (yMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight | |||
| | absoluteFromParentCentre | proportionOfParentSize)); | |||
| } | |||
| /** Returns the raw y co-ordinate. | |||
| If the y position mode is absolute, then this will be the absolute value. If it's | |||
| proportional, then this will be a fractional proportion, where 1.0 means the full | |||
| height of the parent space. | |||
| */ | |||
| double getY() const noexcept { return y; } | |||
| /** Sets the raw value of the y co-ordinate. | |||
| See getY() for the meaning of this value. | |||
| */ | |||
| void setY (const double newY) noexcept { y = newY; } | |||
| /** Returns the mode used to calculate the width. | |||
| To change any of the modes, use setModes(). | |||
| */ | |||
| SizeMode getWidthMode() const noexcept { return (SizeMode) wMode; } | |||
| /** Returns the raw width value. | |||
| If the width mode is absolute, then this will be the absolute value. If the mode is | |||
| proportional, then this will be a fractional proportion, where 1.0 means the full | |||
| width of the parent space. | |||
| */ | |||
| double getWidth() const noexcept { return w; } | |||
| /** Sets the raw width value. | |||
| See getWidth() for the details about what this value means. | |||
| */ | |||
| void setWidth (const double newWidth) noexcept { w = newWidth; } | |||
| /** Returns the mode used to calculate the height. | |||
| To change any of the modes, use setModes(). | |||
| */ | |||
| SizeMode getHeightMode() const noexcept { return (SizeMode) hMode; } | |||
| /** Returns the raw height value. | |||
| If the height mode is absolute, then this will be the absolute value. If the mode is | |||
| proportional, then this will be a fractional proportion, where 1.0 means the full | |||
| height of the parent space. | |||
| */ | |||
| double getHeight() const noexcept { return h; } | |||
| /** Sets the raw height value. | |||
| See getHeight() for the details about what this value means. | |||
| */ | |||
| void setHeight (const double newHeight) noexcept { h = newHeight; } | |||
| //============================================================================== | |||
| /** If the size and position are constance, and wouldn't be affected by changes | |||
| in the parent's size, then this will return true. | |||
| */ | |||
| bool isPositionAbsolute() const noexcept | |||
| { | |||
| return xMode == absoluteFromParentTopLeft | |||
| && yMode == absoluteFromParentTopLeft | |||
| && wMode == absoluteSize | |||
| && hMode == absoluteSize; | |||
| } | |||
| //============================================================================== | |||
| /** Compares two objects. */ | |||
| bool operator== (const PositionedRectangle& other) const noexcept | |||
| { | |||
| return x == other.x && y == other.y | |||
| && w == other.w && h == other.h | |||
| && xMode == other.xMode && yMode == other.yMode | |||
| && wMode == other.wMode && hMode == other.hMode; | |||
| } | |||
| /** Compares two objects. */ | |||
| bool operator!= (const PositionedRectangle& other) const noexcept | |||
| { | |||
| return ! operator== (other); | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| double x, y, w, h; | |||
| uint8 xMode, yMode, wMode, hMode; | |||
| void addPosDescription (String& s, const uint8 mode, const double value) const noexcept | |||
| { | |||
| if ((mode & proportionOfParentSize) != 0) | |||
| { | |||
| s << (roundToInt (value * 100000.0) / 1000.0) << '%'; | |||
| } | |||
| else | |||
| { | |||
| s << (roundToInt (value * 100.0) / 100.0); | |||
| if ((mode & absoluteFromParentBottomRight) != 0) | |||
| s << 'R'; | |||
| else if ((mode & absoluteFromParentCentre) != 0) | |||
| s << 'C'; | |||
| } | |||
| if ((mode & anchorAtRightOrBottom) != 0) | |||
| s << 'r'; | |||
| else if ((mode & anchorAtCentre) != 0) | |||
| s << 'c'; | |||
| } | |||
| void addSizeDescription (String& s, const uint8 mode, const double value) const noexcept | |||
| { | |||
| if (mode == proportionalSize) | |||
| s << (roundToInt (value * 100000.0) / 1000.0) << '%'; | |||
| else if (mode == parentSizeMinusAbsolute) | |||
| s << (roundToInt (value * 100.0) / 100.0) << 'M'; | |||
| else | |||
| s << (roundToInt (value * 100.0) / 100.0); | |||
| } | |||
| void decodePosString (const String& s, uint8& mode, double& value) noexcept | |||
| { | |||
| if (s.containsChar ('r')) | |||
| mode = anchorAtRightOrBottom; | |||
| else if (s.containsChar ('c')) | |||
| mode = anchorAtCentre; | |||
| else | |||
| mode = anchorAtLeftOrTop; | |||
| if (s.containsChar ('%')) | |||
| { | |||
| mode |= proportionOfParentSize; | |||
| value = s.removeCharacters ("%rcRC").getDoubleValue() / 100.0; | |||
| } | |||
| else | |||
| { | |||
| if (s.containsChar ('R')) | |||
| mode |= absoluteFromParentBottomRight; | |||
| else if (s.containsChar ('C')) | |||
| mode |= absoluteFromParentCentre; | |||
| else | |||
| mode |= absoluteFromParentTopLeft; | |||
| value = s.removeCharacters ("rcRC").getDoubleValue(); | |||
| } | |||
| } | |||
| void decodeSizeString (const String& s, uint8& mode, double& value) noexcept | |||
| { | |||
| if (s.containsChar ('%')) | |||
| { | |||
| mode = proportionalSize; | |||
| value = s.upToFirstOccurrenceOf ("%", false, false).getDoubleValue() / 100.0; | |||
| } | |||
| else if (s.containsChar ('M')) | |||
| { | |||
| mode = parentSizeMinusAbsolute; | |||
| value = s.getDoubleValue(); | |||
| } | |||
| else | |||
| { | |||
| mode = absoluteSize; | |||
| value = s.getDoubleValue(); | |||
| } | |||
| } | |||
| void applyPosAndSize (double& xOut, double& wOut, const double x_, const double w_, | |||
| const uint8 xMode_, const uint8 wMode_, | |||
| const int parentPos, const int parentSize) const noexcept | |||
| { | |||
| if (wMode_ == proportionalSize) | |||
| wOut = roundToInt (w_ * parentSize); | |||
| else if (wMode_ == parentSizeMinusAbsolute) | |||
| wOut = jmax (0, parentSize - roundToInt (w_)); | |||
| else | |||
| wOut = roundToInt (w_); | |||
| if ((xMode_ & proportionOfParentSize) != 0) | |||
| xOut = parentPos + x_ * parentSize; | |||
| else if ((xMode_ & absoluteFromParentBottomRight) != 0) | |||
| xOut = (parentPos + parentSize) - x_; | |||
| else if ((xMode_ & absoluteFromParentCentre) != 0) | |||
| xOut = x_ + (parentPos + parentSize / 2); | |||
| else | |||
| xOut = x_ + parentPos; | |||
| if ((xMode_ & anchorAtRightOrBottom) != 0) | |||
| xOut -= wOut; | |||
| else if ((xMode_ & anchorAtCentre) != 0) | |||
| xOut -= wOut / 2; | |||
| } | |||
| void updatePosAndSize (double& xOut, double& wOut, double x_, const double w_, | |||
| const uint8 xMode_, const uint8 wMode_, | |||
| const int parentPos, const int parentSize) const noexcept | |||
| { | |||
| if (wMode_ == proportionalSize) | |||
| { | |||
| if (parentSize > 0) | |||
| wOut = w_ / parentSize; | |||
| } | |||
| else if (wMode_ == parentSizeMinusAbsolute) | |||
| wOut = parentSize - w_; | |||
| else | |||
| wOut = w_; | |||
| if ((xMode_ & anchorAtRightOrBottom) != 0) | |||
| x_ += w_; | |||
| else if ((xMode_ & anchorAtCentre) != 0) | |||
| x_ += w_ / 2; | |||
| if ((xMode_ & proportionOfParentSize) != 0) | |||
| { | |||
| if (parentSize > 0) | |||
| xOut = (x_ - parentPos) / parentSize; | |||
| } | |||
| else if ((xMode_ & absoluteFromParentBottomRight) != 0) | |||
| xOut = (parentPos + parentSize) - x_; | |||
| else if ((xMode_ & absoluteFromParentCentre) != 0) | |||
| xOut = x_ - (parentPos + parentSize / 2); | |||
| else | |||
| xOut = x_ - parentPos; | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| struct RelativePositionedRectangle | |||
| { | |||
| //============================================================================== | |||
| RelativePositionedRectangle() | |||
| : relativeToX (0), | |||
| relativeToY (0), | |||
| relativeToW (0), | |||
| relativeToH (0) | |||
| { | |||
| } | |||
| RelativePositionedRectangle (const RelativePositionedRectangle& other) | |||
| : rect (other.rect), | |||
| relativeToX (other.relativeToX), | |||
| relativeToY (other.relativeToY), | |||
| relativeToW (other.relativeToW), | |||
| relativeToH (other.relativeToH) | |||
| { | |||
| } | |||
| RelativePositionedRectangle& operator= (const RelativePositionedRectangle& other) | |||
| { | |||
| rect = other.rect; | |||
| relativeToX = other.relativeToX; | |||
| relativeToY = other.relativeToY; | |||
| relativeToW = other.relativeToW; | |||
| relativeToH = other.relativeToH; | |||
| return *this; | |||
| } | |||
| //============================================================================== | |||
| bool operator== (const RelativePositionedRectangle& other) const noexcept | |||
| { | |||
| return rect == other.rect | |||
| && relativeToX == other.relativeToX | |||
| && relativeToY == other.relativeToY | |||
| && relativeToW == other.relativeToW | |||
| && relativeToH == other.relativeToH; | |||
| } | |||
| bool operator!= (const RelativePositionedRectangle& other) const noexcept | |||
| { | |||
| return ! operator== (other); | |||
| } | |||
| template <typename LayoutType> | |||
| void getRelativeTargetBounds (const Rectangle<int>& parentArea, | |||
| const LayoutType* layout, | |||
| int& x, int& xw, int& y, int& yh, | |||
| int& w, int& h) const | |||
| { | |||
| Component* rx = 0; | |||
| Component* ry = 0; | |||
| Component* rw = 0; | |||
| Component* rh = 0; | |||
| if (layout != 0) | |||
| { | |||
| rx = layout->findComponentWithId (relativeToX); | |||
| ry = layout->findComponentWithId (relativeToY); | |||
| rw = layout->findComponentWithId (relativeToW); | |||
| rh = layout->findComponentWithId (relativeToH); | |||
| } | |||
| x = parentArea.getX() + (rx != 0 ? rx->getX() : 0); | |||
| y = parentArea.getY() + (ry != 0 ? ry->getY() : 0); | |||
| w = rw != 0 ? rw->getWidth() : parentArea.getWidth(); | |||
| h = rh != 0 ? rh->getHeight() : parentArea.getHeight(); | |||
| xw = rx != 0 ? rx->getWidth() : parentArea.getWidth(); | |||
| yh = ry != 0 ? ry->getHeight() : parentArea.getHeight(); | |||
| } | |||
| Rectangle<int> getRectangle (const Rectangle<int>& parentArea, | |||
| const ComponentLayout* layout) const | |||
| { | |||
| int x, xw, y, yh, w, h; | |||
| getRelativeTargetBounds (parentArea, layout, x, xw, y, yh, w, h); | |||
| const Rectangle<int> xyRect ((xw <= 0 || yh <= 0) ? Rectangle<int>() | |||
| : rect.getRectangle (Rectangle<int> (x, y, xw, yh))); | |||
| const Rectangle<int> whRect ((w <= 0 || h <= 0) ? Rectangle<int>() | |||
| : rect.getRectangle (Rectangle<int> (x, y, w, h))); | |||
| return Rectangle<int> (xyRect.getX(), xyRect.getY(), | |||
| whRect.getWidth(), whRect.getHeight()); | |||
| } | |||
| void getRectangleDouble (double& x, double& y, double& w, double& h, | |||
| const Rectangle<int>& parentArea, | |||
| const ComponentLayout* layout) const | |||
| { | |||
| int rx, rxw, ry, ryh, rw, rh; | |||
| getRelativeTargetBounds (parentArea, layout, rx, rxw, ry, ryh, rw, rh); | |||
| double dummy1, dummy2; | |||
| rect.getRectangleDouble (Rectangle<int> (rx, ry, rxw, ryh), x, y, dummy1, dummy2); | |||
| rect.getRectangleDouble (Rectangle<int> (rx, ry, rw, rh), dummy1, dummy2, w, h); | |||
| } | |||
| void updateFromComponent (const Component& comp, const ComponentLayout* layout) | |||
| { | |||
| int x, xw, y, yh, w, h; | |||
| getRelativeTargetBounds (Rectangle<int> (0, 0, comp.getParentWidth(), comp.getParentHeight()), | |||
| layout, x, xw, y, yh, w, h); | |||
| PositionedRectangle xyRect (rect), whRect (rect); | |||
| xyRect.updateFrom (comp.getBounds(), Rectangle<int> (x, y, xw, yh)); | |||
| whRect.updateFrom (comp.getBounds(), Rectangle<int> (x, y, w, h)); | |||
| rect.setX (xyRect.getX()); | |||
| rect.setY (xyRect.getY()); | |||
| rect.setWidth (whRect.getWidth()); | |||
| rect.setHeight (whRect.getHeight()); | |||
| } | |||
| void updateFrom (double newX, double newY, double newW, double newH, | |||
| const Rectangle<int>& parentArea, const ComponentLayout* layout) | |||
| { | |||
| int x, xw, y, yh, w, h; | |||
| getRelativeTargetBounds (parentArea, layout, x, xw, y, yh, w, h); | |||
| PositionedRectangle xyRect (rect), whRect (rect); | |||
| xyRect.updateFromDouble (newX, newY, newW, newH, Rectangle<int> (x, y, xw, yh)); | |||
| whRect.updateFromDouble (newX, newY, newW, newH, Rectangle<int> (x, y, w, h)); | |||
| rect.setX (xyRect.getX()); | |||
| rect.setY (xyRect.getY()); | |||
| rect.setWidth (whRect.getWidth()); | |||
| rect.setHeight (whRect.getHeight()); | |||
| } | |||
| void applyToXml (XmlElement& e) const | |||
| { | |||
| e.setAttribute ("pos", rect.toString()); | |||
| if (relativeToX != 0) e.setAttribute ("posRelativeX", String::toHexString (relativeToX)); | |||
| if (relativeToY != 0) e.setAttribute ("posRelativeY", String::toHexString (relativeToY)); | |||
| if (relativeToW != 0) e.setAttribute ("posRelativeW", String::toHexString (relativeToW)); | |||
| if (relativeToH != 0) e.setAttribute ("posRelativeH", String::toHexString (relativeToH)); | |||
| } | |||
| void restoreFromXml (const XmlElement& e, const RelativePositionedRectangle& defaultPos) | |||
| { | |||
| rect = PositionedRectangle (e.getStringAttribute ("pos", defaultPos.rect.toString())); | |||
| relativeToX = e.getStringAttribute ("posRelativeX", String::toHexString (defaultPos.relativeToX)).getHexValue64(); | |||
| relativeToY = e.getStringAttribute ("posRelativeY", String::toHexString (defaultPos.relativeToY)).getHexValue64(); | |||
| relativeToW = e.getStringAttribute ("posRelativeW", String::toHexString (defaultPos.relativeToW)).getHexValue64(); | |||
| relativeToH = e.getStringAttribute ("posRelativeH", String::toHexString (defaultPos.relativeToH)).getHexValue64(); | |||
| } | |||
| String toString() const | |||
| { | |||
| StringArray toks; | |||
| toks.addTokens (rect.toString(), false); | |||
| return toks[0] + " " + toks[1]; | |||
| } | |||
| Point<float> toXY (const Rectangle<int>& parentArea, | |||
| const ComponentLayout* layout) const | |||
| { | |||
| double x, y, w, h; | |||
| getRectangleDouble (x, y, w, h, parentArea, layout); | |||
| return Point<float> ((float) x, (float) y); | |||
| } | |||
| void getXY (double& x, double& y, | |||
| const Rectangle<int>& parentArea, | |||
| const ComponentLayout* layout) const | |||
| { | |||
| double w, h; | |||
| getRectangleDouble (x, y, w, h, parentArea, layout); | |||
| } | |||
| //============================================================================== | |||
| PositionedRectangle rect; | |||
| int64 relativeToX; | |||
| int64 relativeToY; | |||
| int64 relativeToW; | |||
| int64 relativeToH; | |||
| }; | |||
| #endif // __JUCER_RELATIVEPOSITIONEDRECTANGLE_H_D07A846__ | |||
| @@ -0,0 +1,275 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 "../../jucer_Headers.h" | |||
| #include "jucer_ResourceEditorPanel.h" | |||
| //============================================================================== | |||
| class ResourceListButton : public Component, | |||
| private ButtonListener | |||
| { | |||
| public: | |||
| ResourceListButton (JucerDocument& doc) | |||
| : document (doc), reloadButton ("Reload"), row (0) | |||
| { | |||
| setInterceptsMouseClicks (false, true); | |||
| addAndMakeVisible (&reloadButton); | |||
| reloadButton.addListener (this); | |||
| } | |||
| void update (int newRow) | |||
| { | |||
| row = newRow; | |||
| reloadButton.setVisible (document.getResources() [row] != nullptr); | |||
| } | |||
| void resized() | |||
| { | |||
| reloadButton.setBoundsInset (BorderSize<int> (2)); | |||
| } | |||
| void buttonClicked (Button*) | |||
| { | |||
| if (const BinaryResources::BinaryResource* const r = document.getResources() [row]) | |||
| document.getResources() | |||
| .browseForResource ("Select a file to replace this resource", | |||
| "*", | |||
| File (r->originalFilename), | |||
| r->name); | |||
| } | |||
| private: | |||
| JucerDocument& document; | |||
| TextButton reloadButton; | |||
| int row; | |||
| }; | |||
| //============================================================================== | |||
| ResourceEditorPanel::ResourceEditorPanel (JucerDocument& doc) | |||
| : document (doc), | |||
| addButton ("Add new resource..."), | |||
| reloadAllButton ("Reload all resources"), | |||
| delButton ("Delete selected resources") | |||
| { | |||
| addAndMakeVisible (&addButton); | |||
| addButton.addListener (this); | |||
| addAndMakeVisible (&reloadAllButton); | |||
| reloadAllButton.addListener (this); | |||
| addAndMakeVisible (&delButton); | |||
| delButton.addListener (this); | |||
| delButton.setEnabled (false); | |||
| addAndMakeVisible (listBox = new TableListBox (String::empty, this)); | |||
| listBox->getHeader().addColumn ("name", 1, 150, 80, 400); | |||
| listBox->getHeader().addColumn ("original file", 2, 350, 80, 800); | |||
| listBox->getHeader().addColumn ("size", 3, 100, 40, 150); | |||
| listBox->getHeader().addColumn ("reload", 4, 100, 100, 100, TableHeaderComponent::notResizableOrSortable); | |||
| listBox->getHeader().setStretchToFitActive (true); | |||
| listBox->setColour (ListBox::backgroundColourId, Colours::lightgrey); | |||
| listBox->setColour (ListBox::outlineColourId, Colours::darkgrey); | |||
| listBox->setOutlineThickness (1); | |||
| listBox->updateContent(); | |||
| document.addChangeListener (this); | |||
| handleCommandMessage (1); | |||
| } | |||
| ResourceEditorPanel::~ResourceEditorPanel() | |||
| { | |||
| document.removeChangeListener (this); | |||
| } | |||
| int ResourceEditorPanel::getNumRows() | |||
| { | |||
| return document.getResources().size(); | |||
| } | |||
| void ResourceEditorPanel::paintRowBackground (Graphics& g, int /*rowNumber*/, | |||
| int /*width*/, int /*height*/, bool rowIsSelected) | |||
| { | |||
| if (rowIsSelected) | |||
| g.fillAll (findColour (TextEditor::highlightColourId)); | |||
| } | |||
| void ResourceEditorPanel::paintCell (Graphics& g, int rowNumber, int columnId, int width, int height, | |||
| bool /*rowIsSelected*/) | |||
| { | |||
| if (const BinaryResources::BinaryResource* const r = document.getResources() [rowNumber]) | |||
| { | |||
| String text; | |||
| if (columnId == 1) | |||
| text = r->name; | |||
| else if (columnId == 2) | |||
| text = r->originalFilename; | |||
| else if (columnId == 3) | |||
| text = File::descriptionOfSizeInBytes (r->data.getSize()); | |||
| g.setFont (13.0f); | |||
| g.drawText (text, 4, 0, width - 6, height, Justification::centredLeft, true); | |||
| } | |||
| } | |||
| Component* ResourceEditorPanel::refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/, | |||
| Component* existingComponentToUpdate) | |||
| { | |||
| if (columnId != 4) | |||
| return nullptr; | |||
| if (existingComponentToUpdate == nullptr) | |||
| existingComponentToUpdate = new ResourceListButton (document); | |||
| ((ResourceListButton*) existingComponentToUpdate)->update (rowNumber); | |||
| return existingComponentToUpdate; | |||
| } | |||
| int ResourceEditorPanel::getColumnAutoSizeWidth (int columnId) | |||
| { | |||
| if (columnId == 4) | |||
| return 0; | |||
| Font f (13.0f); | |||
| int widest = 40; | |||
| for (int i = document.getResources().size(); --i >= 0;) | |||
| { | |||
| const BinaryResources::BinaryResource* const r = document.getResources() [i]; | |||
| String text; | |||
| if (columnId == 1) | |||
| text = r->name; | |||
| else if (columnId == 2) | |||
| text = r->originalFilename; | |||
| else if (columnId == 3) | |||
| text = File::descriptionOfSizeInBytes (r->data.getSize()); | |||
| widest = jmax (widest, f.getStringWidth (text)); | |||
| } | |||
| return widest + 10; | |||
| } | |||
| //============================================================================== | |||
| class ResourceSorter | |||
| { | |||
| public: | |||
| ResourceSorter (const int columnId_, const bool forwards) | |||
| : columnId (columnId_), | |||
| direction (forwards ? 1 : -1) | |||
| { | |||
| } | |||
| int compareElements (BinaryResources::BinaryResource* first, BinaryResources::BinaryResource* second) | |||
| { | |||
| if (columnId == 1) return direction * first->name.compare (second->name); | |||
| if (columnId == 2) return direction * first->originalFilename.compare (second->originalFilename); | |||
| if (columnId == 3) return direction * (int) first->data.getSize() - (int) second->data.getSize(); | |||
| return 0; | |||
| } | |||
| private: | |||
| const int columnId, direction; | |||
| ResourceSorter (const ResourceSorter&); | |||
| ResourceSorter& operator= (const ResourceSorter&); | |||
| }; | |||
| void ResourceEditorPanel::sortOrderChanged (int newSortColumnId, const bool isForwards) | |||
| { | |||
| ResourceSorter sorter (newSortColumnId, isForwards); | |||
| document.getResources().sort (sorter); | |||
| } | |||
| //============================================================================== | |||
| void ResourceEditorPanel::selectedRowsChanged (int /*lastRowSelected*/) | |||
| { | |||
| delButton.setEnabled (listBox->getNumSelectedRows() > 0); | |||
| } | |||
| void ResourceEditorPanel::resized() | |||
| { | |||
| listBox->setBounds (6, 4, getWidth() - 12, getHeight() - 38); | |||
| addButton.changeWidthToFitText (22); | |||
| addButton.setTopLeftPosition (8, getHeight() - 30); | |||
| reloadAllButton.changeWidthToFitText (22); | |||
| reloadAllButton.setTopLeftPosition (addButton.getRight() + 10, getHeight() - 30); | |||
| delButton.changeWidthToFitText (22); | |||
| delButton.setTopRightPosition (getWidth() - 8, getHeight() - 30); | |||
| } | |||
| void ResourceEditorPanel::visibilityChanged() | |||
| { | |||
| if (isVisible()) | |||
| listBox->updateContent(); | |||
| } | |||
| void ResourceEditorPanel::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| if (isVisible()) | |||
| listBox->updateContent(); | |||
| } | |||
| void ResourceEditorPanel::buttonClicked (Button* b) | |||
| { | |||
| if (b == &addButton) | |||
| { | |||
| document.getResources() | |||
| .browseForResource ("Select a file to add as a resource", | |||
| "*", | |||
| File::nonexistent, | |||
| String::empty); | |||
| } | |||
| else if (b == &delButton) | |||
| { | |||
| document.getResources().remove (listBox->getSelectedRow (0)); | |||
| } | |||
| else if (b == &reloadAllButton) | |||
| { | |||
| StringArray failed; | |||
| for (int i = 0; i < document.getResources().size(); ++i) | |||
| { | |||
| if (! document.getResources().reload (i)) | |||
| failed.add (document.getResources().getResourceNames() [i]); | |||
| } | |||
| if (failed.size() > 0) | |||
| { | |||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||
| TRANS("Reloading resources"), | |||
| TRANS("The following resources couldn't be reloaded from their original files:\n\n") | |||
| + failed.joinIntoString (", ")); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,61 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_RESOURCEEDITORPANEL_JUCEHEADER__ | |||
| #define __JUCER_RESOURCEEDITORPANEL_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| //============================================================================== | |||
| class ResourceEditorPanel : public Component, | |||
| private TableListBoxModel, | |||
| private ChangeListener, | |||
| private ButtonListener | |||
| { | |||
| public: | |||
| ResourceEditorPanel (JucerDocument& document); | |||
| ~ResourceEditorPanel(); | |||
| void resized(); | |||
| void visibilityChanged(); | |||
| void changeListenerCallback (ChangeBroadcaster*); | |||
| void buttonClicked (Button*); | |||
| int getNumRows(); | |||
| void paintRowBackground (Graphics& g, int rowNumber, int width, int height, bool rowIsSelected); | |||
| void paintCell (Graphics& g, int rowNumber, int columnId, int width, int height, bool rowIsSelected); | |||
| Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected, Component* existingComponentToUpdate); | |||
| int getColumnAutoSizeWidth (int columnId); | |||
| void sortOrderChanged (int newSortColumnId, bool isForwards); | |||
| void selectedRowsChanged (int lastRowSelected); | |||
| private: | |||
| JucerDocument& document; | |||
| ScopedPointer<TableListBox> listBox; | |||
| TextButton addButton, reloadAllButton, delButton; | |||
| }; | |||
| #endif // __JUCER_RESOURCEEDITORPANEL_JUCEHEADER__ | |||
| @@ -0,0 +1,96 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-11 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 __JUCER_SNAPGRIDPAINTER_JUCEHEADER__ | |||
| #define __JUCER_SNAPGRIDPAINTER_JUCEHEADER__ | |||
| #include "../jucer_JucerDocument.h" | |||
| #include "../jucer_PaintRoutine.h" | |||
| //============================================================================== | |||
| class SnapGridPainter | |||
| { | |||
| public: | |||
| SnapGridPainter() | |||
| : snapGridSize (-1), snapShown (false) | |||
| { | |||
| } | |||
| bool updateFromDesign (JucerDocument& design) | |||
| { | |||
| if (snapGridSize != design.getSnappingGridSize() | |||
| || snapShown != (design.isSnapShown() && design.isSnapActive (false))) | |||
| { | |||
| snapGridSize = design.getSnappingGridSize(); | |||
| snapShown = design.isSnapShown() && design.isSnapActive (false); | |||
| backgroundFill = Image(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| void updateColour() | |||
| { | |||
| backgroundFill = Image(); | |||
| } | |||
| void draw (Graphics& g, PaintRoutine* backgroundGraphics) | |||
| { | |||
| if (backgroundFill.isNull() && snapShown) | |||
| { | |||
| backgroundFill = Image (Image::ARGB, snapGridSize, snapGridSize, true); | |||
| Graphics g2 (backgroundFill); | |||
| Colour col (Colours::black); | |||
| if (backgroundGraphics != nullptr) | |||
| col = backgroundGraphics->getBackgroundColour().contrasting(); | |||
| if (snapGridSize > 2) | |||
| { | |||
| g2.setColour (col.withAlpha (0.1f)); | |||
| g2.drawRect (0, 0, snapGridSize + 1, snapGridSize + 1); | |||
| } | |||
| } | |||
| if (backgroundFill.isValid()) | |||
| { | |||
| g.setTiledImageFill (backgroundFill, 0, 0, 1.0f); | |||
| g.fillAll(); | |||
| } | |||
| } | |||
| private: | |||
| int snapGridSize; | |||
| bool snapShown; | |||
| Image backgroundFill; | |||
| }; | |||
| #endif // __JUCER_SNAPGRIDPAINTER_JUCEHEADER__ | |||