@@ -68,7 +68,6 @@ OBJECTS := \ | |||||
$(OBJDIR)/jucer_ProjectTreeViewBase.o \ | $(OBJDIR)/jucer_ProjectTreeViewBase.o \ | ||||
$(OBJDIR)/jucer_TreeViewTypes.o \ | $(OBJDIR)/jucer_TreeViewTypes.o \ | ||||
$(OBJDIR)/jucer_CodeHelpers.o \ | $(OBJDIR)/jucer_CodeHelpers.o \ | ||||
$(OBJDIR)/jucer_Coordinate.o \ | |||||
$(OBJDIR)/jucer_FileHelpers.o \ | $(OBJDIR)/jucer_FileHelpers.o \ | ||||
$(OBJDIR)/jucer_StoredSettings.o \ | $(OBJDIR)/jucer_StoredSettings.o \ | ||||
$(OBJDIR)/jucer_MiscUtilities.o \ | $(OBJDIR)/jucer_MiscUtilities.o \ | ||||
@@ -96,177 +95,172 @@ clean: | |||||
$(OBJDIR)/jucer_CodeGenerator.o: ../../Source/model/Component/jucer_CodeGenerator.cpp | $(OBJDIR)/jucer_CodeGenerator.o: ../../Source/model/Component/jucer_CodeGenerator.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_CodeGenerator.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ComponentDocument.o: ../../Source/model/Component/jucer_ComponentDocument.cpp | $(OBJDIR)/jucer_ComponentDocument.o: ../../Source/model/Component/jucer_ComponentDocument.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ComponentDocument.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ComponentTypeManager.o: ../../Source/model/Component/Types/jucer_ComponentTypeManager.cpp | $(OBJDIR)/jucer_ComponentTypeManager.o: ../../Source/model/Component/Types/jucer_ComponentTypeManager.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ComponentTypeManager.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_DrawableDocument.o: ../../Source/model/Drawable/jucer_DrawableDocument.cpp | $(OBJDIR)/jucer_DrawableDocument.o: ../../Source/model/Drawable/jucer_DrawableDocument.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_DrawableDocument.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_NewFileWizard.o: ../../Source/model/Project/jucer_NewFileWizard.cpp | $(OBJDIR)/jucer_NewFileWizard.o: ../../Source/model/Project/jucer_NewFileWizard.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_NewFileWizard.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_Project.o: ../../Source/model/Project/jucer_Project.cpp | $(OBJDIR)/jucer_Project.o: ../../Source/model/Project/jucer_Project.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_Project.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ProjectExporter.o: ../../Source/model/Project/jucer_ProjectExporter.cpp | $(OBJDIR)/jucer_ProjectExporter.o: ../../Source/model/Project/jucer_ProjectExporter.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ProjectExporter.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ProjectWizard.o: ../../Source/model/Project/jucer_ProjectWizard.cpp | $(OBJDIR)/jucer_ProjectWizard.o: ../../Source/model/Project/jucer_ProjectWizard.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ProjectWizard.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ResourceFile.o: ../../Source/model/Project/jucer_ResourceFile.cpp | $(OBJDIR)/jucer_ResourceFile.o: ../../Source/model/Project/jucer_ResourceFile.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ResourceFile.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_SourceCodeEditor.o: ../../Source/ui/Code\ Editor/jucer_SourceCodeEditor.cpp | $(OBJDIR)/jucer_SourceCodeEditor.o: ../../Source/ui/Code\ Editor/jucer_SourceCodeEditor.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_SourceCodeEditor.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ComponentEditor.o: ../../Source/ui/Component\ Editor/jucer_ComponentEditor.cpp | $(OBJDIR)/jucer_ComponentEditor.o: ../../Source/ui/Component\ Editor/jucer_ComponentEditor.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ComponentEditor.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ComponentViewer.o: ../../Source/ui/Component\ Editor/jucer_ComponentViewer.cpp | $(OBJDIR)/jucer_ComponentViewer.o: ../../Source/ui/Component\ Editor/jucer_ComponentViewer.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ComponentViewer.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_DrawableEditor.o: ../../Source/ui/Drawable\ Editor/jucer_DrawableEditor.cpp | $(OBJDIR)/jucer_DrawableEditor.o: ../../Source/ui/Drawable\ Editor/jucer_DrawableEditor.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_DrawableEditor.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_EditorCanvas.o: ../../Source/ui/Editor\ Base/jucer_EditorCanvas.cpp | $(OBJDIR)/jucer_EditorCanvas.o: ../../Source/ui/Editor\ Base/jucer_EditorCanvas.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_EditorCanvas.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_DocumentEditorComponent.o: ../../Source/ui/jucer_DocumentEditorComponent.cpp | $(OBJDIR)/jucer_DocumentEditorComponent.o: ../../Source/ui/jucer_DocumentEditorComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_DocumentEditorComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_JucerTreeViewBase.o: ../../Source/ui/jucer_JucerTreeViewBase.cpp | $(OBJDIR)/jucer_JucerTreeViewBase.o: ../../Source/ui/jucer_JucerTreeViewBase.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_JucerTreeViewBase.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_MainWindow.o: ../../Source/ui/jucer_MainWindow.cpp | $(OBJDIR)/jucer_MainWindow.o: ../../Source/ui/jucer_MainWindow.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_MainWindow.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_OpenDocumentManager.o: ../../Source/ui/jucer_OpenDocumentManager.cpp | $(OBJDIR)/jucer_OpenDocumentManager.o: ../../Source/ui/jucer_OpenDocumentManager.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_OpenDocumentManager.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_GroupInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_GroupInformationComponent.cpp | $(OBJDIR)/jucer_GroupInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_GroupInformationComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_GroupInformationComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ItemPreviewComponent.o: ../../Source/ui/Project\ Editor/jucer_ItemPreviewComponent.cpp | $(OBJDIR)/jucer_ItemPreviewComponent.o: ../../Source/ui/Project\ Editor/jucer_ItemPreviewComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ItemPreviewComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ProjectContentComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectContentComponent.cpp | $(OBJDIR)/jucer_ProjectContentComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectContentComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ProjectContentComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ProjectInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectInformationComponent.cpp | $(OBJDIR)/jucer_ProjectInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectInformationComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ProjectInformationComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_ProjectTreeViewBase.o: ../../Source/ui/Project\ Editor/jucer_ProjectTreeViewBase.cpp | $(OBJDIR)/jucer_ProjectTreeViewBase.o: ../../Source/ui/Project\ Editor/jucer_ProjectTreeViewBase.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_ProjectTreeViewBase.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_TreeViewTypes.o: ../../Source/ui/Project\ Editor/jucer_TreeViewTypes.cpp | $(OBJDIR)/jucer_TreeViewTypes.o: ../../Source/ui/Project\ Editor/jucer_TreeViewTypes.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_TreeViewTypes.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_CodeHelpers.o: ../../Source/utility/jucer_CodeHelpers.cpp | $(OBJDIR)/jucer_CodeHelpers.o: ../../Source/utility/jucer_CodeHelpers.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||||
$(OBJDIR)/jucer_Coordinate.o: ../../Source/utility/jucer_Coordinate.cpp | |||||
-@mkdir -p $(OBJDIR) | |||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_CodeHelpers.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_FileHelpers.o: ../../Source/utility/jucer_FileHelpers.cpp | $(OBJDIR)/jucer_FileHelpers.o: ../../Source/utility/jucer_FileHelpers.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_FileHelpers.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_StoredSettings.o: ../../Source/utility/jucer_StoredSettings.cpp | $(OBJDIR)/jucer_StoredSettings.o: ../../Source/utility/jucer_StoredSettings.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_StoredSettings.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_MiscUtilities.o: ../../Source/utility/jucer_MiscUtilities.cpp | $(OBJDIR)/jucer_MiscUtilities.o: ../../Source/utility/jucer_MiscUtilities.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_MiscUtilities.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/jucer_Main.o: ../../Source/jucer_Main.cpp | $(OBJDIR)/jucer_Main.o: ../../Source/jucer_Main.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling jucer_Main.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp | $(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling BinaryData.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode1.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode2.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode3.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode4.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
-include $(OBJECTS:%.o=%.d) | -include $(OBJECTS:%.o=%.d) |
@@ -42,7 +42,6 @@ | |||||
984444E3B2947675DC7D65DA = { isa = PBXBuildFile; fileRef = 1FDE55685608689765ADC578; }; | 984444E3B2947675DC7D65DA = { isa = PBXBuildFile; fileRef = 1FDE55685608689765ADC578; }; | ||||
58BF60E87F9A8EDCACC5D1AE = { isa = PBXBuildFile; fileRef = 939E2A7946081DB4D21B89B6; }; | 58BF60E87F9A8EDCACC5D1AE = { isa = PBXBuildFile; fileRef = 939E2A7946081DB4D21B89B6; }; | ||||
28B94C4BB7B572E6F5419E5D = { isa = PBXBuildFile; fileRef = 78E0309CB6D5E7E80B5BED7D; }; | 28B94C4BB7B572E6F5419E5D = { isa = PBXBuildFile; fileRef = 78E0309CB6D5E7E80B5BED7D; }; | ||||
5BF87265418D736250283182 = { isa = PBXBuildFile; fileRef = C7ADB43F83A83FFC08921A12; }; | |||||
12C1D006503C664FF07F476F = { isa = PBXBuildFile; fileRef = 5533704F0D30A9C62058FEC7; }; | 12C1D006503C664FF07F476F = { isa = PBXBuildFile; fileRef = 5533704F0D30A9C62058FEC7; }; | ||||
DDAB225ABE572196882C3524 = { isa = PBXBuildFile; fileRef = 7A1CD936BD306A6E0BEFB046; }; | DDAB225ABE572196882C3524 = { isa = PBXBuildFile; fileRef = 7A1CD936BD306A6E0BEFB046; }; | ||||
92612DD3884793248F1EC45A = { isa = PBXBuildFile; fileRef = 49A1C43070A68985C25F34C7; }; | 92612DD3884793248F1EC45A = { isa = PBXBuildFile; fileRef = 49A1C43070A68985C25F34C7; }; | ||||
@@ -85,6 +84,7 @@ | |||||
E894E1F6D582678EE1F02763 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Viewport.h; path = ../../Source/model/Component/Types/jucer_Viewport.h; sourceTree = SOURCE_ROOT; }; | E894E1F6D582678EE1F02763 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Viewport.h; path = ../../Source/model/Component/Types/jucer_Viewport.h; sourceTree = SOURCE_ROOT; }; | ||||
B1471E8698D193FBCF0DD13D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DrawableDocument.cpp; path = ../../Source/model/Drawable/jucer_DrawableDocument.cpp; sourceTree = SOURCE_ROOT; }; | B1471E8698D193FBCF0DD13D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DrawableDocument.cpp; path = ../../Source/model/Drawable/jucer_DrawableDocument.cpp; sourceTree = SOURCE_ROOT; }; | ||||
739F94CA6213B43D867AB0FD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableDocument.h; path = ../../Source/model/Drawable/jucer_DrawableDocument.h; sourceTree = SOURCE_ROOT; }; | 739F94CA6213B43D867AB0FD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableDocument.h; path = ../../Source/model/Drawable/jucer_DrawableDocument.h; sourceTree = SOURCE_ROOT; }; | ||||
BDE8CD9273E1B0D0E500D283 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableTypeHandler.h; path = ../../Source/model/Drawable/jucer_DrawableTypeHandler.h; sourceTree = SOURCE_ROOT; }; | |||||
9DCB32BBD7053ACCB598CE79 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_NewFileWizard.cpp; path = ../../Source/model/Project/jucer_NewFileWizard.cpp; sourceTree = SOURCE_ROOT; }; | 9DCB32BBD7053ACCB598CE79 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_NewFileWizard.cpp; path = ../../Source/model/Project/jucer_NewFileWizard.cpp; sourceTree = SOURCE_ROOT; }; | ||||
201DF0B7B4AA3E03B1AA5144 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_NewFileWizard.h; path = ../../Source/model/Project/jucer_NewFileWizard.h; sourceTree = SOURCE_ROOT; }; | 201DF0B7B4AA3E03B1AA5144 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_NewFileWizard.h; path = ../../Source/model/Project/jucer_NewFileWizard.h; sourceTree = SOURCE_ROOT; }; | ||||
4179D4C7BF616A4A3C3E11CA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Project.cpp; path = ../../Source/model/Project/jucer_Project.cpp; sourceTree = SOURCE_ROOT; }; | 4179D4C7BF616A4A3C3E11CA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Project.cpp; path = ../../Source/model/Project/jucer_Project.cpp; sourceTree = SOURCE_ROOT; }; | ||||
@@ -143,8 +143,6 @@ | |||||
9C58E022906C193862372BC1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CodeHelpers.h; path = ../../Source/utility/jucer_CodeHelpers.h; sourceTree = SOURCE_ROOT; }; | 9C58E022906C193862372BC1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CodeHelpers.h; path = ../../Source/utility/jucer_CodeHelpers.h; sourceTree = SOURCE_ROOT; }; | ||||
AAF3C58696944A256CA61730 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ColourEditorComponent.h; path = ../../Source/utility/jucer_ColourEditorComponent.h; sourceTree = SOURCE_ROOT; }; | AAF3C58696944A256CA61730 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ColourEditorComponent.h; path = ../../Source/utility/jucer_ColourEditorComponent.h; sourceTree = SOURCE_ROOT; }; | ||||
9736236B5C4D6A16FC7E03AC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Colours.h; path = ../../Source/utility/jucer_Colours.h; sourceTree = SOURCE_ROOT; }; | 9736236B5C4D6A16FC7E03AC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Colours.h; path = ../../Source/utility/jucer_Colours.h; sourceTree = SOURCE_ROOT; }; | ||||
C7ADB43F83A83FFC08921A12 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Coordinate.cpp; path = ../../Source/utility/jucer_Coordinate.cpp; sourceTree = SOURCE_ROOT; }; | |||||
EFA0636FB8ABA3377AB6C6F4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Coordinate.h; path = ../../Source/utility/jucer_Coordinate.h; sourceTree = SOURCE_ROOT; }; | |||||
CC9A3046B8B9FCDFE2092F51 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CoordinatePropertyComponent.h; path = ../../Source/utility/jucer_CoordinatePropertyComponent.h; sourceTree = SOURCE_ROOT; }; | CC9A3046B8B9FCDFE2092F51 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CoordinatePropertyComponent.h; path = ../../Source/utility/jucer_CoordinatePropertyComponent.h; sourceTree = SOURCE_ROOT; }; | ||||
5533704F0D30A9C62058FEC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_FileHelpers.cpp; path = ../../Source/utility/jucer_FileHelpers.cpp; sourceTree = SOURCE_ROOT; }; | 5533704F0D30A9C62058FEC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_FileHelpers.cpp; path = ../../Source/utility/jucer_FileHelpers.cpp; sourceTree = SOURCE_ROOT; }; | ||||
27E71DE11448E4D6721D5508 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_FileHelpers.h; path = ../../Source/utility/jucer_FileHelpers.h; sourceTree = SOURCE_ROOT; }; | 27E71DE11448E4D6721D5508 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_FileHelpers.h; path = ../../Source/utility/jucer_FileHelpers.h; sourceTree = SOURCE_ROOT; }; | ||||
@@ -204,7 +202,8 @@ | |||||
7C95A5CDB1B24D227D92749E ); name = Component; sourceTree = "<group>"; }; | 7C95A5CDB1B24D227D92749E ); name = Component; sourceTree = "<group>"; }; | ||||
E70E3BE796E91EA86CFE10FE = { isa = PBXGroup; children = ( | E70E3BE796E91EA86CFE10FE = { isa = PBXGroup; children = ( | ||||
B1471E8698D193FBCF0DD13D, | B1471E8698D193FBCF0DD13D, | ||||
739F94CA6213B43D867AB0FD ); name = Drawable; sourceTree = "<group>"; }; | |||||
739F94CA6213B43D867AB0FD, | |||||
BDE8CD9273E1B0D0E500D283 ); name = Drawable; sourceTree = "<group>"; }; | |||||
ADA17383E5554BCDF567AACC = { isa = PBXGroup; children = ( | ADA17383E5554BCDF567AACC = { isa = PBXGroup; children = ( | ||||
9DCB32BBD7053ACCB598CE79, | 9DCB32BBD7053ACCB598CE79, | ||||
201DF0B7B4AA3E03B1AA5144, | 201DF0B7B4AA3E03B1AA5144, | ||||
@@ -280,8 +279,6 @@ | |||||
9C58E022906C193862372BC1, | 9C58E022906C193862372BC1, | ||||
AAF3C58696944A256CA61730, | AAF3C58696944A256CA61730, | ||||
9736236B5C4D6A16FC7E03AC, | 9736236B5C4D6A16FC7E03AC, | ||||
C7ADB43F83A83FFC08921A12, | |||||
EFA0636FB8ABA3377AB6C6F4, | |||||
CC9A3046B8B9FCDFE2092F51, | CC9A3046B8B9FCDFE2092F51, | ||||
5533704F0D30A9C62058FEC7, | 5533704F0D30A9C62058FEC7, | ||||
27E71DE11448E4D6721D5508, | 27E71DE11448E4D6721D5508, | ||||
@@ -438,7 +435,6 @@ | |||||
984444E3B2947675DC7D65DA, | 984444E3B2947675DC7D65DA, | ||||
58BF60E87F9A8EDCACC5D1AE, | 58BF60E87F9A8EDCACC5D1AE, | ||||
28B94C4BB7B572E6F5419E5D, | 28B94C4BB7B572E6F5419E5D, | ||||
5BF87265418D736250283182, | |||||
12C1D006503C664FF07F476F, | 12C1D006503C664FF07F476F, | ||||
DDAB225ABE572196882C3524, | DDAB225ABE572196882C3524, | ||||
92612DD3884793248F1EC45A, | 92612DD3884793248F1EC45A, | ||||
@@ -154,6 +154,7 @@ | |||||
<Filter Name="Drawable"> | <Filter Name="Drawable"> | ||||
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.cpp"/> | <File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.cpp"/> | ||||
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.h"/> | <File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.h"/> | ||||
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableTypeHandler.h"/> | |||||
</Filter> | </Filter> | ||||
<Filter Name="Project"> | <Filter Name="Project"> | ||||
<File RelativePath="..\..\Source\model\Project\jucer_NewFileWizard.cpp"/> | <File RelativePath="..\..\Source\model\Project\jucer_NewFileWizard.cpp"/> | ||||
@@ -229,8 +230,6 @@ | |||||
<File RelativePath="..\..\Source\utility\jucer_CodeHelpers.h"/> | <File RelativePath="..\..\Source\utility\jucer_CodeHelpers.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_ColourEditorComponent.h"/> | <File RelativePath="..\..\Source\utility\jucer_ColourEditorComponent.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_Colours.h"/> | <File RelativePath="..\..\Source\utility\jucer_Colours.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_Coordinate.cpp"/> | |||||
<File RelativePath="..\..\Source\utility\jucer_Coordinate.h"/> | |||||
<File RelativePath="..\..\Source\utility\jucer_CoordinatePropertyComponent.h"/> | <File RelativePath="..\..\Source\utility\jucer_CoordinatePropertyComponent.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_FileHelpers.cpp"/> | <File RelativePath="..\..\Source\utility\jucer_FileHelpers.cpp"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_FileHelpers.h"/> | <File RelativePath="..\..\Source\utility\jucer_FileHelpers.h"/> | ||||
@@ -154,6 +154,7 @@ | |||||
<Filter Name="Drawable"> | <Filter Name="Drawable"> | ||||
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.cpp"/> | <File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.cpp"/> | ||||
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.h"/> | <File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.h"/> | ||||
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableTypeHandler.h"/> | |||||
</Filter> | </Filter> | ||||
<Filter Name="Project"> | <Filter Name="Project"> | ||||
<File RelativePath="..\..\Source\model\Project\jucer_NewFileWizard.cpp"/> | <File RelativePath="..\..\Source\model\Project\jucer_NewFileWizard.cpp"/> | ||||
@@ -229,8 +230,6 @@ | |||||
<File RelativePath="..\..\Source\utility\jucer_CodeHelpers.h"/> | <File RelativePath="..\..\Source\utility\jucer_CodeHelpers.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_ColourEditorComponent.h"/> | <File RelativePath="..\..\Source\utility\jucer_ColourEditorComponent.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_Colours.h"/> | <File RelativePath="..\..\Source\utility\jucer_Colours.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_Coordinate.cpp"/> | |||||
<File RelativePath="..\..\Source\utility\jucer_Coordinate.h"/> | |||||
<File RelativePath="..\..\Source\utility\jucer_CoordinatePropertyComponent.h"/> | <File RelativePath="..\..\Source\utility\jucer_CoordinatePropertyComponent.h"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_FileHelpers.cpp"/> | <File RelativePath="..\..\Source\utility\jucer_FileHelpers.cpp"/> | ||||
<File RelativePath="..\..\Source\utility\jucer_FileHelpers.h"/> | <File RelativePath="..\..\Source\utility\jucer_FileHelpers.h"/> | ||||
@@ -72,6 +72,8 @@ | |||||
file="Source/model/Drawable/jucer_DrawableDocument.cpp"/> | file="Source/model/Drawable/jucer_DrawableDocument.cpp"/> | ||||
<FILE id="qMcrWuCal" name="jucer_DrawableDocument.h" compile="0" resource="0" | <FILE id="qMcrWuCal" name="jucer_DrawableDocument.h" compile="0" resource="0" | ||||
file="Source/model/Drawable/jucer_DrawableDocument.h"/> | file="Source/model/Drawable/jucer_DrawableDocument.h"/> | ||||
<FILE id="tGjXOXiR9" name="jucer_DrawableTypeHandler.h" compile="0" | |||||
resource="0" file="Source/model/Drawable/jucer_DrawableTypeHandler.h"/> | |||||
</GROUP> | </GROUP> | ||||
<GROUP id="na25KSPIj" name="Project"> | <GROUP id="na25KSPIj" name="Project"> | ||||
<FILE id="jqL1mb9xp" name="jucer_NewFileWizard.cpp" compile="1" resource="0" | <FILE id="jqL1mb9xp" name="jucer_NewFileWizard.cpp" compile="1" resource="0" | ||||
@@ -205,10 +207,6 @@ | |||||
resource="0" file="Source/utility/jucer_ColourEditorComponent.h"/> | resource="0" file="Source/utility/jucer_ColourEditorComponent.h"/> | ||||
<FILE id="bjibbvm3S" name="jucer_Colours.h" compile="0" resource="0" | <FILE id="bjibbvm3S" name="jucer_Colours.h" compile="0" resource="0" | ||||
file="Source/utility/jucer_Colours.h"/> | file="Source/utility/jucer_Colours.h"/> | ||||
<FILE id="bDebnoSX" name="jucer_Coordinate.cpp" compile="1" resource="0" | |||||
file="Source/utility/jucer_Coordinate.cpp"/> | |||||
<FILE id="uqXX3Ga6S" name="jucer_Coordinate.h" compile="0" resource="0" | |||||
file="Source/utility/jucer_Coordinate.h"/> | |||||
<FILE id="DDCunFHcy" name="jucer_CoordinatePropertyComponent.h" compile="0" | <FILE id="DDCunFHcy" name="jucer_CoordinatePropertyComponent.h" compile="0" | ||||
resource="0" file="Source/utility/jucer_CoordinatePropertyComponent.h"/> | resource="0" file="Source/utility/jucer_CoordinatePropertyComponent.h"/> | ||||
<FILE id="WlEYep7NN" name="jucer_FileHelpers.cpp" compile="1" resource="0" | <FILE id="WlEYep7NN" name="jucer_FileHelpers.cpp" compile="1" resource="0" | ||||
@@ -40,7 +40,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
ComponentBoundsEditor (ComponentDocument& document_, const String& name, Type type_, | ComponentBoundsEditor (ComponentDocument& document_, const String& name, Type type_, | ||||
const ValueTree& compState_, const Value& coordValue_) | const ValueTree& compState_, const Value& coordValue_) | ||||
: CoordinatePropertyComponent (document_, name, | |||||
: CoordinatePropertyComponent (&document_, name, | |||||
Value (new CoordExtractor (coordValue_, type_)), | Value (new CoordExtractor (coordValue_, type_)), | ||||
type_ == left || type_ == right), | type_ == left || type_ == right), | ||||
document (document_), | document (document_), | ||||
@@ -184,7 +184,7 @@ Component* ComponentTypeManager::createFromStoredType (ComponentDocument& docume | |||||
ComponentTypeHandler* ComponentTypeManager::getHandlerFor (const Identifier& type) | ComponentTypeHandler* ComponentTypeManager::getHandlerFor (const Identifier& type) | ||||
{ | { | ||||
for (int i = handlers.size(); --i >= 0;) | for (int i = handlers.size(); --i >= 0;) | ||||
if (handlers.getUnchecked(i)->getXmlTag() == type) | |||||
if (handlers.getUnchecked(i)->getValueTreeType() == type) | |||||
return handlers.getUnchecked(i); | return handlers.getUnchecked(i); | ||||
return 0; | return 0; | ||||
@@ -205,8 +205,8 @@ juce_ImplementSingleton_SingleThreaded (ComponentTypeManager); | |||||
//============================================================================== | //============================================================================== | ||||
ComponentTypeHandler::ComponentTypeHandler (const String& displayName_, const String& className_, | ComponentTypeHandler::ComponentTypeHandler (const String& displayName_, const String& className_, | ||||
const String& xmlTag_, const String& memberNameRoot_) | |||||
: displayName (displayName_), className (className_), xmlTag (xmlTag_), | |||||
const Identifier& valueTreeType_, const String& memberNameRoot_) | |||||
: displayName (displayName_), className (className_), valueTreeType (valueTreeType_), | |||||
memberNameRoot (memberNameRoot_) | memberNameRoot (memberNameRoot_) | ||||
{ | { | ||||
} | } | ||||
@@ -315,7 +315,7 @@ void ComponentTypeInstance::initialiseNewItemBasics() | |||||
void ComponentTypeInstance::updateComponentBasics (Component* comp) | void ComponentTypeInstance::updateComponentBasics (Component* comp) | ||||
{ | { | ||||
RelativeRectangle pos (state [ComponentDocument::compBoundsProperty].toString()); | RelativeRectangle pos (state [ComponentDocument::compBoundsProperty].toString()); | ||||
comp->setBounds (pos.resolve (document).getSmallestIntegerContainer()); | |||||
comp->setBounds (pos.resolve (&document).getSmallestIntegerContainer()); | |||||
//comp->setName (state [ComponentDocument::compNameProperty]); | //comp->setName (state [ComponentDocument::compNameProperty]); | ||||
@@ -86,11 +86,12 @@ class ComponentTypeHandler | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
ComponentTypeHandler (const String& displayName_, const String& className_, const String& xmlTag_, const String& memberNameRoot_); | |||||
ComponentTypeHandler (const String& displayName_, const String& className_, | |||||
const Identifier& valueTreeType_, const String& memberNameRoot_); | |||||
virtual ~ComponentTypeHandler(); | virtual ~ComponentTypeHandler(); | ||||
const String& getDisplayName() const { return displayName; } | const String& getDisplayName() const { return displayName; } | ||||
const Identifier& getXmlTag() const { return xmlTag; } | |||||
const Identifier& getValueTreeType() const { return valueTreeType; } | |||||
const String& getMemberNameRoot() const { return memberNameRoot; } | const String& getMemberNameRoot() const { return memberNameRoot; } | ||||
virtual Component* createComponent() = 0; | virtual Component* createComponent() = 0; | ||||
@@ -106,7 +107,7 @@ public: | |||||
protected: | protected: | ||||
//============================================================================== | //============================================================================== | ||||
const String displayName, className, memberNameRoot; | const String displayName, className, memberNameRoot; | ||||
const Identifier xmlTag; | |||||
const Identifier valueTreeType; | |||||
private: | private: | ||||
ComponentTypeHandler (const ComponentTypeHandler&); | ComponentTypeHandler (const ComponentTypeHandler&); | ||||
@@ -359,7 +359,7 @@ const ValueTree ComponentDocument::performNewComponentMenuItem (int menuResultCo | |||||
if (handler != 0) | if (handler != 0) | ||||
{ | { | ||||
ValueTree state (handler->getXmlTag()); | |||||
ValueTree state (handler->getValueTreeType()); | |||||
state.setProperty (idProperty, createAlphaNumericUID(), 0); | state.setProperty (idProperty, createAlphaNumericUID(), 0); | ||||
ComponentTypeInstance comp (*this, state); | ComponentTypeInstance comp (*this, state); | ||||
@@ -532,7 +532,7 @@ void ComponentDocument::renameAnchor (const String& oldName, const String& newNa | |||||
{ | { | ||||
ValueTree v (getComponent(i)); | ValueTree v (getComponent(i)); | ||||
RelativeRectangle coords (getCoordsFor (v)); | RelativeRectangle coords (getCoordsFor (v)); | ||||
coords.renameAnchorIfUsed (oldName, newName, *this); | |||||
coords.renameAnchorIfUsed (oldName, newName, this); | |||||
setCoordsFor (v, coords); | setCoordsFor (v, coords); | ||||
} | } | ||||
@@ -551,7 +551,7 @@ void ComponentDocument::addMarkerMenuItem (int i, const RelativeCoordinate& coor | |||||
name << '.' << edge; | name << '.' << edge; | ||||
menu.addItem (i, name, | menu.addItem (i, name, | ||||
! (name == fullCoordName || requestedCoord.references (fullCoordName, *this)), | |||||
! (name == fullCoordName || requestedCoord.references (fullCoordName, this)), | |||||
name == (isAnchor1 ? coord.getAnchorName1() : coord.getAnchorName2())); | name == (isAnchor1 ? coord.getAnchorName1() : coord.getAnchorName2())); | ||||
} | } | ||||
@@ -780,7 +780,7 @@ bool ComponentDocument::MarkerList::createProperties (Array <PropertyComponent*> | |||||
props.add (new TextPropertyComponent (Value (new MarkerListBase::MarkerNameValueSource (this, getNameAsValue (marker))), | props.add (new TextPropertyComponent (Value (new MarkerListBase::MarkerNameValueSource (this, getNameAsValue (marker))), | ||||
"Marker Name", 256, false)); | "Marker Name", 256, false)); | ||||
props.add (new MarkerListBase::PositionPropertyComponent (document, *this, "Position", marker, | |||||
props.add (new MarkerListBase::PositionPropertyComponent (&document, *this, "Position", marker, | |||||
marker.getPropertyAsValue (getMarkerPosProperty(), document.getUndoManager()))); | marker.getPropertyAsValue (getMarkerPosProperty(), document.getUndoManager()))); | ||||
return true; | return true; | ||||
} | } | ||||
@@ -28,7 +28,6 @@ | |||||
#include "../../jucer_Headers.h" | #include "../../jucer_Headers.h" | ||||
#include "../Project/jucer_Project.h" | #include "../Project/jucer_Project.h" | ||||
#include "../../utility/jucer_Coordinate.h" | |||||
#include "../../utility/jucer_MarkerListBase.h" | #include "../../utility/jucer_MarkerListBase.h" | ||||
#include "jucer_CodeGenerator.h" | #include "jucer_CodeGenerator.h" | ||||
@@ -24,6 +24,54 @@ | |||||
*/ | */ | ||||
#include "jucer_DrawableDocument.h" | #include "jucer_DrawableDocument.h" | ||||
#include "jucer_DrawableTypeHandler.h" | |||||
//============================================================================== | |||||
class DrawableTypeManager : public DeletedAtShutdown | |||||
{ | |||||
public: | |||||
DrawableTypeManager() | |||||
{ | |||||
handlers.add (new DrawablePathHandler()); | |||||
handlers.add (new DrawableImageHandler()); | |||||
} | |||||
~DrawableTypeManager() | |||||
{ | |||||
} | |||||
juce_DeclareSingleton_SingleThreaded_Minimal (DrawableTypeManager); | |||||
//============================================================================== | |||||
int getNumHandlers() const { return handlers.size(); } | |||||
DrawableTypeHandler* getHandler (const int index) const { return handlers[index]; } | |||||
DrawableTypeHandler* getHandlerFor (const Identifier& type) | |||||
{ | |||||
for (int i = handlers.size(); --i >= 0;) | |||||
if (handlers.getUnchecked(i)->getValueTreeType() == type) | |||||
return handlers.getUnchecked(i); | |||||
jassertfalse; | |||||
return 0; | |||||
} | |||||
const StringArray getDisplayNames() | |||||
{ | |||||
StringArray s; | |||||
for (int i = 0; i < handlers.size(); ++i) | |||||
s.add (handlers.getUnchecked(i)->getDisplayName()); | |||||
return s; | |||||
} | |||||
private: | |||||
OwnedArray <DrawableTypeHandler> handlers; | |||||
}; | |||||
juce_ImplementSingleton_SingleThreaded (DrawableTypeManager); | |||||
//============================================================================== | //============================================================================== | ||||
@@ -55,9 +103,9 @@ DrawableDocument::~DrawableDocument() | |||||
root.removeListener (this); | root.removeListener (this); | ||||
} | } | ||||
ValueTree DrawableDocument::getRootDrawableNode() const | |||||
DrawableComposite::ValueTreeWrapper DrawableDocument::getRootDrawableNode() const | |||||
{ | { | ||||
return root.getChild (0); | |||||
return DrawableComposite::ValueTreeWrapper (root.getChild (0)); | |||||
} | } | ||||
void DrawableDocument::checkRootObject() | void DrawableDocument::checkRootObject() | ||||
@@ -75,11 +123,6 @@ void DrawableDocument::checkRootObject() | |||||
getCanvasHeight() = 500; | getCanvasHeight() = 500; | ||||
} | } | ||||
const String DrawableDocument::getIdFor (const ValueTree& object) | |||||
{ | |||||
return object [Ids::id_]; | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
void DrawableDocument::setName (const String& name) | void DrawableDocument::setName (const String& name) | ||||
{ | { | ||||
@@ -194,59 +237,49 @@ void DrawableDocument::changed() | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
static const Colour getRandomColour() | |||||
{ | |||||
return Colours::red.withHue (Random::getSystemRandom().nextFloat()); | |||||
} | |||||
const int menuItemOffset = 0x63451fa4; | |||||
void DrawableDocument::addDrawable (Drawable& d) | |||||
void DrawableDocument::addNewItemMenuItems (PopupMenu& menu) const | |||||
{ | { | ||||
DrawableComposite dc; | |||||
dc.insertDrawable (d.createCopy()); | |||||
ValueTree dcNode (dc.createValueTree (0)); | |||||
ValueTree subNode (dcNode.getChild(0)); | |||||
dcNode.removeChild (subNode, 0); | |||||
addMissingIds (subNode); | |||||
const StringArray displayNames (DrawableTypeManager::getInstance()->getDisplayNames()); | |||||
getRootDrawableNode().addChild (subNode, -1, getUndoManager()); | |||||
for (int i = 0; i < displayNames.size(); ++i) | |||||
menu.addItem (i + menuItemOffset, "New " + displayNames[i]); | |||||
} | } | ||||
void DrawableDocument::addRectangle() | |||||
const ValueTree DrawableDocument::performNewItemMenuItem (int menuResultCode) | |||||
{ | { | ||||
Path p; | |||||
p.addRectangle ((float) Random::getSystemRandom().nextInt (500), | |||||
(float) Random::getSystemRandom().nextInt (500), | |||||
100.0f, 100.0f); | |||||
const StringArray displayNames (DrawableTypeManager::getInstance()->getDisplayNames()); | |||||
DrawablePath d; | |||||
d.setPath (p); | |||||
d.setFill (FillType (getRandomColour())); | |||||
if (menuResultCode >= menuItemOffset && menuResultCode < menuItemOffset + displayNames.size()) | |||||
{ | |||||
DrawableTypeHandler* handler = DrawableTypeManager::getInstance()->getHandler (menuResultCode - menuItemOffset); | |||||
jassert (handler != 0); | |||||
addDrawable (d); | |||||
} | |||||
if (handler != 0) | |||||
{ | |||||
ValueTree state (handler->createNewInstance (*this, | |||||
Point<float> (Random::getSystemRandom().nextFloat() * 100.0f + 100.0f, | |||||
Random::getSystemRandom().nextFloat() * 100.0f + 100.0f))); | |||||
void DrawableDocument::addCircle() | |||||
{ | |||||
Path p; | |||||
p.addEllipse ((float) Random::getSystemRandom().nextInt (500), | |||||
(float) Random::getSystemRandom().nextInt (500), | |||||
100.0f, 100.0f); | |||||
getRootDrawableNode().addDrawable (state, -1, getUndoManager()); | |||||
DrawablePath d; | |||||
d.setPath (p); | |||||
d.setFill (FillType (getRandomColour())); | |||||
return state; | |||||
} | |||||
} | |||||
addDrawable (d); | |||||
return ValueTree::invalid; | |||||
} | } | ||||
void DrawableDocument::addImage (const File& imageFile) | |||||
//============================================================================== | |||||
Image* DrawableDocument::getImageForIdentifier (const var& imageIdentifier) | |||||
{ | { | ||||
jassertfalse | |||||
DrawableImage d; | |||||
return ImageCache::getFromMemory (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize); | |||||
} | |||||
addDrawable (d); | |||||
const var DrawableDocument::getIdentifierForImage (Image* image) | |||||
{ | |||||
return var::null; //xxx todo | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -28,13 +28,13 @@ | |||||
#include "../../jucer_Headers.h" | #include "../../jucer_Headers.h" | ||||
#include "../Project/jucer_Project.h" | #include "../Project/jucer_Project.h" | ||||
#include "../../utility/jucer_Coordinate.h" | |||||
#include "../../utility/jucer_MarkerListBase.h" | #include "../../utility/jucer_MarkerListBase.h" | ||||
//============================================================================== | //============================================================================== | ||||
class DrawableDocument : public ValueTree::Listener, | class DrawableDocument : public ValueTree::Listener, | ||||
public ChangeBroadcaster | |||||
public ChangeBroadcaster, | |||||
public Drawable::ImageProvider | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
@@ -51,16 +51,13 @@ public: | |||||
void changed(); | void changed(); | ||||
ValueTree& getRoot() { return root; } | ValueTree& getRoot() { return root; } | ||||
ValueTree getRootDrawableNode() const; | |||||
void addRectangle(); | |||||
void addCircle(); | |||||
void addImage (const File& imageFile); | |||||
DrawableComposite::ValueTreeWrapper getRootDrawableNode() const; | |||||
Value getCanvasWidth() const { return getRootValueNonUndoable (Ids::width); } | Value getCanvasWidth() const { return getRootValueNonUndoable (Ids::width); } | ||||
Value getCanvasHeight() const { return getRootValueNonUndoable (Ids::height); } | Value getCanvasHeight() const { return getRootValueNonUndoable (Ids::height); } | ||||
static const String getIdFor (const ValueTree& object); | |||||
void addNewItemMenuItems (PopupMenu& menu) const; | |||||
const ValueTree performNewItemMenuItem (int menuResultCode); | |||||
//============================================================================== | //============================================================================== | ||||
class MarkerList : public MarkerListBase | class MarkerList : public MarkerListBase | ||||
@@ -91,6 +88,9 @@ public: | |||||
const String getNonexistentMarkerName (const String& name); | const String getNonexistentMarkerName (const String& name); | ||||
void renameAnchor (const String& oldName, const String& newName); | void renameAnchor (const String& oldName, const String& newName); | ||||
Image* getImageForIdentifier (const var& imageIdentifier); | |||||
const var getIdentifierForImage (Image* image); | |||||
//============================================================================== | //============================================================================== | ||||
void valueTreePropertyChanged (ValueTree& tree, const Identifier& name); | void valueTreePropertyChanged (ValueTree& tree, const Identifier& name); | ||||
void valueTreeChildrenChanged (ValueTree& tree); | void valueTreeChildrenChanged (ValueTree& tree); | ||||
@@ -0,0 +1,103 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
Copyright 2004-10 by Raw Material Software Ltd. | |||||
------------------------------------------------------------------------------ | |||||
JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
Public License (Version 2), as published by the Free Software Foundation. | |||||
A copy of the license is included in the JUCE distribution, or can be found | |||||
online at www.gnu.org/licenses. | |||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
------------------------------------------------------------------------------ | |||||
To release a closed-source product which uses JUCE, commercial licenses are | |||||
available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef __JUCER_DRAWABLETYPEHANDLER_H_7FB02E2F__ | |||||
#define __JUCER_DRAWABLETYPEHANDLER_H_7FB02E2F__ | |||||
#include "jucer_DrawableDocument.h" | |||||
//============================================================================== | |||||
class DrawableTypeHandler | |||||
{ | |||||
public: | |||||
DrawableTypeHandler (const String& displayName_, const Identifier& valueTreeType_) | |||||
: displayName (displayName_), valueTreeType (valueTreeType_) | |||||
{ | |||||
} | |||||
virtual ~DrawableTypeHandler() {} | |||||
virtual const ValueTree createNewInstance (DrawableDocument& document, const Point<float>& approxPosition) = 0; | |||||
const String& getDisplayName() const { return displayName; } | |||||
const Identifier& getValueTreeType() const { return valueTreeType; } | |||||
private: | |||||
const String displayName; | |||||
const Identifier valueTreeType; | |||||
}; | |||||
//============================================================================== | |||||
class DrawablePathHandler : public DrawableTypeHandler | |||||
{ | |||||
public: | |||||
DrawablePathHandler() : DrawableTypeHandler ("Polygon", DrawablePath::valueTreeType) {} | |||||
~DrawablePathHandler() {} | |||||
const ValueTree createNewInstance (DrawableDocument& document, const Point<float>& approxPosition) | |||||
{ | |||||
Path p; | |||||
p.addTriangle (approxPosition.getX(), approxPosition.getY() - 50.0f, | |||||
approxPosition.getX() + 50.0f, approxPosition.getY() + 20.0f, | |||||
approxPosition.getX() - 50.0f, approxPosition.getY() + 20.0f); | |||||
DrawablePath dp; | |||||
dp.setPath (p); | |||||
dp.setFill (Colours::lightblue.withHue (Random::getSystemRandom().nextFloat())); | |||||
return dp.createValueTree (0); | |||||
} | |||||
}; | |||||
//============================================================================== | |||||
class DrawableImageHandler : public DrawableTypeHandler | |||||
{ | |||||
public: | |||||
DrawableImageHandler() : DrawableTypeHandler ("Image", DrawableImage::valueTreeType) {} | |||||
~DrawableImageHandler() {} | |||||
const ValueTree createNewInstance (DrawableDocument& document, const Point<float>& approxPosition) | |||||
{ | |||||
Image tempImage (Image::ARGB, 100, 100, true); | |||||
{ | |||||
Graphics g (tempImage); | |||||
g.fillAll (Colours::grey.withAlpha (0.3f)); | |||||
g.setColour (Colours::red); | |||||
g.setFont (40.0f); | |||||
g.drawText ("?", 0, 0, 100, 100, Justification::centred, false); | |||||
} | |||||
DrawableImage di; | |||||
di.setTransform (RelativePoint (approxPosition), | |||||
RelativePoint (approxPosition + Point<float> (100.0f, 0.0f)), | |||||
RelativePoint (approxPosition + Point<float> (0.0f, 100.0f))); | |||||
return di.createValueTree (&document); | |||||
} | |||||
}; | |||||
#endif // __JUCER_DRAWABLETYPEHANDLER_H_7FB02E2F__ |
@@ -298,7 +298,7 @@ private: | |||||
out << "$(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i))) | out << "$(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i))) | ||||
<< ": " << escapeSpaces (files.getReference(i).toUnixStyle()) << newLine | << ": " << escapeSpaces (files.getReference(i).toUnixStyle()) << newLine | ||||
<< "\t-@mkdir -p $(OBJDIR)" << newLine | << "\t-@mkdir -p $(OBJDIR)" << newLine | ||||
<< "\t@echo $(notdir $<)" << newLine | |||||
<< "\t@echo \"Compiling " << files.getReference(i).getFileName() << "\"" << newLine | |||||
<< (files.getReference(i).hasFileExtension (".c") ? "\t@$(CC) $(CFLAGS) -o \"$@\" -c \"$<\"" | << (files.getReference(i).hasFileExtension (".c") ? "\t@$(CC) $(CFLAGS) -o \"$@\" -c \"$<\"" | ||||
: "\t@$(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"") | : "\t@$(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"") | ||||
<< newLine << newLine; | << newLine << newLine; | ||||
@@ -120,7 +120,7 @@ public: | |||||
const Rectangle<int> getObjectPosition (const ValueTree& state) | const Rectangle<int> getObjectPosition (const ValueTree& state) | ||||
{ | { | ||||
return getDocument().getCoordsFor (state).resolve (getDocument()).getSmallestIntegerContainer(); | |||||
return getDocument().getCoordsFor (state).resolve (&getDocument()).getSmallestIntegerContainer(); | |||||
} | } | ||||
RelativeRectangle getObjectCoords (const ValueTree& state) | RelativeRectangle getObjectCoords (const ValueTree& state) | ||||
@@ -176,14 +176,14 @@ public: | |||||
const Rectangle<float> getObjectPosition (const ValueTree& state) | const Rectangle<float> getObjectPosition (const ValueTree& state) | ||||
{ | { | ||||
ComponentDocument& doc = getDocument(); | ComponentDocument& doc = getDocument(); | ||||
return doc.getCoordsFor (state).resolve (doc); | |||||
return doc.getCoordsFor (state).resolve (&doc); | |||||
} | } | ||||
bool setObjectPosition (ValueTree& state, const Rectangle<float>& newBounds) | bool setObjectPosition (ValueTree& state, const Rectangle<float>& newBounds) | ||||
{ | { | ||||
ComponentDocument& doc = getDocument(); | ComponentDocument& doc = getDocument(); | ||||
RelativeRectangle pr (doc.getCoordsFor (state)); | RelativeRectangle pr (doc.getCoordsFor (state)); | ||||
pr.moveToAbsolute (newBounds, doc); | |||||
pr.moveToAbsolute (newBounds, &doc); | |||||
return doc.setCoordsFor (state, pr); | return doc.setCoordsFor (state, pr); | ||||
} | } | ||||
@@ -191,7 +191,7 @@ public: | |||||
float getMarkerPosition (const ValueTree& marker, bool isX) | float getMarkerPosition (const ValueTree& marker, bool isX) | ||||
{ | { | ||||
ComponentDocument& doc = getDocument(); | ComponentDocument& doc = getDocument(); | ||||
return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (doc); | |||||
return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (&doc); | |||||
} | } | ||||
}; | }; | ||||
@@ -80,7 +80,7 @@ void ComponentViewer::handleAsyncUpdate() | |||||
background = Colour::fromString (componentDocument->getBackgroundColour().toString()); | background = Colour::fromString (componentDocument->getBackgroundColour().toString()); | ||||
if (layoutManager == 0) | if (layoutManager == 0) | ||||
layoutManager = new ComponentAutoLayoutManager (this); | |||||
layoutManager = new RelativeRectangleLayoutManager (this); | |||||
int i; | int i; | ||||
for (i = getNumChildComponents(); --i >= 0;) | for (i = getNumChildComponents(); --i >= 0;) | ||||
@@ -62,7 +62,7 @@ private: | |||||
ComponentDocument* componentDocument; | ComponentDocument* componentDocument; | ||||
ValueTree documentRoot; | ValueTree documentRoot; | ||||
ScopedPointer<ComponentAutoLayoutManager> layoutManager; | |||||
ScopedPointer<RelativeRectangleLayoutManager> layoutManager; | |||||
Colour background; | Colour background; | ||||
ComponentViewer (const ComponentViewer&); | ComponentViewer (const ComponentViewer&); | ||||
@@ -53,7 +53,7 @@ public: | |||||
void createCanvas() | void createCanvas() | ||||
{ | { | ||||
initialise (new DrawableEditorCanvas (editor), toolbarFactory, | initialise (new DrawableEditorCanvas (editor), toolbarFactory, | ||||
new DrawableTreeViewItem (editor, editor.getDocument().getRootDrawableNode())); | |||||
new DrawableTreeViewItem (editor, editor.getDocument().getRootDrawableNode().getState())); | |||||
} | } | ||||
SelectedItemSet<String>& getSelection() | SelectedItemSet<String>& getSelection() | ||||
@@ -117,17 +117,10 @@ void DrawableEditor::selectionToBack() | |||||
void DrawableEditor::showNewShapeMenu (Component* componentToAttachTo) | void DrawableEditor::showNewShapeMenu (Component* componentToAttachTo) | ||||
{ | { | ||||
/* | |||||
PopupMenu m; | PopupMenu m; | ||||
getDocument().addNewComponentMenuItems (m); | |||||
getDocument().addNewItemMenuItems (m); | |||||
const int r = m.showAt (componentToAttachTo); | const int r = m.showAt (componentToAttachTo); | ||||
const ValueTree newComp (getDocument().performNewComponentMenuItem (r)); | |||||
if (newComp.isValid()) | |||||
getSelection().selectOnly (newComp [ComponentDocument::idProperty]); | |||||
*/ | |||||
getDocument().performNewItemMenuItem (r); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -54,8 +54,19 @@ public: | |||||
void updateComponents() | void updateComponents() | ||||
{ | { | ||||
drawable = Drawable::createFromValueTree (getEditor().getDocument().getRootDrawableNode(), 0); | |||||
getComponentHolder()->repaint(); | |||||
DrawableDocument& doc = getEditor().getDocument(); | |||||
if (drawable == 0) | |||||
{ | |||||
drawable = Drawable::createFromValueTree (doc.getRootDrawableNode().getState(), &doc); | |||||
getComponentHolder()->repaint(); | |||||
} | |||||
else | |||||
{ | |||||
const Rectangle<float> damage (drawable->refreshFromValueTree (doc.getRootDrawableNode().getState(), &doc)); | |||||
getComponentHolder()->repaint (damage.getSmallestIntegerContainer()); | |||||
} | |||||
startTimer (500); | startTimer (500); | ||||
} | } | ||||
@@ -89,9 +100,9 @@ public: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
// getDocument().addNewComponentMenuItems (m); | |||||
// const int r = m.show(); | |||||
// getDocument().performNewComponentMenuItem (r); | |||||
getDocument().addNewItemMenuItems (m); | |||||
const int r = m.show(); | |||||
getDocument().performNewItemMenuItem (r); | |||||
} | } | ||||
} | } | ||||
@@ -38,14 +38,14 @@ public: | |||||
DrawableTreeViewItem (DrawableEditor& editor_, const ValueTree& drawableRoot) | DrawableTreeViewItem (DrawableEditor& editor_, const ValueTree& drawableRoot) | ||||
: editor (editor_), node (drawableRoot), typeName (drawableRoot.getType().toString()) | : editor (editor_), node (drawableRoot), typeName (drawableRoot.getType().toString()) | ||||
{ | { | ||||
node.addListener (this); | |||||
node.getState().addListener (this); | |||||
editor.getSelection().addChangeListener (this); | editor.getSelection().addChangeListener (this); | ||||
} | } | ||||
~DrawableTreeViewItem() | ~DrawableTreeViewItem() | ||||
{ | { | ||||
editor.getSelection().removeChangeListener (this); | editor.getSelection().removeChangeListener (this); | ||||
node.removeListener (this); | |||||
node.getState().removeListener (this); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -55,7 +55,7 @@ public: | |||||
void valueTreeChildrenChanged (ValueTree& tree) | void valueTreeChildrenChanged (ValueTree& tree) | ||||
{ | { | ||||
if (tree == node) | |||||
if (tree == node.getState()) | |||||
refreshSubItems(); | refreshSubItems(); | ||||
} | } | ||||
@@ -67,14 +67,13 @@ public: | |||||
// TreeViewItem stuff.. | // TreeViewItem stuff.. | ||||
bool mightContainSubItems() | bool mightContainSubItems() | ||||
{ | { | ||||
return node.getType() == DrawableComposite::valueTreeType | |||||
&& node.getNumChildren() > 0; | |||||
return node.getState().getType() == DrawableComposite::valueTreeType; | |||||
} | } | ||||
const String getUniqueName() const | const String getUniqueName() const | ||||
{ | { | ||||
jassert (node [Ids::id_].toString().isNotEmpty()); | |||||
return node [Ids::id_]; | |||||
jassert (node.getID().isNotEmpty()); | |||||
return node.getID(); | |||||
} | } | ||||
void itemOpennessChanged (bool isNowOpen) | void itemOpennessChanged (bool isNowOpen) | ||||
@@ -85,15 +84,17 @@ public: | |||||
void refreshSubItems() | void refreshSubItems() | ||||
{ | { | ||||
if (node.getType() == DrawableComposite::valueTreeType) | |||||
if (node.getState().getType() == DrawableComposite::valueTreeType) | |||||
{ | { | ||||
ScopedPointer <XmlElement> oldOpenness (getOpennessState()); | ScopedPointer <XmlElement> oldOpenness (getOpennessState()); | ||||
clearSubItems(); | clearSubItems(); | ||||
for (int i = 0; i < node.getNumChildren(); ++i) | |||||
DrawableComposite::ValueTreeWrapper composite (node.getState()); | |||||
for (int i = 0; i < composite.getNumDrawables(); ++i) | |||||
{ | { | ||||
ValueTree subNode (node.getChild (i)); | |||||
ValueTree subNode (composite.getDrawableState (i)); | |||||
DrawableTreeViewItem* const item = new DrawableTreeViewItem (editor, subNode); | DrawableTreeViewItem* const item = new DrawableTreeViewItem (editor, subNode); | ||||
addSubItem (item); | addSubItem (item); | ||||
} | } | ||||
@@ -114,7 +115,7 @@ public: | |||||
const String getRenamingName() const | const String getRenamingName() const | ||||
{ | { | ||||
return node ["name"]; | |||||
return node.getID(); | |||||
} | } | ||||
void setName (const String& newName) | void setName (const String& newName) | ||||
@@ -138,7 +139,7 @@ public: | |||||
void itemSelectionChanged (bool isNowSelected) | void itemSelectionChanged (bool isNowSelected) | ||||
{ | { | ||||
const String objectId (DrawableDocument::getIdFor (node)); | |||||
const String objectId (node.getID()); | |||||
if (isNowSelected) | if (isNowSelected) | ||||
editor.getSelection().addToSelection (objectId); | editor.getSelection().addToSelection (objectId); | ||||
@@ -148,7 +149,7 @@ public: | |||||
void changeListenerCallback (void*) | void changeListenerCallback (void*) | ||||
{ | { | ||||
setSelected (editor.getSelection().isSelected (DrawableDocument::getIdFor (node)), false); | |||||
setSelected (editor.getSelection().isSelected (node.getID()), false); | |||||
} | } | ||||
const String getTooltip() | const String getTooltip() | ||||
@@ -194,7 +195,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
DrawableEditor& editor; | DrawableEditor& editor; | ||||
ValueTree node; | |||||
Drawable::ValueTreeWrapperBase node; | |||||
private: | private: | ||||
String typeName; | String typeName; | ||||
@@ -243,7 +243,7 @@ public: | |||||
void updatePosition() | void updatePosition() | ||||
{ | { | ||||
RelativeCoordinate coord (getMarkerList().getCoordinate (marker)); | RelativeCoordinate coord (getMarkerList().getCoordinate (marker)); | ||||
const int pos = roundToInt (coord.resolve (getMarkerList())); | |||||
const int pos = roundToInt (coord.resolve (&getMarkerList())); | |||||
const int width = 8; | const int width = 8; | ||||
if (isX) | if (isX) | ||||
@@ -309,7 +309,7 @@ public: | |||||
canvas->getUndoManager().beginNewTransaction(); | canvas->getUndoManager().beginNewTransaction(); | ||||
RelativeCoordinate coord (getMarkerList().getCoordinate (marker)); | RelativeCoordinate coord (getMarkerList().getCoordinate (marker)); | ||||
dragStartPos = coord.resolve (getMarkerList()); | |||||
dragStartPos = coord.resolve (&getMarkerList()); | |||||
} | } | ||||
} | } | ||||
@@ -335,7 +335,7 @@ public: | |||||
// (can't use getDistanceFromDragStart() because it doesn't take into account auto-scrolling) | // (can't use getDistanceFromDragStart() because it doesn't take into account auto-scrolling) | ||||
coord.moveToAbsolute (jmax (0, roundToInt (dragStartPos + (isX ? e2.x - mouseDownPos.getX() | coord.moveToAbsolute (jmax (0, roundToInt (dragStartPos + (isX ? e2.x - mouseDownPos.getX() | ||||
: e2.y - mouseDownPos.getY()))), | : e2.y - mouseDownPos.getY()))), | ||||
getMarkerList()); | |||||
&getMarkerList()); | |||||
getMarkerList().setCoordinate (marker, coord); | getMarkerList().setCoordinate (marker, coord); | ||||
} | } | ||||
else | else | ||||
@@ -26,10 +26,10 @@ | |||||
#ifndef __JUCER_EDITORCANVAS_H_EF886D17__ | #ifndef __JUCER_EDITORCANVAS_H_EF886D17__ | ||||
#define __JUCER_EDITORCANVAS_H_EF886D17__ | #define __JUCER_EDITORCANVAS_H_EF886D17__ | ||||
#include "../../utility/jucer_Coordinate.h" | |||||
#include "../../utility/jucer_MarkerListBase.h" | #include "../../utility/jucer_MarkerListBase.h" | ||||
class EditorPanelBase; | class EditorPanelBase; | ||||
//============================================================================== | //============================================================================== | ||||
class EditorCanvasBase : public Component, | class EditorCanvasBase : public Component, | ||||
public ValueTree::Listener, | public ValueTree::Listener, | ||||
@@ -1,167 +0,0 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
Copyright 2004-10 by Raw Material Software Ltd. | |||||
------------------------------------------------------------------------------ | |||||
JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
Public License (Version 2), as published by the Free Software Foundation. | |||||
A copy of the license is included in the JUCE distribution, or can be found | |||||
online at www.gnu.org/licenses. | |||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
------------------------------------------------------------------------------ | |||||
To release a closed-source product which uses JUCE, commercial licenses are | |||||
available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
============================================================================== | |||||
*/ | |||||
#include "jucer_Coordinate.h" | |||||
//============================================================================== | |||||
ComponentAutoLayoutManager::ComponentAutoLayoutManager (Component* parentComponent) | |||||
: parent (parentComponent) | |||||
{ | |||||
parent->addComponentListener (this); | |||||
} | |||||
ComponentAutoLayoutManager::~ComponentAutoLayoutManager() | |||||
{ | |||||
parent->removeComponentListener (this); | |||||
for (int i = components.size(); --i >= 0;) | |||||
components.getUnchecked(i)->component->removeComponentListener (this); | |||||
} | |||||
void ComponentAutoLayoutManager::setMarker (const String& name, const RelativeCoordinate& coord) | |||||
{ | |||||
for (int i = markers.size(); --i >= 0;) | |||||
{ | |||||
MarkerPosition* m = markers.getUnchecked(i); | |||||
if (m->markerName == name) | |||||
{ | |||||
m->position = coord; | |||||
applyLayout(); | |||||
return; | |||||
} | |||||
} | |||||
markers.add (new MarkerPosition (name, coord)); | |||||
applyLayout(); | |||||
} | |||||
void ComponentAutoLayoutManager::setComponentBounds (Component* comp, const String& name, const RelativeRectangle& coords) | |||||
{ | |||||
jassert (comp != 0); | |||||
// All the components that this layout manages must be inside the parent component.. | |||||
jassert (parent->isParentOf (comp)); | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
if (c->component == comp) | |||||
{ | |||||
c->name = name; | |||||
c->coords = coords; | |||||
triggerAsyncUpdate(); | |||||
return; | |||||
} | |||||
} | |||||
components.add (new ComponentPosition (comp, name, coords)); | |||||
comp->addComponentListener (this); | |||||
triggerAsyncUpdate(); | |||||
} | |||||
void ComponentAutoLayoutManager::applyLayout() | |||||
{ | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
// All the components that this layout manages must be inside the parent component.. | |||||
jassert (parent->isParentOf (c->component)); | |||||
c->component->setBounds (c->coords.resolve (*this).getSmallestIntegerContainer()); | |||||
} | |||||
} | |||||
const RelativeCoordinate ComponentAutoLayoutManager::findNamedCoordinate (const String& objectName, const String& edge) const | |||||
{ | |||||
if (objectName == RelativeCoordinate::Strings::parent) | |||||
{ | |||||
if (edge == RelativeCoordinate::Strings::right) return RelativeCoordinate ((double) parent->getWidth(), true); | |||||
if (edge == RelativeCoordinate::Strings::bottom) return RelativeCoordinate ((double) parent->getHeight(), false); | |||||
} | |||||
if (objectName.isNotEmpty() && edge.isNotEmpty()) | |||||
{ | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
if (c->name == objectName) | |||||
{ | |||||
if (edge == RelativeCoordinate::Strings::left) return c->coords.left; | |||||
if (edge == RelativeCoordinate::Strings::right) return c->coords.right; | |||||
if (edge == RelativeCoordinate::Strings::top) return c->coords.top; | |||||
if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom; | |||||
} | |||||
} | |||||
} | |||||
for (int i = markers.size(); --i >= 0;) | |||||
{ | |||||
MarkerPosition* m = markers.getUnchecked(i); | |||||
if (m->markerName == objectName) | |||||
return m->position; | |||||
} | |||||
return RelativeCoordinate(); | |||||
} | |||||
void ComponentAutoLayoutManager::componentMovedOrResized (Component& component, bool wasMoved, bool wasResized) | |||||
{ | |||||
triggerAsyncUpdate(); | |||||
if (parent == &component) | |||||
handleUpdateNowIfNeeded(); | |||||
} | |||||
void ComponentAutoLayoutManager::componentBeingDeleted (Component& component) | |||||
{ | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
if (c->component == &component) | |||||
{ | |||||
components.remove (i); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
void ComponentAutoLayoutManager::handleAsyncUpdate() | |||||
{ | |||||
applyLayout(); | |||||
} | |||||
ComponentAutoLayoutManager::MarkerPosition::MarkerPosition (const String& name, const RelativeCoordinate& coord) | |||||
: markerName (name), position (coord) | |||||
{ | |||||
} | |||||
ComponentAutoLayoutManager::ComponentPosition::ComponentPosition (Component* component_, const String& name_, const RelativeRectangle& coords_) | |||||
: component (component_), name (name_), coords (coords_) | |||||
{ | |||||
} |
@@ -1,102 +0,0 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
Copyright 2004-10 by Raw Material Software Ltd. | |||||
------------------------------------------------------------------------------ | |||||
JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
Public License (Version 2), as published by the Free Software Foundation. | |||||
A copy of the license is included in the JUCE distribution, or can be found | |||||
online at www.gnu.org/licenses. | |||||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
------------------------------------------------------------------------------ | |||||
To release a closed-source product which uses JUCE, commercial licenses are | |||||
available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef __JUCER_COORDINATE_H_EF56ACFA__ | |||||
#define __JUCER_COORDINATE_H_EF56ACFA__ | |||||
#include "../jucer_Headers.h" | |||||
//============================================================================== | |||||
/** | |||||
*/ | |||||
class ComponentAutoLayoutManager : public ComponentListener, | |||||
public RelativeCoordinate::NamedCoordinateFinder, | |||||
public AsyncUpdater | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** | |||||
*/ | |||||
ComponentAutoLayoutManager (Component* parentComponent); | |||||
/** Destructor. */ | |||||
~ComponentAutoLayoutManager(); | |||||
//============================================================================== | |||||
/** | |||||
*/ | |||||
void setMarker (const String& name, const RelativeCoordinate& coord); | |||||
/** | |||||
*/ | |||||
void setComponentBounds (Component* component, const String& componentName, const RelativeRectangle& bounds); | |||||
/** | |||||
*/ | |||||
void applyLayout(); | |||||
//============================================================================== | |||||
/** @internal */ | |||||
const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const; | |||||
/** @internal */ | |||||
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); | |||||
/** @internal */ | |||||
void componentBeingDeleted (Component& component); | |||||
/** @internal */ | |||||
void handleAsyncUpdate(); | |||||
juce_UseDebuggingNewOperator | |||||
private: | |||||
//============================================================================== | |||||
struct ComponentPosition | |||||
{ | |||||
ComponentPosition (Component* component, const String& name, const RelativeRectangle& coords); | |||||
Component* component; | |||||
String name; | |||||
RelativeRectangle coords; | |||||
}; | |||||
struct MarkerPosition | |||||
{ | |||||
MarkerPosition (const String& name, const RelativeCoordinate& coord); | |||||
String markerName; | |||||
RelativeCoordinate position; | |||||
}; | |||||
Component* parent; | |||||
OwnedArray <ComponentPosition> components; | |||||
OwnedArray <MarkerPosition> markers; | |||||
ComponentAutoLayoutManager (const ComponentAutoLayoutManager&); | |||||
ComponentAutoLayoutManager& operator= (const ComponentAutoLayoutManager&); | |||||
}; | |||||
#endif // __JUCER_COORDINATE_H_EF56ACFA__ |
@@ -34,7 +34,7 @@ class CoordinatePropertyComponent : public PropertyComponent, | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
CoordinatePropertyComponent (RelativeCoordinate::NamedCoordinateFinder& nameSource_, const String& name, | |||||
CoordinatePropertyComponent (RelativeCoordinate::NamedCoordinateFinder* nameSource_, const String& name, | |||||
const Value& coordValue_, bool isHorizontal_) | const Value& coordValue_, bool isHorizontal_) | ||||
: PropertyComponent (name, 40), nameSource (nameSource_), | : PropertyComponent (name, 40), nameSource (nameSource_), | ||||
coordValue (coordValue_), | coordValue (coordValue_), | ||||
@@ -142,7 +142,7 @@ public: | |||||
virtual const String pickMarker (TextButton* button, const String& currentMarker, bool isAnchor1) = 0; | virtual const String pickMarker (TextButton* button, const String& currentMarker, bool isAnchor1) = 0; | ||||
protected: | protected: | ||||
RelativeCoordinate::NamedCoordinateFinder& nameSource; | |||||
RelativeCoordinate::NamedCoordinateFinder* nameSource; | |||||
Value coordValue, textValue; | Value coordValue, textValue; | ||||
Label* label; | Label* label; | ||||
TextButton* proportionButton; | TextButton* proportionButton; | ||||
@@ -56,7 +56,7 @@ public: | |||||
{ | { | ||||
ValueTree v (getMarker (i)); | ValueTree v (getMarker (i)); | ||||
RelativeCoordinate coord (getCoordinate (v)); | RelativeCoordinate coord (getCoordinate (v)); | ||||
coord.renameAnchorIfUsed (oldName, newName, *this); | |||||
coord.renameAnchorIfUsed (oldName, newName, this); | |||||
setCoordinate (v, coord); | setCoordinate (v, coord); | ||||
} | } | ||||
} | } | ||||
@@ -133,7 +133,7 @@ public: | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
PositionPropertyComponent (NamedCoordinateFinder& nameSource_, MarkerListBase& markerList_, | |||||
PositionPropertyComponent (NamedCoordinateFinder* nameSource_, MarkerListBase& markerList_, | |||||
const String& name, const ValueTree& markerState_, | const String& name, const ValueTree& markerState_, | ||||
const Value& coordValue_) | const Value& coordValue_) | ||||
: CoordinatePropertyComponent (nameSource_, name, coordValue_, markerList_.isHorizontal()), | : CoordinatePropertyComponent (nameSource_, name, coordValue_, markerList_.isHorizontal()), | ||||
@@ -266,3 +266,143 @@ void FloatingLabelComponent::paint (Graphics& g) | |||||
g.setColour (colour); | g.setColour (colour); | ||||
glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f)); | glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f)); | ||||
} | } | ||||
//============================================================================== | |||||
RelativeRectangleLayoutManager::RelativeRectangleLayoutManager (Component* parentComponent) | |||||
: parent (parentComponent) | |||||
{ | |||||
parent->addComponentListener (this); | |||||
} | |||||
RelativeRectangleLayoutManager::~RelativeRectangleLayoutManager() | |||||
{ | |||||
parent->removeComponentListener (this); | |||||
for (int i = components.size(); --i >= 0;) | |||||
components.getUnchecked(i)->component->removeComponentListener (this); | |||||
} | |||||
void RelativeRectangleLayoutManager::setMarker (const String& name, const RelativeCoordinate& coord) | |||||
{ | |||||
for (int i = markers.size(); --i >= 0;) | |||||
{ | |||||
MarkerPosition* m = markers.getUnchecked(i); | |||||
if (m->markerName == name) | |||||
{ | |||||
m->position = coord; | |||||
applyLayout(); | |||||
return; | |||||
} | |||||
} | |||||
markers.add (new MarkerPosition (name, coord)); | |||||
applyLayout(); | |||||
} | |||||
void RelativeRectangleLayoutManager::setComponentBounds (Component* comp, const String& name, const RelativeRectangle& coords) | |||||
{ | |||||
jassert (comp != 0); | |||||
// All the components that this layout manages must be inside the parent component.. | |||||
jassert (parent->isParentOf (comp)); | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
if (c->component == comp) | |||||
{ | |||||
c->name = name; | |||||
c->coords = coords; | |||||
triggerAsyncUpdate(); | |||||
return; | |||||
} | |||||
} | |||||
components.add (new ComponentPosition (comp, name, coords)); | |||||
comp->addComponentListener (this); | |||||
triggerAsyncUpdate(); | |||||
} | |||||
void RelativeRectangleLayoutManager::applyLayout() | |||||
{ | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
// All the components that this layout manages must be inside the parent component.. | |||||
jassert (parent->isParentOf (c->component)); | |||||
c->component->setBounds (c->coords.resolve (this).getSmallestIntegerContainer()); | |||||
} | |||||
} | |||||
const RelativeCoordinate RelativeRectangleLayoutManager::findNamedCoordinate (const String& objectName, const String& edge) const | |||||
{ | |||||
if (objectName == RelativeCoordinate::Strings::parent) | |||||
{ | |||||
if (edge == RelativeCoordinate::Strings::right) return RelativeCoordinate ((double) parent->getWidth(), true); | |||||
if (edge == RelativeCoordinate::Strings::bottom) return RelativeCoordinate ((double) parent->getHeight(), false); | |||||
} | |||||
if (objectName.isNotEmpty() && edge.isNotEmpty()) | |||||
{ | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
if (c->name == objectName) | |||||
{ | |||||
if (edge == RelativeCoordinate::Strings::left) return c->coords.left; | |||||
if (edge == RelativeCoordinate::Strings::right) return c->coords.right; | |||||
if (edge == RelativeCoordinate::Strings::top) return c->coords.top; | |||||
if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom; | |||||
} | |||||
} | |||||
} | |||||
for (int i = markers.size(); --i >= 0;) | |||||
{ | |||||
MarkerPosition* m = markers.getUnchecked(i); | |||||
if (m->markerName == objectName) | |||||
return m->position; | |||||
} | |||||
return RelativeCoordinate(); | |||||
} | |||||
void RelativeRectangleLayoutManager::componentMovedOrResized (Component& component, bool wasMoved, bool wasResized) | |||||
{ | |||||
triggerAsyncUpdate(); | |||||
if (parent == &component) | |||||
handleUpdateNowIfNeeded(); | |||||
} | |||||
void RelativeRectangleLayoutManager::componentBeingDeleted (Component& component) | |||||
{ | |||||
for (int i = components.size(); --i >= 0;) | |||||
{ | |||||
ComponentPosition* c = components.getUnchecked(i); | |||||
if (c->component == &component) | |||||
{ | |||||
components.remove (i); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
void RelativeRectangleLayoutManager::handleAsyncUpdate() | |||||
{ | |||||
applyLayout(); | |||||
} | |||||
RelativeRectangleLayoutManager::MarkerPosition::MarkerPosition (const String& name, const RelativeCoordinate& coord) | |||||
: markerName (name), position (coord) | |||||
{ | |||||
} | |||||
RelativeRectangleLayoutManager::ComponentPosition::ComponentPosition (Component* component_, const String& name_, const RelativeRectangle& coords_) | |||||
: component (component_), name (name_), coords (coords_) | |||||
{ | |||||
} |
@@ -136,3 +136,72 @@ private: | |||||
JucerToolbarButton (const JucerToolbarButton&); | JucerToolbarButton (const JucerToolbarButton&); | ||||
JucerToolbarButton& operator= (const JucerToolbarButton&); | JucerToolbarButton& operator= (const JucerToolbarButton&); | ||||
}; | }; | ||||
//============================================================================== | |||||
/** | |||||
*/ | |||||
class RelativeRectangleLayoutManager : public ComponentListener, | |||||
public RelativeCoordinate::NamedCoordinateFinder, | |||||
public AsyncUpdater | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** | |||||
*/ | |||||
RelativeRectangleLayoutManager (Component* parentComponent); | |||||
/** Destructor. */ | |||||
~RelativeRectangleLayoutManager(); | |||||
//============================================================================== | |||||
/** | |||||
*/ | |||||
void setMarker (const String& name, const RelativeCoordinate& coord); | |||||
/** | |||||
*/ | |||||
void setComponentBounds (Component* component, const String& componentName, const RelativeRectangle& bounds); | |||||
/** | |||||
*/ | |||||
void applyLayout(); | |||||
//============================================================================== | |||||
/** @internal */ | |||||
const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const; | |||||
/** @internal */ | |||||
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); | |||||
/** @internal */ | |||||
void componentBeingDeleted (Component& component); | |||||
/** @internal */ | |||||
void handleAsyncUpdate(); | |||||
juce_UseDebuggingNewOperator | |||||
private: | |||||
//============================================================================== | |||||
struct ComponentPosition | |||||
{ | |||||
ComponentPosition (Component* component, const String& name, const RelativeRectangle& coords); | |||||
Component* component; | |||||
String name; | |||||
RelativeRectangle coords; | |||||
}; | |||||
struct MarkerPosition | |||||
{ | |||||
MarkerPosition (const String& name, const RelativeCoordinate& coord); | |||||
String markerName; | |||||
RelativeCoordinate position; | |||||
}; | |||||
Component* parent; | |||||
OwnedArray <ComponentPosition> components; | |||||
OwnedArray <MarkerPosition> markers; | |||||
RelativeRectangleLayoutManager (const RelativeRectangleLayoutManager&); | |||||
RelativeRectangleLayoutManager& operator= (const RelativeRectangleLayoutManager&); | |||||
}; |
@@ -63,12 +63,12 @@ clean: | |||||
$(OBJDIR)/Main.o: ../../Source/Main.cpp | $(OBJDIR)/Main.o: ../../Source/Main.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling Main.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp | $(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
-include $(OBJECTS:%.o=%.d) | -include $(OBJECTS:%.o=%.d) |
@@ -70,47 +70,47 @@ clean: | |||||
$(OBJDIR)/FilterGraph.o: ../../Source/FilterGraph.cpp | $(OBJDIR)/FilterGraph.o: ../../Source/FilterGraph.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling FilterGraph.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/GraphEditorPanel.o: ../../Source/GraphEditorPanel.cpp | $(OBJDIR)/GraphEditorPanel.o: ../../Source/GraphEditorPanel.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling GraphEditorPanel.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/HostStartup.o: ../../Source/HostStartup.cpp | $(OBJDIR)/HostStartup.o: ../../Source/HostStartup.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling HostStartup.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/InternalFilters.o: ../../Source/InternalFilters.cpp | $(OBJDIR)/InternalFilters.o: ../../Source/InternalFilters.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling InternalFilters.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/MainHostWindow.o: ../../Source/MainHostWindow.cpp | $(OBJDIR)/MainHostWindow.o: ../../Source/MainHostWindow.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling MainHostWindow.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode1.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode2.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode3.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode4.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
-include $(OBJECTS:%.o=%.d) | -include $(OBJECTS:%.o=%.d) |
@@ -63,12 +63,12 @@ clean: | |||||
$(OBJDIR)/Main.o: ../../Source/Main.cpp | $(OBJDIR)/Main.o: ../../Source/Main.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling Main.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp | $(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
-include $(OBJECTS:%.o=%.d) | -include $(OBJECTS:%.o=%.d) |
@@ -67,32 +67,32 @@ clean: | |||||
$(OBJDIR)/Main.o: ../../Source/Main.cpp | $(OBJDIR)/Main.o: ../../Source/Main.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling Main.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/MainComponent.o: ../../Source/MainComponent.cpp | $(OBJDIR)/MainComponent.o: ../../Source/MainComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling MainComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode1.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode2.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode3.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode4.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
-include $(OBJECTS:%.o=%.d) | -include $(OBJECTS:%.o=%.d) |
@@ -87,132 +87,132 @@ clean: | |||||
$(OBJDIR)/ApplicationStartup.o: ../../Source/ApplicationStartup.cpp | $(OBJDIR)/ApplicationStartup.o: ../../Source/ApplicationStartup.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling ApplicationStartup.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/MainDemoWindow.o: ../../Source/MainDemoWindow.cpp | $(OBJDIR)/MainDemoWindow.o: ../../Source/MainDemoWindow.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling MainDemoWindow.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/AudioDemoLatencyPage.o: ../../Source/demos/AudioDemoLatencyPage.cpp | $(OBJDIR)/AudioDemoLatencyPage.o: ../../Source/demos/AudioDemoLatencyPage.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling AudioDemoLatencyPage.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/AudioDemoPlaybackPage.o: ../../Source/demos/AudioDemoPlaybackPage.cpp | $(OBJDIR)/AudioDemoPlaybackPage.o: ../../Source/demos/AudioDemoPlaybackPage.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling AudioDemoPlaybackPage.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/AudioDemoRecordPage.o: ../../Source/demos/AudioDemoRecordPage.cpp | $(OBJDIR)/AudioDemoRecordPage.o: ../../Source/demos/AudioDemoRecordPage.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling AudioDemoRecordPage.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/AudioDemoSetupPage.o: ../../Source/demos/AudioDemoSetupPage.cpp | $(OBJDIR)/AudioDemoSetupPage.o: ../../Source/demos/AudioDemoSetupPage.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling AudioDemoSetupPage.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/AudioDemoSynthPage.o: ../../Source/demos/AudioDemoSynthPage.cpp | $(OBJDIR)/AudioDemoSynthPage.o: ../../Source/demos/AudioDemoSynthPage.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling AudioDemoSynthPage.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/AudioDemoTabComponent.o: ../../Source/demos/AudioDemoTabComponent.cpp | $(OBJDIR)/AudioDemoTabComponent.o: ../../Source/demos/AudioDemoTabComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling AudioDemoTabComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/CameraDemo.o: ../../Source/demos/CameraDemo.cpp | $(OBJDIR)/CameraDemo.o: ../../Source/demos/CameraDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling CameraDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/CodeEditorDemo.o: ../../Source/demos/CodeEditorDemo.cpp | $(OBJDIR)/CodeEditorDemo.o: ../../Source/demos/CodeEditorDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling CodeEditorDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/DragAndDropDemo.o: ../../Source/demos/DragAndDropDemo.cpp | $(OBJDIR)/DragAndDropDemo.o: ../../Source/demos/DragAndDropDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling DragAndDropDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/FontsAndTextDemo.o: ../../Source/demos/FontsAndTextDemo.cpp | $(OBJDIR)/FontsAndTextDemo.o: ../../Source/demos/FontsAndTextDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling FontsAndTextDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/InterprocessCommsDemo.o: ../../Source/demos/InterprocessCommsDemo.cpp | $(OBJDIR)/InterprocessCommsDemo.o: ../../Source/demos/InterprocessCommsDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling InterprocessCommsDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/OpenGLDemo.o: ../../Source/demos/OpenGLDemo.cpp | $(OBJDIR)/OpenGLDemo.o: ../../Source/demos/OpenGLDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling OpenGLDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/QuickTimeDemo.o: ../../Source/demos/QuickTimeDemo.cpp | $(OBJDIR)/QuickTimeDemo.o: ../../Source/demos/QuickTimeDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling QuickTimeDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/RenderingTestComponent.o: ../../Source/demos/RenderingTestComponent.cpp | $(OBJDIR)/RenderingTestComponent.o: ../../Source/demos/RenderingTestComponent.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling RenderingTestComponent.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/TableDemo.o: ../../Source/demos/TableDemo.cpp | $(OBJDIR)/TableDemo.o: ../../Source/demos/TableDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling TableDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/ThreadingDemo.o: ../../Source/demos/ThreadingDemo.cpp | $(OBJDIR)/ThreadingDemo.o: ../../Source/demos/ThreadingDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling ThreadingDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/TreeViewDemo.o: ../../Source/demos/TreeViewDemo.cpp | $(OBJDIR)/TreeViewDemo.o: ../../Source/demos/TreeViewDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling TreeViewDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/WebBrowserDemo.o: ../../Source/demos/WebBrowserDemo.cpp | $(OBJDIR)/WebBrowserDemo.o: ../../Source/demos/WebBrowserDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling WebBrowserDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/WidgetsDemo.o: ../../Source/demos/WidgetsDemo.cpp | $(OBJDIR)/WidgetsDemo.o: ../../Source/demos/WidgetsDemo.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling WidgetsDemo.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp | $(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling BinaryData.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode1.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode2.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode3.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp | ||||
-@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
@echo $(notdir $<) | |||||
@echo "Compiling JuceLibraryCode4.cpp" | |||||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
-include $(OBJECTS:%.o=%.d) | -include $(OBJECTS:%.o=%.d) |
@@ -150,7 +150,7 @@ public: | |||||
return false; | return false; | ||||
for (int i = numUsed; --i >= 0;) | for (int i = numUsed; --i >= 0;) | ||||
if (data.elements [i] != other.data.elements [i]) | |||||
if (! (data.elements [i] == other.data.elements [i])) | |||||
return false; | return false; | ||||
return true; | return true; | ||||
@@ -40,6 +40,11 @@ inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var | |||||
{ | { | ||||
} | } | ||||
bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const throw() | |||||
{ | |||||
return name == other.name && value == other.value; | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
NamedValueSet::NamedValueSet() throw() | NamedValueSet::NamedValueSet() throw() | ||||
{ | { | ||||
@@ -60,6 +65,16 @@ NamedValueSet::~NamedValueSet() | |||||
{ | { | ||||
} | } | ||||
bool NamedValueSet::operator== (const NamedValueSet& other) const | |||||
{ | |||||
return values == other.values; | |||||
} | |||||
bool NamedValueSet::operator!= (const NamedValueSet& other) const | |||||
{ | |||||
return ! operator== (other); | |||||
} | |||||
int NamedValueSet::size() const throw() | int NamedValueSet::size() const throw() | ||||
{ | { | ||||
return values.size(); | return values.size(); | ||||
@@ -51,6 +51,9 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~NamedValueSet(); | ~NamedValueSet(); | ||||
bool operator== (const NamedValueSet& other) const; | |||||
bool operator!= (const NamedValueSet& other) const; | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns the total number of values that the set contains. */ | /** Returns the total number of values that the set contains. */ | ||||
int size() const throw(); | int size() const throw(); | ||||
@@ -108,6 +111,7 @@ private: | |||||
{ | { | ||||
NamedValue() throw(); | NamedValue() throw(); | ||||
NamedValue (const Identifier& name, const var& value); | NamedValue (const Identifier& name, const var& value); | ||||
bool operator== (const NamedValue& other) const throw(); | |||||
Identifier name; | Identifier name; | ||||
var value; | var value; | ||||
@@ -500,6 +500,22 @@ void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoMan | |||||
} | } | ||||
} | } | ||||
bool ValueTree::SharedObject::isEquivalentTo (const SharedObject& other) const | |||||
{ | |||||
if (type != other.type | |||||
|| properties.size() != other.properties.size() | |||||
|| children.size() != other.children.size() | |||||
|| properties != other.properties) | |||||
return false; | |||||
for (int i = 0; i < children.size(); ++i) | |||||
if (! children.getUnchecked(i)->isEquivalentTo (*other.children.getUnchecked(i))) | |||||
return false; | |||||
return true; | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
ValueTree::ValueTree() throw() | ValueTree::ValueTree() throw() | ||||
: object (0) | : object (0) | ||||
@@ -546,16 +562,22 @@ ValueTree::~ValueTree() | |||||
object->valueTreesWithListeners.removeValue (this); | object->valueTreesWithListeners.removeValue (this); | ||||
} | } | ||||
bool ValueTree::operator== (const ValueTree& other) const | |||||
bool ValueTree::operator== (const ValueTree& other) const throw() | |||||
{ | { | ||||
return object == other.object; | return object == other.object; | ||||
} | } | ||||
bool ValueTree::operator!= (const ValueTree& other) const | |||||
bool ValueTree::operator!= (const ValueTree& other) const throw() | |||||
{ | { | ||||
return object != other.object; | return object != other.object; | ||||
} | } | ||||
bool ValueTree::isEquivalentTo (const ValueTree& other) const | |||||
{ | |||||
return object == other.object | |||||
|| (object != 0 && other.object != 0 && object->isEquivalentTo (*other.object)); | |||||
} | |||||
ValueTree ValueTree::createCopy() const | ValueTree ValueTree::createCopy() const | ||||
{ | { | ||||
return ValueTree (object != 0 ? new SharedObject (*object) : 0); | return ValueTree (object != 0 ? new SharedObject (*object) : 0); | ||||
@@ -710,7 +732,7 @@ int ValueTree::indexOf (const ValueTree& child) const | |||||
return object != 0 ? object->indexOf (child) : -1; | return object != 0 ? object->indexOf (child) : -1; | ||||
} | } | ||||
void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager) | |||||
void ValueTree::addChild (const ValueTree& child, int index, UndoManager* const undoManager) | |||||
{ | { | ||||
if (object != 0) | if (object != 0) | ||||
object->addChild (child.object, index, undoManager); | object->addChild (child.object, index, undoManager); | ||||
@@ -102,13 +102,21 @@ public: | |||||
Note that this isn't a value comparison - two independently-created trees which | Note that this isn't a value comparison - two independently-created trees which | ||||
contain identical data are not considered equal. | contain identical data are not considered equal. | ||||
*/ | */ | ||||
bool operator== (const ValueTree& other) const; | |||||
bool operator== (const ValueTree& other) const throw(); | |||||
/** Returns true if this and the other node refer to different underlying structures. | /** Returns true if this and the other node refer to different underlying structures. | ||||
Note that this isn't a value comparison - two independently-created trees which | Note that this isn't a value comparison - two independently-created trees which | ||||
contain identical data are not considered equal. | contain identical data are not considered equal. | ||||
*/ | */ | ||||
bool operator!= (const ValueTree& other) const; | |||||
bool operator!= (const ValueTree& other) const throw(); | |||||
/** Performs a deep comparison between the properties and children of two trees. | |||||
If all the properties and children of the two trees are the same (recursively), this | |||||
returns true. | |||||
The normal operator==() only checks whether two trees refer to the same shared data | |||||
structure, so use this method if you need to do a proper value comparison. | |||||
*/ | |||||
bool isEquivalentTo (const ValueTree& other) const; | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns true if this node refers to some valid data. | /** Returns true if this node refers to some valid data. | ||||
@@ -233,7 +241,7 @@ public: | |||||
If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
so that this change can be undone. | so that this change can be undone. | ||||
*/ | */ | ||||
void addChild (ValueTree child, int index, UndoManager* undoManager); | |||||
void addChild (const ValueTree& child, int index, UndoManager* undoManager); | |||||
/** Removes the specified child from this node's child-list. | /** Removes the specified child from this node's child-list. | ||||
If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
@@ -464,6 +472,7 @@ private: | |||||
void removeChild (int childIndex, UndoManager*); | void removeChild (int childIndex, UndoManager*); | ||||
void removeAllChildren (UndoManager*); | void removeAllChildren (UndoManager*); | ||||
void moveChild (int currentIndex, int newIndex, UndoManager*); | void moveChild (int currentIndex, int newIndex, UndoManager*); | ||||
bool isEquivalentTo (const SharedObject& other) const; | |||||
XmlElement* createXml() const; | XmlElement* createXml() const; | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
@@ -33,7 +33,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
#define JUCE_BUILDNUMBER 5 | |||||
#define JUCE_BUILDNUMBER 6 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -877,8 +877,7 @@ void ListBox::setHeaderComponent (Component* const newHeaderComponent) | |||||
void ListBox::repaintRow (const int rowNumber) throw() | void ListBox::repaintRow (const int rowNumber) throw() | ||||
{ | { | ||||
const Rectangle<int> r (getRowPosition (rowNumber, true)); | |||||
repaint (r.getX(), r.getY(), r.getWidth(), r.getHeight()); | |||||
repaint (getRowPosition (rowNumber, true)); | |||||
} | } | ||||
Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | ||||
@@ -1338,8 +1338,9 @@ void TreeViewItem::repaintItem() const | |||||
{ | { | ||||
if (ownerView != 0 && areAllParentsOpen()) | if (ownerView != 0 && areAllParentsOpen()) | ||||
{ | { | ||||
const Rectangle<int> r (getItemPosition (true)); | |||||
ownerView->viewport->repaint (0, r.getY(), r.getRight(), r.getHeight()); | |||||
Rectangle<int> r (getItemPosition (true)); | |||||
r.setLeft (0); | |||||
ownerView->viewport->repaint (r); | |||||
} | } | ||||
} | } | ||||
@@ -1555,6 +1555,11 @@ void Component::repaint (const int x, const int y, | |||||
internalRepaint (x, y, w, h); | internalRepaint (x, y, w, h); | ||||
} | } | ||||
void Component::repaint (const Rectangle<int>& area) | |||||
{ | |||||
repaint (area.getX(), area.getY(), area.getWidth(), area.getHeight()); | |||||
} | |||||
void Component::internalRepaint (int x, int y, int w, int h) | void Component::internalRepaint (int x, int y, int w, int h) | ||||
{ | { | ||||
// if component methods are being called from threads other than the message | // if component methods are being called from threads other than the message | ||||
@@ -1596,7 +1601,7 @@ void Component::internalRepaint (int x, int y, int w, int h) | |||||
ComponentPeer* const peer = getPeer(); | ComponentPeer* const peer = getPeer(); | ||||
if (peer != 0) | if (peer != 0) | ||||
peer->repaint (x, y, w, h); | |||||
peer->repaint (Rectangle<int> (x, y, w, h)); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -819,6 +819,21 @@ public: | |||||
*/ | */ | ||||
void repaint (int x, int y, int width, int height); | void repaint (int x, int y, int width, int height); | ||||
/** Marks a subsection of this component as needing to be redrawn. | |||||
Calling this will not do any repainting immediately, but will mark the given region | |||||
of the component as 'dirty'. At some point in the near future the operating system | |||||
will send a paint message, which will redraw all the dirty regions of all components. | |||||
There's no guarantee about how soon after calling repaint() the redraw will actually | |||||
happen, and other queued events may be delivered before a redraw is done. | |||||
The region that is passed in will be clipped to keep it within the bounds of this | |||||
component. | |||||
@see repaint() | |||||
*/ | |||||
void repaint (const Rectangle<int>& area); | |||||
//============================================================================== | //============================================================================== | ||||
/** Makes the component use an internal buffer to optimise its redrawing. | /** Makes the component use an internal buffer to optimise its redrawing. | ||||
@@ -117,14 +117,14 @@ public: | |||||
&& ((unsigned int) position.getY()) < (unsigned int) magnifierComp->getHeight(); | && ((unsigned int) position.getY()) < (unsigned int) magnifierComp->getHeight(); | ||||
} | } | ||||
void repaint (int x, int y, int w, int h) | |||||
void repaint (const Rectangle<int>& area) | |||||
{ | { | ||||
const double zoom = magnifierComp->getScaleFactor(); | const double zoom = magnifierComp->getScaleFactor(); | ||||
magnifierComp->repaint ((int) (x * zoom), | |||||
(int) (y * zoom), | |||||
roundToInt (w * zoom) + 1, | |||||
roundToInt (h * zoom) + 1); | |||||
magnifierComp->repaint ((int) (area.getX() * zoom), | |||||
(int) (area.getY() * zoom), | |||||
roundToInt (area.getWidth() * zoom) + 1, | |||||
roundToInt (area.getHeight() * zoom) + 1); | |||||
} | } | ||||
void performAnyPendingRepaintsNow() | void performAnyPendingRepaintsNow() | ||||
@@ -281,7 +281,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** Invalidates a region of the window to be repainted asynchronously. */ | /** Invalidates a region of the window to be repainted asynchronously. */ | ||||
virtual void repaint (int x, int y, int w, int h) = 0; | |||||
virtual void repaint (const Rectangle<int>& area) = 0; | |||||
/** This can be called (from the message thread) to cause the immediate redrawing | /** This can be called (from the message thread) to cause the immediate redrawing | ||||
of any areas of this window that need repainting. | of any areas of this window that need repainting. | ||||
@@ -95,9 +95,7 @@ DocumentWindow::~DocumentWindow() | |||||
//============================================================================== | //============================================================================== | ||||
void DocumentWindow::repaintTitleBar() | void DocumentWindow::repaintTitleBar() | ||||
{ | { | ||||
const Rectangle<int> titleBarArea (getTitleBarArea()); | |||||
repaint (titleBarArea.getX(), titleBarArea.getY(), | |||||
titleBarArea.getWidth(), titleBarArea.getHeight()); | |||||
repaint (getTitleBarArea()); | |||||
} | } | ||||
void DocumentWindow::setName (const String& newName) | void DocumentWindow::setName (const String& newName) | ||||
@@ -177,12 +177,13 @@ public: | |||||
x = endX; | x = endX; | ||||
} | } | ||||
levelAccumulator >>= 8; | |||||
if (levelAccumulator > 0) | if (levelAccumulator > 0) | ||||
{ | { | ||||
x >>= 8; | x >>= 8; | ||||
jassert (x >= bounds.getX() && x < bounds.getRight()); | jassert (x >= bounds.getX() && x < bounds.getRight()); | ||||
levelAccumulator >>= 8; | |||||
if (levelAccumulator >> 8) | if (levelAccumulator >> 8) | ||||
iterationCallback.handleEdgeTablePixelFull (x); | iterationCallback.handleEdgeTablePixelFull (x); | ||||
else | else | ||||
@@ -76,6 +76,16 @@ FillType::~FillType() throw() | |||||
{ | { | ||||
} | } | ||||
bool FillType::operator== (const FillType& other) const | |||||
{ | |||||
return colour == other.colour && gradient == other.gradient && image == other.image; | |||||
} | |||||
bool FillType::operator!= (const FillType& other) const | |||||
{ | |||||
return ! operator== (other); | |||||
} | |||||
void FillType::setColour (const Colour& newColour) throw() | void FillType::setColour (const Colour& newColour) throw() | ||||
{ | { | ||||
gradient = 0; | gradient = 0; | ||||
@@ -110,4 +120,10 @@ void FillType::setOpacity (const float newOpacity) throw() | |||||
colour = colour.withAlpha (newOpacity); | colour = colour.withAlpha (newOpacity); | ||||
} | } | ||||
bool FillType::isInvisible() const throw() | |||||
{ | |||||
return colour.isTransparent() || (gradient != 0 && gradient->isInvisible()); | |||||
} | |||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE |
@@ -103,6 +103,12 @@ public: | |||||
*/ | */ | ||||
float getOpacity() const throw() { return colour.getFloatAlpha(); } | float getOpacity() const throw() { return colour.getFloatAlpha(); } | ||||
/** Returns true if this fill type is completely transparent. */ | |||||
bool isInvisible() const throw(); | |||||
bool operator== (const FillType& other) const; | |||||
bool operator!= (const FillType& other) const; | |||||
/** The solid colour being used. | /** The solid colour being used. | ||||
If the fill type is not a solid colour, the alpha channel of this colour indicates | If the fill type is not a solid colour, the alpha channel of this colour indicates | ||||
@@ -1899,41 +1899,38 @@ public: | |||||
shapeToFill = clip->applyClipTo (shapeToFill); | shapeToFill = clip->applyClipTo (shapeToFill); | ||||
if (shapeToFill != 0) | if (shapeToFill != 0) | ||||
fillShapeWithoutClipping (image, shapeToFill, replaceContents); | |||||
} | |||||
{ | |||||
Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); | |||||
void fillShapeWithoutClipping (Image& image, const SoftwareRendererClasses::ClipRegionBase::Ptr& shapeToFill, const bool replaceContents) | |||||
{ | |||||
Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); | |||||
if (fillType.isGradient()) | |||||
{ | |||||
jassert (! replaceContents); // that option is just for solid colours | |||||
if (fillType.isGradient()) | |||||
{ | |||||
jassert (! replaceContents); // that option is just for solid colours | |||||
ColourGradient g2 (*(fillType.gradient)); | |||||
g2.multiplyOpacity (fillType.getOpacity()); | |||||
g2.point1.addXY (-0.5f, -0.5f); | |||||
g2.point2.addXY (-0.5f, -0.5f); | |||||
AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); | |||||
const bool isIdentity = transform.isOnlyTranslation(); | |||||
ColourGradient g2 (*(fillType.gradient)); | |||||
g2.multiplyOpacity (fillType.getOpacity()); | |||||
g2.point1.addXY (-0.5f, -0.5f); | |||||
g2.point2.addXY (-0.5f, -0.5f); | |||||
AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); | |||||
const bool isIdentity = transform.isOnlyTranslation(); | |||||
if (isIdentity) | |||||
{ | |||||
// If our translation doesn't involve any distortion, we can speed it up.. | |||||
g2.point1.applyTransform (transform); | |||||
g2.point2.applyTransform (transform); | |||||
transform = AffineTransform::identity; | |||||
} | |||||
if (isIdentity) | |||||
shapeToFill->fillAllWithGradient (destData, g2, transform, isIdentity); | |||||
} | |||||
else if (fillType.isTiledImage()) | |||||
{ | { | ||||
// If our translation doesn't involve any distortion, we can speed it up.. | |||||
g2.point1.applyTransform (transform); | |||||
g2.point2.applyTransform (transform); | |||||
transform = AffineTransform::identity; | |||||
renderImage (image, *(fillType.image), fillType.image->getBounds(), fillType.transform, shapeToFill); | |||||
} | |||||
else | |||||
{ | |||||
shapeToFill->fillAllWithColour (destData, fillType.colour.getPixelARGB(), replaceContents); | |||||
} | } | ||||
shapeToFill->fillAllWithGradient (destData, g2, transform, isIdentity); | |||||
} | |||||
else if (fillType.isTiledImage()) | |||||
{ | |||||
renderImage (image, *(fillType.image), fillType.image->getBounds(), fillType.transform, shapeToFill); | |||||
} | |||||
else | |||||
{ | |||||
shapeToFill->fillAllWithColour (destData, fillType.colour.getPixelARGB(), replaceContents); | |||||
} | } | ||||
} | } | ||||
@@ -36,7 +36,6 @@ BEGIN_JUCE_NAMESPACE | |||||
#include "../../../text/juce_XmlDocument.h" | #include "../../../text/juce_XmlDocument.h" | ||||
#include "../../../io/files/juce_FileInputStream.h" | #include "../../../io/files/juce_FileInputStream.h" | ||||
const Identifier Drawable::idProperty ("id"); | |||||
//============================================================================== | //============================================================================== | ||||
Drawable::RenderingContext::RenderingContext (Graphics& g_, | Drawable::RenderingContext::RenderingContext (Graphics& g_, | ||||
@@ -50,6 +49,7 @@ Drawable::RenderingContext::RenderingContext (Graphics& g_, | |||||
//============================================================================== | //============================================================================== | ||||
Drawable::Drawable() | Drawable::Drawable() | ||||
: parent (0) | |||||
{ | { | ||||
} | } | ||||
@@ -57,8 +57,7 @@ Drawable::~Drawable() | |||||
{ | { | ||||
} | } | ||||
void Drawable::draw (Graphics& g, const float opacity, | |||||
const AffineTransform& transform) const | |||||
void Drawable::draw (Graphics& g, const float opacity, const AffineTransform& transform) const | |||||
{ | { | ||||
render (RenderingContext (g, transform, opacity)); | render (RenderingContext (g, transform, opacity)); | ||||
} | } | ||||
@@ -156,4 +155,131 @@ Drawable* Drawable::createFromValueTree (const ValueTree& tree, ImageProvider* i | |||||
} | } | ||||
//============================================================================== | |||||
const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::type ("type"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::x1 ("x1"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::x2 ("x2"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::y1 ("y1"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::y2 ("y2"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::colour ("colour"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::radial ("radial"); | |||||
const Identifier Drawable::ValueTreeWrapperBase::colours ("colours"); | |||||
Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_) | |||||
: state (state_) | |||||
{ | |||||
} | |||||
Drawable::ValueTreeWrapperBase::~ValueTreeWrapperBase() | |||||
{ | |||||
} | |||||
const String Drawable::ValueTreeWrapperBase::getID() const | |||||
{ | |||||
return state [idProperty]; | |||||
} | |||||
void Drawable::ValueTreeWrapperBase::setID (const String& newID, UndoManager* undoManager) | |||||
{ | |||||
if (newID.isEmpty()) | |||||
state.removeProperty (idProperty, undoManager); | |||||
else | |||||
state.setProperty (idProperty, newID, undoManager); | |||||
} | |||||
const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v) | |||||
{ | |||||
const String newType (v[type].toString()); | |||||
if (newType == "solid") | |||||
{ | |||||
const String colourString (v [colour].toString()); | |||||
return FillType (Colour (colourString.isEmpty() ? (uint32) 0xff000000 | |||||
: (uint32) colourString.getHexValue32())); | |||||
} | |||||
else if (newType == "gradient") | |||||
{ | |||||
ColourGradient g; | |||||
g.point1.setXY (v[x1], v[y1]); | |||||
g.point2.setXY (v[x2], v[y2]); | |||||
g.isRadial = v[radial]; | |||||
StringArray colourSteps; | |||||
colourSteps.addTokens (v[colours].toString(), false); | |||||
for (int i = 0; i < colourSteps.size() / 2; ++i) | |||||
g.addColour (colourSteps[i * 2].getDoubleValue(), | |||||
Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); | |||||
return FillType (g); | |||||
} | |||||
else if (newType == "image") | |||||
{ | |||||
jassertfalse; //xxx todo | |||||
} | |||||
jassertfalse; | |||||
return FillType(); | |||||
} | |||||
void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager) | |||||
{ | |||||
ValueTree v (state.getChildWithName (tag)); | |||||
if (! v.isValid()) | |||||
{ | |||||
state.addChild (ValueTree (tag), -1, undoManager); | |||||
v = state.getChildWithName (tag); | |||||
} | |||||
if (fillType.isColour()) | |||||
{ | |||||
v.setProperty (type, "solid", undoManager); | |||||
v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager); | |||||
v.removeProperty (x1, undoManager); | |||||
v.removeProperty (x2, undoManager); | |||||
v.removeProperty (y1, undoManager); | |||||
v.removeProperty (y2, undoManager); | |||||
v.removeProperty (radial, undoManager); | |||||
v.removeProperty (colours, undoManager); | |||||
} | |||||
else if (fillType.isGradient()) | |||||
{ | |||||
v.setProperty (type, "gradient", undoManager); | |||||
v.setProperty (x1, fillType.gradient->point1.getX(), undoManager); | |||||
v.setProperty (y1, fillType.gradient->point1.getY(), undoManager); | |||||
v.setProperty (x2, fillType.gradient->point2.getX(), undoManager); | |||||
v.setProperty (y2, fillType.gradient->point2.getY(), undoManager); | |||||
v.setProperty (radial, fillType.gradient->isRadial, undoManager); | |||||
String s; | |||||
for (int i = 0; i < fillType.gradient->getNumColours(); ++i) | |||||
s << " " << fillType.gradient->getColourPosition (i) | |||||
<< " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); | |||||
v.setProperty (colours, s.trimStart(), undoManager); | |||||
v.removeProperty (colour, undoManager); | |||||
} | |||||
else if (fillType.isTiledImage()) | |||||
{ | |||||
v.setProperty (type, "image", undoManager); | |||||
jassertfalse; //xxx todo | |||||
v.removeProperty (x1, undoManager); | |||||
v.removeProperty (x2, undoManager); | |||||
v.removeProperty (y1, undoManager); | |||||
v.removeProperty (y2, undoManager); | |||||
v.removeProperty (radial, undoManager); | |||||
v.removeProperty (colours, undoManager); | |||||
v.removeProperty (colour, undoManager); | |||||
} | |||||
else | |||||
{ | |||||
jassertfalse; | |||||
} | |||||
} | |||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE |
@@ -27,8 +27,10 @@ | |||||
#define __JUCE_DRAWABLE_JUCEHEADER__ | #define __JUCE_DRAWABLE_JUCEHEADER__ | ||||
#include "../contexts/juce_Graphics.h" | #include "../contexts/juce_Graphics.h" | ||||
#include "../geometry/juce_RelativeCoordinate.h" | |||||
#include "../../../text/juce_XmlElement.h" | #include "../../../text/juce_XmlElement.h" | ||||
#include "../../../containers/juce_ValueTree.h" | #include "../../../containers/juce_ValueTree.h" | ||||
class DrawableComposite; | |||||
//============================================================================== | //============================================================================== | ||||
@@ -229,11 +231,34 @@ public: | |||||
/** Returns the tag ID that is used for a ValueTree that stores this type of drawable. */ | /** Returns the tag ID that is used for a ValueTree that stores this type of drawable. */ | ||||
virtual const Identifier getValueTreeType() const = 0; | virtual const Identifier getValueTreeType() const = 0; | ||||
//============================================================================== | |||||
/** Internal class used to manage ValueTrees that represent Drawables. */ | |||||
class ValueTreeWrapperBase | |||||
{ | |||||
public: | |||||
ValueTreeWrapperBase (const ValueTree& state); | |||||
~ValueTreeWrapperBase(); | |||||
ValueTree& getState() throw() { return state; } | |||||
const String getID() const; | |||||
void setID (const String& newID, UndoManager* undoManager); | |||||
protected: | |||||
ValueTree state; | |||||
static const Identifier idProperty, type, x1, x2, y1, y2, colour, radial, colours; | |||||
static const FillType readFillType (const ValueTree& v); | |||||
void replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager); | |||||
}; | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
protected: | protected: | ||||
static const Identifier idProperty; | |||||
friend class DrawableComposite; | |||||
DrawableComposite* parent; | |||||
virtual void invalidatePoints() = 0; | |||||
private: | private: | ||||
String name; | String name; | ||||
@@ -37,8 +37,21 @@ BEGIN_JUCE_NAMESPACE | |||||
//============================================================================== | //============================================================================== | ||||
DrawableComposite::DrawableComposite() | DrawableComposite::DrawableComposite() | ||||
{ | { | ||||
controlPoints[1].setXY (1.0f, 0.0f); | |||||
controlPoints[2].setXY (0.0f, 1.0f); | |||||
controlPoints[1] = RelativePoint (Point<float> (1.0f, 0.0f)); | |||||
controlPoints[2] = RelativePoint (Point<float> (0.0f, 1.0f)); | |||||
} | |||||
DrawableComposite::DrawableComposite (const DrawableComposite& other) | |||||
{ | |||||
int i; | |||||
for (i = 0; i < 3; ++i) | |||||
controlPoints[i] = other.controlPoints[i]; | |||||
for (i = 0; i < drawables.size(); ++i) | |||||
drawables.add (other.drawables.getUnchecked(i)->createCopy()); | |||||
for (i = 0; i < markers.size(); ++i) | |||||
markers.add (new Marker (*other.markers.getUnchecked(i))); | |||||
} | } | ||||
DrawableComposite::~DrawableComposite() | DrawableComposite::~DrawableComposite() | ||||
@@ -51,7 +64,9 @@ void DrawableComposite::insertDrawable (Drawable* drawable, const int index) | |||||
if (drawable != 0) | if (drawable != 0) | ||||
{ | { | ||||
jassert (! drawables.contains (drawable)); // trying to add a drawable that's already in here! | jassert (! drawables.contains (drawable)); // trying to add a drawable that's already in here! | ||||
jassert (drawable->parent == 0); // A drawable can only live inside one parent at a time! | |||||
drawables.insert (index, drawable); | drawables.insert (index, drawable); | ||||
drawable->parent = this; | |||||
} | } | ||||
} | } | ||||
@@ -71,9 +86,9 @@ void DrawableComposite::bringToFront (const int index) | |||||
drawables.move (index, -1); | drawables.move (index, -1); | ||||
} | } | ||||
void DrawableComposite::setTransform (const Point<float>& targetPositionForOrigin, | |||||
const Point<float>& targetPositionForX1Y0, | |||||
const Point<float>& targetPositionForX0Y1) | |||||
void DrawableComposite::setTransform (const RelativePoint& targetPositionForOrigin, | |||||
const RelativePoint& targetPositionForX1Y0, | |||||
const RelativePoint& targetPositionForX0Y1) | |||||
{ | { | ||||
controlPoints[0] = targetPositionForOrigin; | controlPoints[0] = targetPositionForOrigin; | ||||
controlPoints[1] = targetPositionForX1Y0; | controlPoints[1] = targetPositionForX1Y0; | ||||
@@ -81,11 +96,70 @@ void DrawableComposite::setTransform (const Point<float>& targetPositionForOrigi | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
const AffineTransform DrawableComposite::getTransform() const | |||||
DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other) | |||||
: name (other.name), position (other.position), isOnXAxis (other.isOnXAxis) | |||||
{ | |||||
} | |||||
DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_, const bool isOnXAxis_) | |||||
: name (name_), position (position_), isOnXAxis (isOnXAxis_) | |||||
{ | |||||
} | |||||
bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw() | |||||
{ | |||||
return name != other.name || position != other.position || isOnXAxis != other.isOnXAxis; | |||||
} | |||||
//============================================================================== | |||||
int DrawableComposite::getNumMarkers (bool xAxis) const throw() | |||||
{ | |||||
return markers.size(); | |||||
} | |||||
const DrawableComposite::Marker* DrawableComposite::getMarker (int index) const throw() | |||||
{ | |||||
return markers [index]; | |||||
} | |||||
void DrawableComposite::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position) | |||||
{ | |||||
for (int i = 0; i < markers.size(); ++i) | |||||
{ | |||||
Marker* const m = markers.getUnchecked(i); | |||||
if (m->name == name) | |||||
{ | |||||
jassert (m->isOnXAxis == xAxis); // trying to either have two markers with the same name on different axes? | |||||
if (m->position != position) | |||||
{ | |||||
m->position = position; | |||||
invalidatePoints(); | |||||
} | |||||
return; | |||||
} | |||||
} | |||||
markers.add (new Marker (name, position, xAxis)); | |||||
invalidatePoints(); | |||||
} | |||||
void DrawableComposite::removeMarker (int index) | |||||
{ | { | ||||
return AffineTransform::fromTargetPoints (controlPoints[0].getX(), controlPoints[0].getY(), | |||||
controlPoints[1].getX(), controlPoints[1].getY(), | |||||
controlPoints[2].getX(), controlPoints[2].getY()); | |||||
markers.remove (index); | |||||
} | |||||
//============================================================================== | |||||
const AffineTransform DrawableComposite::calculateTransform() const | |||||
{ | |||||
Point<float> resolved[3]; | |||||
for (int i = 0; i < 3; ++i) | |||||
resolved[i] = controlPoints[i].resolve (parent); | |||||
return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), | |||||
resolved[1].getX(), resolved[1].getY(), | |||||
resolved[2].getX(), resolved[2].getY()); | |||||
} | } | ||||
void DrawableComposite::render (const Drawable::RenderingContext& context) const | void DrawableComposite::render (const Drawable::RenderingContext& context) const | ||||
@@ -95,7 +169,7 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const | |||||
if (context.opacity >= 1.0f || drawables.size() == 1) | if (context.opacity >= 1.0f || drawables.size() == 1) | ||||
{ | { | ||||
Drawable::RenderingContext contextCopy (context); | Drawable::RenderingContext contextCopy (context); | ||||
contextCopy.transform = getTransform().followedBy (context.transform); | |||||
contextCopy.transform = calculateTransform().followedBy (context.transform); | |||||
for (int i = 0; i < drawables.size(); ++i) | for (int i = 0; i < drawables.size(); ++i) | ||||
drawables.getUnchecked(i)->render (contextCopy); | drawables.getUnchecked(i)->render (contextCopy); | ||||
@@ -121,6 +195,33 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const | |||||
} | } | ||||
} | } | ||||
const RelativeCoordinate DrawableComposite::findNamedCoordinate (const String& objectName, const String& edge) const | |||||
{ | |||||
if (objectName == RelativeCoordinate::Strings::parent) | |||||
{ | |||||
if (edge == RelativeCoordinate::Strings::right) | |||||
{ | |||||
jassertfalse; // a Drawable doesn't have a fixed right-hand edge - use a marker instead if you need a point of reference. | |||||
return RelativeCoordinate (100.0, true); | |||||
} | |||||
if (edge == RelativeCoordinate::Strings::bottom) | |||||
{ | |||||
jassertfalse; // a Drawable doesn't have a fixed bottom edge - use a marker instead if you need a point of reference. | |||||
return RelativeCoordinate (100.0, false); | |||||
} | |||||
} | |||||
for (int i = 0; i < markers.size(); ++i) | |||||
{ | |||||
Marker* const m = markers.getUnchecked(i); | |||||
if (m->name == objectName) | |||||
return m->position; | |||||
} | |||||
return RelativeCoordinate(); | |||||
} | |||||
const Rectangle<float> DrawableComposite::getUntransformedBounds() const | const Rectangle<float> DrawableComposite::getUntransformedBounds() const | ||||
{ | { | ||||
Rectangle<float> bounds; | Rectangle<float> bounds; | ||||
@@ -133,12 +234,12 @@ const Rectangle<float> DrawableComposite::getUntransformedBounds() const | |||||
const Rectangle<float> DrawableComposite::getBounds() const | const Rectangle<float> DrawableComposite::getBounds() const | ||||
{ | { | ||||
return getUntransformedBounds().transformed (getTransform()); | |||||
return getUntransformedBounds().transformed (calculateTransform()); | |||||
} | } | ||||
bool DrawableComposite::hitTest (float x, float y) const | bool DrawableComposite::hitTest (float x, float y) const | ||||
{ | { | ||||
getTransform().inverted().transformPoint (x, y); | |||||
calculateTransform().inverted().transformPoint (x, y); | |||||
for (int i = 0; i < drawables.size(); ++i) | for (int i = 0; i < drawables.size(); ++i) | ||||
if (drawables.getUnchecked(i)->hitTest (x, y)) | if (drawables.getUnchecked(i)->hitTest (x, y)) | ||||
@@ -149,125 +250,282 @@ bool DrawableComposite::hitTest (float x, float y) const | |||||
Drawable* DrawableComposite::createCopy() const | Drawable* DrawableComposite::createCopy() const | ||||
{ | { | ||||
DrawableComposite* const dc = new DrawableComposite(); | |||||
for (int i = 0; i < 3; ++i) | |||||
dc->controlPoints[i] = controlPoints[i]; | |||||
return new DrawableComposite (*this); | |||||
} | |||||
void DrawableComposite::invalidatePoints() | |||||
{ | |||||
for (int i = 0; i < drawables.size(); ++i) | for (int i = 0; i < drawables.size(); ++i) | ||||
dc->drawables.add (drawables.getUnchecked(i)->createCopy()); | |||||
return dc; | |||||
drawables.getUnchecked(i)->invalidatePoints(); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
const Identifier DrawableComposite::valueTreeType ("Group"); | const Identifier DrawableComposite::valueTreeType ("Group"); | ||||
namespace DrawableCompositeHelpers | |||||
const Identifier DrawableComposite::ValueTreeWrapper::topLeft ("topLeft"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::topRight ("topRight"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::bottomLeft ("bottomLeft"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::childGroupTag ("Drawables"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTag ("Markers"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::markerTag ("Marker"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::nameProperty ("name"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::xAxisProperty ("xAxis"); | |||||
const Identifier DrawableComposite::ValueTreeWrapper::posProperty ("position"); | |||||
//============================================================================== | |||||
DrawableComposite::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) | |||||
: ValueTreeWrapperBase (state_) | |||||
{ | |||||
jassert (state.hasType (valueTreeType)); | |||||
} | |||||
ValueTree DrawableComposite::ValueTreeWrapper::getChildList() const | |||||
{ | |||||
return state.getChildWithName (childGroupTag); | |||||
} | |||||
ValueTree DrawableComposite::ValueTreeWrapper::getChildListCreating (UndoManager* undoManager) | |||||
{ | |||||
const ValueTree childList (getChildList()); | |||||
if (childList.isValid()) | |||||
return childList; | |||||
state.addChild (ValueTree (childGroupTag), 0, undoManager); | |||||
return getChildList(); | |||||
} | |||||
ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList() const | |||||
{ | { | ||||
static const Identifier topLeft ("topLeft"); | |||||
static const Identifier topRight ("topRight"); | |||||
static const Identifier bottomLeft ("bottomLeft"); | |||||
return state.getChildWithName (markerGroupTag); | |||||
} | |||||
ValueTree DrawableComposite::ValueTreeWrapper::getMarkerListCreating (UndoManager* undoManager) | |||||
{ | |||||
const ValueTree markerList (getMarkerList()); | |||||
if (markerList.isValid()) | |||||
return markerList; | |||||
state.addChild (ValueTree (markerGroupTag), -1, undoManager); | |||||
return getMarkerList(); | |||||
} | |||||
int DrawableComposite::ValueTreeWrapper::getNumDrawables() const | |||||
{ | |||||
return getChildList().getNumChildren(); | |||||
} | |||||
const ValueTree DrawableComposite::ValueTreeWrapper::getDrawableState (int index) const | |||||
{ | |||||
return getChildList().getChild (index); | |||||
} | |||||
void DrawableComposite::ValueTreeWrapper::addDrawable (const ValueTree& newDrawableState, int index, UndoManager* undoManager) | |||||
{ | |||||
getChildListCreating (undoManager).addChild (newDrawableState, index, undoManager); | |||||
} | |||||
void DrawableComposite::ValueTreeWrapper::moveDrawableOrder (int currentIndex, int newIndex, UndoManager* undoManager) | |||||
{ | |||||
getChildListCreating (undoManager).moveChild (currentIndex, newIndex, undoManager); | |||||
} | |||||
void DrawableComposite::ValueTreeWrapper::removeDrawable (int index, UndoManager* undoManager) | |||||
{ | |||||
getChildList().removeChild (index, undoManager); | |||||
} | |||||
const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForOrigin() const | |||||
{ | |||||
const String pos (state [topLeft].toString()); | |||||
return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (); | |||||
} | |||||
void DrawableComposite::ValueTreeWrapper::setTargetPositionForOrigin (const RelativePoint& newPoint, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (topLeft, newPoint.toString(), undoManager); | |||||
} | |||||
const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForX1Y0() const | |||||
{ | |||||
const String pos (state [topRight].toString()); | |||||
return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point<float> (1.0f, 0.0f)); | |||||
} | |||||
void DrawableComposite::ValueTreeWrapper::setTargetPositionForX1Y0 (const RelativePoint& newPoint, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (topRight, newPoint.toString(), undoManager); | |||||
} | |||||
static void stringToPoint (const String& coords, Point<float>& point) | |||||
const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForX0Y1() const | |||||
{ | |||||
const String pos (state [bottomLeft].toString()); | |||||
return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point<float> (0.0f, 1.0f)); | |||||
} | |||||
void DrawableComposite::ValueTreeWrapper::setTargetPositionForX0Y1 (const RelativePoint& newPoint, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (bottomLeft, newPoint.toString(), undoManager); | |||||
} | |||||
int DrawableComposite::ValueTreeWrapper::getNumMarkers() const | |||||
{ | |||||
return getMarkerList().getNumChildren(); | |||||
} | |||||
const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (int index) const | |||||
{ | |||||
const ValueTree marker (getMarkerList().getChild (index)); | |||||
const bool isXAxis = marker [xAxisProperty]; | |||||
return Marker (marker [nameProperty], | |||||
RelativeCoordinate (marker [posProperty].toString(), isXAxis), | |||||
isXAxis); | |||||
} | |||||
void DrawableComposite::ValueTreeWrapper::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager) | |||||
{ | |||||
ValueTree markerList (getMarkerListCreating (undoManager)); | |||||
ValueTree marker (markerList.getChildWithProperty (nameProperty, name)); | |||||
if (marker.isValid()) | |||||
{ | { | ||||
if (coords.isNotEmpty()) | |||||
{ | |||||
const int comma = coords.indexOfChar (','); | |||||
point.setXY (coords.substring (0, comma).getFloatValue(), | |||||
coords.substring (comma + 1).getFloatValue()); | |||||
} | |||||
jassert ((bool) marker [xAxisProperty] == xAxis); // shouldn't change the axis of a marker after it has been created! | |||||
marker.setProperty (posProperty, position.toString(), undoManager); | |||||
} | } | ||||
static const var pointToString (const Point<float>& point) | |||||
else | |||||
{ | { | ||||
return String (point.getX()) + ", " + String (point.getY()); | |||||
marker = ValueTree (markerTag); | |||||
marker.setProperty (nameProperty, name, 0); | |||||
marker.setProperty (xAxisProperty, xAxis, 0); | |||||
marker.setProperty (posProperty, position.toString(), 0); | |||||
markerList.addChild (marker, -1, undoManager); | |||||
} | } | ||||
} | } | ||||
const Rectangle<float> DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | |||||
void DrawableComposite::ValueTreeWrapper::removeMarker (int index, UndoManager* undoManager) | |||||
{ | { | ||||
jassert (tree.hasType (valueTreeType)); | |||||
return getMarkerList().removeChild (index, undoManager); | |||||
} | |||||
//============================================================================== | |||||
const Rectangle<float> DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | |||||
{ | |||||
Rectangle<float> damageRect; | Rectangle<float> damageRect; | ||||
const ValueTreeWrapper controller (tree); | |||||
setName (controller.getID()); | |||||
setName (tree [idProperty]); | |||||
RelativePoint newControlPoint[3] = { controller.getTargetPositionForOrigin(), | |||||
controller.getTargetPositionForX1Y0(), | |||||
controller.getTargetPositionForX0Y1() }; | |||||
Point<float> newControlPoint[3]; | |||||
DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::topLeft].toString(), newControlPoint[0]); | |||||
DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::topRight].toString(), newControlPoint[1]); | |||||
DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::bottomLeft].toString(), newControlPoint[2]); | |||||
bool controlPointsChanged = false; | |||||
bool redrawAll = false; | |||||
if (controlPoints[0] != newControlPoint[0] | if (controlPoints[0] != newControlPoint[0] | ||||
|| controlPoints[1] != newControlPoint[1] | || controlPoints[1] != newControlPoint[1] | ||||
|| controlPoints[2] != newControlPoint[2]) | || controlPoints[2] != newControlPoint[2]) | ||||
{ | { | ||||
controlPointsChanged = true; | |||||
redrawAll = true; | |||||
damageRect = getUntransformedBounds(); | damageRect = getUntransformedBounds(); | ||||
controlPoints[0] = newControlPoint[0]; | controlPoints[0] = newControlPoint[0]; | ||||
controlPoints[1] = newControlPoint[1]; | controlPoints[1] = newControlPoint[1]; | ||||
controlPoints[2] = newControlPoint[2]; | controlPoints[2] = newControlPoint[2]; | ||||
} | } | ||||
// Remove deleted markers... | |||||
int i; | int i; | ||||
for (i = drawables.size(); --i >= tree.getNumChildren();) | |||||
for (i = markers.size(); --i >= controller.getNumMarkers();) | |||||
{ | |||||
if (damageRect.isEmpty()) | |||||
damageRect = getUntransformedBounds(); | |||||
removeMarker (i); | |||||
} | |||||
// Update markers and add new ones.. | |||||
for (i = 0; i < controller.getNumMarkers(); ++i) | |||||
{ | { | ||||
damageRect = damageRect.getUnion (drawables.getUnchecked(i)->getBounds()); | |||||
const Marker newMarker (controller.getMarker (i)); | |||||
Marker* m = markers[i]; | |||||
if (m == 0 || newMarker != *m) | |||||
{ | |||||
redrawAll = true; | |||||
if (damageRect.isEmpty()) | |||||
damageRect = getUntransformedBounds(); | |||||
if (m == 0) | |||||
markers.add (new Marker (newMarker)); | |||||
else | |||||
*m = newMarker; | |||||
} | |||||
} | |||||
// Remove deleted drawables.. | |||||
for (i = drawables.size(); --i >= controller.getNumDrawables();) | |||||
{ | |||||
Drawable* const d = drawables.getUnchecked(i); | |||||
damageRect = damageRect.getUnion (d->getBounds()); | |||||
d->parent = 0; | |||||
drawables.remove (i); | drawables.remove (i); | ||||
} | } | ||||
for (int i = 0; i < tree.getNumChildren(); ++i) | |||||
// Update drawables and add new ones.. | |||||
for (i = 0; i < controller.getNumDrawables(); ++i) | |||||
{ | { | ||||
const ValueTree childTree (tree.getChild (i)); | |||||
const ValueTree newDrawable (controller.getDrawableState (i)); | |||||
Drawable* d = drawables[i]; | Drawable* d = drawables[i]; | ||||
if (d != 0) | if (d != 0) | ||||
{ | { | ||||
if (childTree.hasType (d->getValueTreeType())) | |||||
if (newDrawable.hasType (d->getValueTreeType())) | |||||
{ | { | ||||
damageRect = damageRect.getUnion (d->refreshFromValueTree (childTree, imageProvider)); | |||||
damageRect = damageRect.getUnion (d->refreshFromValueTree (newDrawable, imageProvider)); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
damageRect = damageRect.getUnion (d->getBounds()); | damageRect = damageRect.getUnion (d->getBounds()); | ||||
d = createFromValueTree (childTree, imageProvider); | |||||
d = createFromValueTree (newDrawable, imageProvider); | |||||
d->parent = this; | |||||
drawables.set (i, d); | drawables.set (i, d); | ||||
damageRect = damageRect.getUnion (d->getBounds()); | damageRect = damageRect.getUnion (d->getBounds()); | ||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
d = createFromValueTree (childTree, imageProvider); | |||||
d = createFromValueTree (newDrawable, imageProvider); | |||||
d->parent = this; | |||||
drawables.set (i, d); | drawables.set (i, d); | ||||
damageRect = damageRect.getUnion (d->getBounds()); | damageRect = damageRect.getUnion (d->getBounds()); | ||||
} | } | ||||
} | } | ||||
if (controlPointsChanged) | |||||
if (redrawAll) | |||||
damageRect = damageRect.getUnion (getUntransformedBounds()); | damageRect = damageRect.getUnion (getUntransformedBounds()); | ||||
return damageRect.transformed (getTransform()); | |||||
return damageRect.transformed (calculateTransform()); | |||||
} | } | ||||
const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider) const | const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider) const | ||||
{ | { | ||||
ValueTree v (valueTreeType); | |||||
ValueTree tree (valueTreeType); | |||||
ValueTreeWrapper v (tree); | |||||
if (getName().isNotEmpty()) | |||||
v.setProperty (idProperty, getName(), 0); | |||||
v.setID (getName(), 0); | |||||
v.setTargetPositionForOrigin (controlPoints[0], 0); | |||||
v.setTargetPositionForX1Y0 (controlPoints[1], 0); | |||||
v.setTargetPositionForX0Y1 (controlPoints[2], 0); | |||||
if (! getTransform().isIdentity()) | |||||
int i; | |||||
for (i = 0; i < drawables.size(); ++i) | |||||
v.addDrawable (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); | |||||
for (i = 0; i < markers.size(); ++i) | |||||
{ | { | ||||
v.setProperty (DrawableCompositeHelpers::topLeft, DrawableCompositeHelpers::pointToString (controlPoints[0]), 0); | |||||
v.setProperty (DrawableCompositeHelpers::topRight, DrawableCompositeHelpers::pointToString (controlPoints[1]), 0); | |||||
v.setProperty (DrawableCompositeHelpers::bottomLeft, DrawableCompositeHelpers::pointToString (controlPoints[2]), 0); | |||||
const Marker* m = markers.getUnchecked(i); | |||||
v.setMarker (m->name, m->isOnXAxis, m->position, 0); | |||||
} | } | ||||
for (int i = 0; i < drawables.size(); ++i) | |||||
v.addChild (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); | |||||
return v; | |||||
return tree; | |||||
} | } | ||||
@@ -35,14 +35,17 @@ | |||||
@see Drawable | @see Drawable | ||||
*/ | */ | ||||
class JUCE_API DrawableComposite : public Drawable | |||||
class JUCE_API DrawableComposite : public Drawable, | |||||
public RelativeCoordinate::NamedCoordinateFinder | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
/** Creates a composite Drawable. | |||||
*/ | |||||
/** Creates a composite Drawable. */ | |||||
DrawableComposite(); | DrawableComposite(); | ||||
/** Creates a copy of a DrawableComposite. */ | |||||
DrawableComposite (const DrawableComposite& other); | |||||
/** Destructor. */ | /** Destructor. */ | ||||
virtual ~DrawableComposite(); | virtual ~DrawableComposite(); | ||||
@@ -122,27 +125,44 @@ public: | |||||
@param targetPositionForX0Y1 the position that the local coordinate (0, 1) should be | @param targetPositionForX0Y1 the position that the local coordinate (0, 1) should be | ||||
mapped onto when rendering this object. | mapped onto when rendering this object. | ||||
*/ | */ | ||||
void setTransform (const Point<float>& targetPositionForOrigin, | |||||
const Point<float>& targetPositionForX1Y0, | |||||
const Point<float>& targetPositionForX0Y1); | |||||
void setTransform (const RelativePoint& targetPositionForOrigin, | |||||
const RelativePoint& targetPositionForX1Y0, | |||||
const RelativePoint& targetPositionForX0Y1); | |||||
/** Returns the position to which the local coordinate (0, 0) should be remapped in the target | /** Returns the position to which the local coordinate (0, 0) should be remapped in the target | ||||
coordinate space when rendering this object. | coordinate space when rendering this object. | ||||
@see setTransform | @see setTransform | ||||
*/ | */ | ||||
const Point<float>& getTargetPositionForOrigin() const throw() { return controlPoints[0]; } | |||||
const RelativePoint& getTargetPositionForOrigin() const throw() { return controlPoints[0]; } | |||||
/** Returns the position to which the local coordinate (1, 0) should be remapped in the target | /** Returns the position to which the local coordinate (1, 0) should be remapped in the target | ||||
coordinate space when rendering this object. | coordinate space when rendering this object. | ||||
@see setTransform | @see setTransform | ||||
*/ | */ | ||||
const Point<float>& getTargetPositionForX1Y0() const throw() { return controlPoints[1]; } | |||||
const RelativePoint& getTargetPositionForX1Y0() const throw() { return controlPoints[1]; } | |||||
/** Returns the position to which the local coordinate (0, 1) should be remapped in the target | /** Returns the position to which the local coordinate (0, 1) should be remapped in the target | ||||
coordinate space when rendering this object. | coordinate space when rendering this object. | ||||
@see setTransform | @see setTransform | ||||
*/ | */ | ||||
const Point<float>& getTargetPositionForX0Y1() const throw() { return controlPoints[2]; } | |||||
const RelativePoint& getTargetPositionForX0Y1() const throw() { return controlPoints[2]; } | |||||
//============================================================================== | |||||
struct Marker | |||||
{ | |||||
Marker (const Marker&); | |||||
Marker (const String& name, const RelativeCoordinate& position, bool isOnXAxis); | |||||
bool operator!= (const Marker&) const throw(); | |||||
String name; | |||||
RelativeCoordinate position; | |||||
bool isOnXAxis; | |||||
}; | |||||
int getNumMarkers (bool xAxis) const throw(); | |||||
const Marker* getMarker (int index) const throw(); | |||||
void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position); | |||||
void removeMarker (int index); | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
@@ -152,12 +172,10 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
bool hitTest (float x, float y) const; | bool hitTest (float x, float y) const; | ||||
/** @internal */ | /** @internal */ | ||||
int getNumControlPoints() const; | |||||
/** @internal */ | |||||
const Point<float> getControlPoint (int index) const; | |||||
/** @internal */ | |||||
Drawable* createCopy() const; | Drawable* createCopy() const; | ||||
/** @internal */ | /** @internal */ | ||||
void invalidatePoints(); | |||||
/** @internal */ | |||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | ||||
/** @internal */ | /** @internal */ | ||||
const ValueTree createValueTree (ImageProvider* imageProvider) const; | const ValueTree createValueTree (ImageProvider* imageProvider) const; | ||||
@@ -165,18 +183,57 @@ public: | |||||
static const Identifier valueTreeType; | static const Identifier valueTreeType; | ||||
/** @internal */ | /** @internal */ | ||||
const Identifier getValueTreeType() const { return valueTreeType; } | const Identifier getValueTreeType() const { return valueTreeType; } | ||||
/** @internal */ | |||||
const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const; | |||||
//============================================================================== | |||||
/** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ | |||||
class ValueTreeWrapper : public ValueTreeWrapperBase | |||||
{ | |||||
public: | |||||
ValueTreeWrapper (const ValueTree& state); | |||||
int getNumDrawables() const; | |||||
const ValueTree getDrawableState (int index) const; | |||||
void addDrawable (const ValueTree& newDrawableState, int index, UndoManager* undoManager); | |||||
void moveDrawableOrder (int currentIndex, int newIndex, UndoManager* undoManager); | |||||
void removeDrawable (int index, UndoManager* undoManager); | |||||
const RelativePoint getTargetPositionForOrigin() const; | |||||
void setTargetPositionForOrigin (const RelativePoint& newPoint, UndoManager* undoManager); | |||||
const RelativePoint getTargetPositionForX1Y0() const; | |||||
void setTargetPositionForX1Y0 (const RelativePoint& newPoint, UndoManager* undoManager); | |||||
const RelativePoint getTargetPositionForX0Y1() const; | |||||
void setTargetPositionForX0Y1 (const RelativePoint& newPoint, UndoManager* undoManager); | |||||
int getNumMarkers() const; | |||||
const Marker getMarker (int index) const; | |||||
void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager); | |||||
void removeMarker (int index, UndoManager* undoManager); | |||||
private: | |||||
static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTag, | |||||
markerTag, nameProperty, xAxisProperty, posProperty; | |||||
ValueTree getChildList() const; | |||||
ValueTree getChildListCreating (UndoManager* undoManager); | |||||
ValueTree getMarkerList() const; | |||||
ValueTree getMarkerListCreating (UndoManager* undoManager); | |||||
}; | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
OwnedArray <Drawable> drawables; | OwnedArray <Drawable> drawables; | ||||
Point<float> controlPoints[3]; | |||||
RelativePoint controlPoints[3]; | |||||
OwnedArray <Marker> markers; | |||||
const Rectangle<float> getUntransformedBounds() const; | const Rectangle<float> getUntransformedBounds() const; | ||||
const AffineTransform getTransform() const; | |||||
const AffineTransform calculateTransform() const; | |||||
DrawableComposite (const DrawableComposite&); | |||||
DrawableComposite& operator= (const DrawableComposite&); | DrawableComposite& operator= (const DrawableComposite&); | ||||
}; | }; | ||||
@@ -27,8 +27,8 @@ | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
#include "juce_DrawableImage.h" | #include "juce_DrawableImage.h" | ||||
#include "juce_DrawableComposite.h" | |||||
#include "../imaging/juce_ImageCache.h" | #include "../imaging/juce_ImageCache.h" | ||||
@@ -39,47 +39,58 @@ DrawableImage::DrawableImage() | |||||
opacity (1.0f), | opacity (1.0f), | ||||
overlayColour (0x00000000) | overlayColour (0x00000000) | ||||
{ | { | ||||
controlPoints[1].setXY (1.0f, 0.0f); | |||||
controlPoints[2].setXY (0.0f, 1.0f); | |||||
controlPoints[1] = RelativePoint (Point<float> (1.0f, 0.0f)); | |||||
controlPoints[2] = RelativePoint (Point<float> (0.0f, 1.0f)); | |||||
} | } | ||||
DrawableImage::~DrawableImage() | |||||
DrawableImage::DrawableImage (const DrawableImage& other) | |||||
: image (0), | |||||
canDeleteImage (false), | |||||
opacity (other.opacity), | |||||
overlayColour (other.overlayColour) | |||||
{ | { | ||||
clearImage(); | |||||
for (int i = 0; i < numElementsInArray (controlPoints); ++i) | |||||
controlPoints[i] = other.controlPoints[i]; | |||||
if (other.image != 0) | |||||
{ | |||||
if ((! other.canDeleteImage) || ! ImageCache::isImageInCache (other.image)) | |||||
{ | |||||
setImage (*other.image); | |||||
} | |||||
else | |||||
{ | |||||
ImageCache::incReferenceCount (other.image); | |||||
setImage (other.image, true); | |||||
} | |||||
} | |||||
} | } | ||||
//============================================================================== | |||||
void DrawableImage::clearImage() | |||||
DrawableImage::~DrawableImage() | |||||
{ | { | ||||
if (canDeleteImage && image != 0) | |||||
ImageCache::releaseOrDelete (image); | |||||
image = 0; | |||||
setImage (0, false); | |||||
} | } | ||||
//============================================================================== | |||||
void DrawableImage::setImage (const Image& imageToCopy) | void DrawableImage::setImage (const Image& imageToCopy) | ||||
{ | { | ||||
clearImage(); | |||||
image = new Image (imageToCopy); | |||||
canDeleteImage = true; | |||||
controlPoints[0].setXY (0.0f, 0.0f); | |||||
controlPoints[1].setXY ((float) image->getWidth(), 0.0f); | |||||
controlPoints[2].setXY (0.0f, (float) image->getHeight()); | |||||
setImage (new Image (imageToCopy), true); | |||||
} | } | ||||
void DrawableImage::setImage (Image* imageToUse, | void DrawableImage::setImage (Image* imageToUse, | ||||
const bool releaseWhenNotNeeded) | const bool releaseWhenNotNeeded) | ||||
{ | { | ||||
clearImage(); | |||||
if (canDeleteImage) | |||||
ImageCache::releaseOrDelete (image); | |||||
image = imageToUse; | image = imageToUse; | ||||
canDeleteImage = releaseWhenNotNeeded; | canDeleteImage = releaseWhenNotNeeded; | ||||
if (image != 0) | if (image != 0) | ||||
{ | { | ||||
controlPoints[0].setXY (0.0f, 0.0f); | |||||
controlPoints[1].setXY ((float) image->getWidth(), 0.0f); | |||||
controlPoints[2].setXY (0.0f, (float) image->getHeight()); | |||||
controlPoints[0] = RelativePoint (Point<float> (0.0f, 0.0f)); | |||||
controlPoints[1] = RelativePoint (Point<float> ((float) image->getWidth(), 0.0f)); | |||||
controlPoints[2] = RelativePoint (Point<float> (0.0f, (float) image->getHeight())); | |||||
} | } | ||||
} | } | ||||
@@ -93,9 +104,9 @@ void DrawableImage::setOverlayColour (const Colour& newOverlayColour) | |||||
overlayColour = newOverlayColour; | overlayColour = newOverlayColour; | ||||
} | } | ||||
void DrawableImage::setTransform (const Point<float>& imageTopLeftPosition, | |||||
const Point<float>& imageTopRightPosition, | |||||
const Point<float>& imageBottomLeftPosition) | |||||
void DrawableImage::setTransform (const RelativePoint& imageTopLeftPosition, | |||||
const RelativePoint& imageTopRightPosition, | |||||
const RelativePoint& imageBottomLeftPosition) | |||||
{ | { | ||||
controlPoints[0] = imageTopLeftPosition; | controlPoints[0] = imageTopLeftPosition; | ||||
controlPoints[1] = imageTopRightPosition; | controlPoints[1] = imageTopRightPosition; | ||||
@@ -103,15 +114,19 @@ void DrawableImage::setTransform (const Point<float>& imageTopLeftPosition, | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
const AffineTransform DrawableImage::getTransform() const | |||||
const AffineTransform DrawableImage::calculateTransform() const | |||||
{ | { | ||||
if (image == 0) | if (image == 0) | ||||
return AffineTransform::identity; | return AffineTransform::identity; | ||||
const Point<float> tr (controlPoints[0] + (controlPoints[1] - controlPoints[0]) / (float) image->getWidth()); | |||||
const Point<float> bl (controlPoints[0] + (controlPoints[2] - controlPoints[0]) / (float) image->getHeight()); | |||||
Point<float> resolved[3]; | |||||
for (int i = 0; i < 3; ++i) | |||||
resolved[i] = controlPoints[i].resolve (parent); | |||||
return AffineTransform::fromTargetPoints (controlPoints[0].getX(), controlPoints[0].getY(), | |||||
const Point<float> tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image->getWidth()); | |||||
const Point<float> bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image->getHeight()); | |||||
return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), | |||||
tr.getX(), tr.getY(), | tr.getX(), tr.getY(), | ||||
bl.getX(), bl.getY()); | bl.getX(), bl.getY()); | ||||
} | } | ||||
@@ -120,7 +135,7 @@ void DrawableImage::render (const Drawable::RenderingContext& context) const | |||||
{ | { | ||||
if (image != 0) | if (image != 0) | ||||
{ | { | ||||
const AffineTransform t (getTransform().followedBy (context.transform)); | |||||
const AffineTransform t (calculateTransform().followedBy (context.transform)); | |||||
if (opacity > 0.0f && ! overlayColour.isOpaque()) | if (opacity > 0.0f && ! overlayColour.isOpaque()) | ||||
{ | { | ||||
@@ -141,7 +156,11 @@ const Rectangle<float> DrawableImage::getBounds() const | |||||
if (image == 0) | if (image == 0) | ||||
return Rectangle<float>(); | return Rectangle<float>(); | ||||
const Point<float> bottomRight (controlPoints[1] + (controlPoints[2] - controlPoints[0])); | |||||
Point<float> resolved[3]; | |||||
for (int i = 0; i < 3; ++i) | |||||
resolved[i] = controlPoints[i].resolve (parent); | |||||
const Point<float> bottomRight (resolved[1] + (resolved[2] - resolved[0])); | |||||
float minX = bottomRight.getX(); | float minX = bottomRight.getX(); | ||||
float maxX = minX; | float maxX = minX; | ||||
float minY = bottomRight.getY(); | float minY = bottomRight.getY(); | ||||
@@ -149,10 +168,10 @@ const Rectangle<float> DrawableImage::getBounds() const | |||||
for (int i = 0; i < 3; ++i) | for (int i = 0; i < 3; ++i) | ||||
{ | { | ||||
minX = jmin (minX, controlPoints[i].getX()); | |||||
maxX = jmax (maxX, controlPoints[i].getX()); | |||||
minY = jmin (minY, controlPoints[i].getY()); | |||||
maxY = jmax (maxY, controlPoints[i].getY()); | |||||
minX = jmin (minX, resolved[i].getX()); | |||||
maxX = jmax (maxX, resolved[i].getX()); | |||||
minY = jmin (minY, resolved[i].getY()); | |||||
maxY = jmax (maxY, resolved[i].getY()); | |||||
} | } | ||||
return Rectangle<float> (minX, minY, maxX - minX, maxY - minY); | return Rectangle<float> (minX, minY, maxX - minX, maxY - minY); | ||||
@@ -163,7 +182,7 @@ bool DrawableImage::hitTest (float x, float y) const | |||||
if (image == 0) | if (image == 0) | ||||
return false; | return false; | ||||
getTransform().inverted().transformPoint (x, y); | |||||
calculateTransform().inverted().transformPoint (x, y); | |||||
const int ix = roundToInt (x); | const int ix = roundToInt (x); | ||||
const int iy = roundToInt (y); | const int iy = roundToInt (y); | ||||
@@ -177,81 +196,117 @@ bool DrawableImage::hitTest (float x, float y) const | |||||
Drawable* DrawableImage::createCopy() const | Drawable* DrawableImage::createCopy() const | ||||
{ | { | ||||
DrawableImage* const di = new DrawableImage(); | |||||
return new DrawableImage (*this); | |||||
} | |||||
di->opacity = opacity; | |||||
di->overlayColour = overlayColour; | |||||
void DrawableImage::invalidatePoints() | |||||
{ | |||||
} | |||||
for (int i = 0; i < 4; ++i) | |||||
di->controlPoints[i] = controlPoints[i]; | |||||
//============================================================================== | |||||
const Identifier DrawableImage::valueTreeType ("Image"); | |||||
if (image != 0) | |||||
{ | |||||
if ((! canDeleteImage) || ! ImageCache::isImageInCache (image)) | |||||
{ | |||||
di->setImage (*image); | |||||
} | |||||
else | |||||
{ | |||||
ImageCache::incReferenceCount (image); | |||||
di->setImage (image, true); | |||||
} | |||||
} | |||||
const Identifier DrawableImage::ValueTreeWrapper::opacity ("opacity"); | |||||
const Identifier DrawableImage::ValueTreeWrapper::overlay ("overlay"); | |||||
const Identifier DrawableImage::ValueTreeWrapper::image ("image"); | |||||
const Identifier DrawableImage::ValueTreeWrapper::topLeft ("topLeft"); | |||||
const Identifier DrawableImage::ValueTreeWrapper::topRight ("topRight"); | |||||
const Identifier DrawableImage::ValueTreeWrapper::bottomLeft ("bottomLeft"); | |||||
return di; | |||||
//============================================================================== | |||||
DrawableImage::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) | |||||
: ValueTreeWrapperBase (state_) | |||||
{ | |||||
jassert (state.hasType (valueTreeType)); | |||||
} | } | ||||
//============================================================================== | |||||
const Identifier DrawableImage::valueTreeType ("Image"); | |||||
const var DrawableImage::ValueTreeWrapper::getImageIdentifier() const | |||||
{ | |||||
return state [image]; | |||||
} | |||||
namespace DrawableImageHelpers | |||||
void DrawableImage::ValueTreeWrapper::setImageIdentifier (const var& newIdentifier, UndoManager* undoManager) | |||||
{ | { | ||||
static const Identifier opacity ("opacity"); | |||||
static const Identifier overlay ("overlay"); | |||||
static const Identifier image ("image"); | |||||
static const Identifier topLeft ("topLeft"); | |||||
static const Identifier topRight ("topRight"); | |||||
static const Identifier bottomLeft ("bottomLeft"); | |||||
static void stringToPoint (const String& coords, Point<float>& point) | |||||
{ | |||||
if (coords.isNotEmpty()) | |||||
{ | |||||
const int comma = coords.indexOfChar (','); | |||||
point.setXY (coords.substring (0, comma).getFloatValue(), | |||||
coords.substring (comma + 1).getFloatValue()); | |||||
} | |||||
} | |||||
state.setProperty (image, newIdentifier, undoManager); | |||||
} | |||||
static const var pointToString (const Point<float>& point) | |||||
{ | |||||
return String (point.getX()) + ", " + String (point.getY()); | |||||
} | |||||
float DrawableImage::ValueTreeWrapper::getOpacity() const | |||||
{ | |||||
return (float) state.getProperty (opacity, 1.0); | |||||
} | } | ||||
const Rectangle<float> DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | |||||
void DrawableImage::ValueTreeWrapper::setOpacity (float newOpacity, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (opacity, newOpacity, undoManager); | |||||
} | |||||
const Colour DrawableImage::ValueTreeWrapper::getOverlayColour() const | |||||
{ | |||||
return Colour (state [overlay].toString().getHexValue32()); | |||||
} | |||||
void DrawableImage::ValueTreeWrapper::setOverlayColour (const Colour& newColour, UndoManager* undoManager) | |||||
{ | |||||
if (newColour.isTransparent()) | |||||
state.removeProperty (overlay, undoManager); | |||||
else | |||||
state.setProperty (overlay, String::toHexString ((int) newColour.getARGB()), undoManager); | |||||
} | |||||
const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForTopLeft() const | |||||
{ | |||||
const String pos (state [topLeft].toString()); | |||||
return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint(); | |||||
} | |||||
void DrawableImage::ValueTreeWrapper::setTargetPositionForTopLeft (const RelativePoint& newPoint, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (topLeft, newPoint.toString(), undoManager); | |||||
} | |||||
const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForTopRight() const | |||||
{ | |||||
const String pos (state [topRight].toString()); | |||||
return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point<float> (100.0f, 0.0f)); | |||||
} | |||||
void DrawableImage::ValueTreeWrapper::setTargetPositionForTopRight (const RelativePoint& newPoint, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (topRight, newPoint.toString(), undoManager); | |||||
} | |||||
const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForBottomLeft() const | |||||
{ | |||||
const String pos (state [bottomLeft].toString()); | |||||
return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point<float> (0.0f, 100.0f)); | |||||
} | |||||
void DrawableImage::ValueTreeWrapper::setTargetPositionForBottomLeft (const RelativePoint& newPoint, UndoManager* undoManager) | |||||
{ | { | ||||
jassert (tree.hasType (valueTreeType)); | |||||
state.setProperty (bottomLeft, newPoint.toString(), undoManager); | |||||
} | |||||
setName (tree [idProperty]); | |||||
//============================================================================== | |||||
const Rectangle<float> DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | |||||
{ | |||||
const ValueTreeWrapper controller (tree); | |||||
setName (controller.getID()); | |||||
const float newOpacity = tree.getProperty (DrawableImageHelpers::opacity, 1.0); | |||||
const Colour newOverlayColour (tree [DrawableImageHelpers::overlay].toString().getHexValue32()); | |||||
const float newOpacity = controller.getOpacity(); | |||||
const Colour newOverlayColour (controller.getOverlayColour()); | |||||
Image* newImage = 0; | Image* newImage = 0; | ||||
const String imageIdentifier (tree [DrawableImageHelpers::image].toString()); | |||||
if (imageIdentifier.isNotEmpty()) | |||||
{ | |||||
jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them! | |||||
const var imageIdentifier (controller.getImageIdentifier()); | |||||
if (imageProvider != 0) | |||||
newImage = imageProvider->getImageForIdentifier (imageIdentifier); | |||||
} | |||||
jassert (imageProvider != 0 || imageIdentifier.isVoid()); // if you're using images, you need to provide something that can load and save them! | |||||
if (imageProvider != 0) | |||||
newImage = imageProvider->getImageForIdentifier (imageIdentifier); | |||||
Point<float> newControlPoint[3]; | |||||
DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::topLeft].toString(), newControlPoint[0]); | |||||
DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::topRight].toString(), newControlPoint[1]); | |||||
DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::bottomLeft].toString(), newControlPoint[2]); | |||||
RelativePoint newControlPoint[3] = { controller.getTargetPositionForTopLeft(), | |||||
controller.getTargetPositionForTopRight(), | |||||
controller.getTargetPositionForBottomLeft() }; | |||||
if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage | if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage | ||||
|| controlPoints[0] != newControlPoint[0] | || controlPoints[0] != newControlPoint[0] | ||||
@@ -266,7 +321,10 @@ const Rectangle<float> DrawableImage::refreshFromValueTree (const ValueTree& tre | |||||
if (image != newImage) | if (image != newImage) | ||||
{ | { | ||||
ImageCache::release (image); | |||||
if (canDeleteImage) | |||||
ImageCache::releaseOrDelete (image); | |||||
canDeleteImage = true; | |||||
image = newImage; | image = newImage; | ||||
} | } | ||||
@@ -279,33 +337,25 @@ const Rectangle<float> DrawableImage::refreshFromValueTree (const ValueTree& tre | |||||
const ValueTree DrawableImage::createValueTree (ImageProvider* imageProvider) const | const ValueTree DrawableImage::createValueTree (ImageProvider* imageProvider) const | ||||
{ | { | ||||
ValueTree v (valueTreeType); | |||||
ValueTree tree (valueTreeType); | |||||
ValueTreeWrapper v (tree); | |||||
if (getName().isNotEmpty()) | |||||
v.setProperty (idProperty, getName(), 0); | |||||
if (opacity < 1.0f) | |||||
v.setProperty (DrawableImageHelpers::opacity, (double) opacity, 0); | |||||
if (! overlayColour.isTransparent()) | |||||
v.setProperty (DrawableImageHelpers::overlay, String::toHexString ((int) overlayColour.getARGB()), 0); | |||||
if (! getTransform().isIdentity()) | |||||
{ | |||||
v.setProperty (DrawableImageHelpers::topLeft, DrawableImageHelpers::pointToString (controlPoints[0]), 0); | |||||
v.setProperty (DrawableImageHelpers::topRight, DrawableImageHelpers::pointToString (controlPoints[1]), 0); | |||||
v.setProperty (DrawableImageHelpers::bottomLeft, DrawableImageHelpers::pointToString (controlPoints[2]), 0); | |||||
} | |||||
v.setID (getName(), 0); | |||||
v.setOpacity (opacity, 0); | |||||
v.setOverlayColour (overlayColour, 0); | |||||
v.setTargetPositionForTopLeft (controlPoints[0], 0); | |||||
v.setTargetPositionForTopRight (controlPoints[1], 0); | |||||
v.setTargetPositionForBottomLeft (controlPoints[2], 0); | |||||
if (image != 0) | if (image != 0) | ||||
{ | { | ||||
jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them! | jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them! | ||||
if (imageProvider != 0) | if (imageProvider != 0) | ||||
v.setProperty (DrawableImageHelpers::image, imageProvider->getIdentifierForImage (image), 0); | |||||
v.setImageIdentifier (imageProvider->getIdentifierForImage (image), 0); | |||||
} | } | ||||
return v; | |||||
return tree; | |||||
} | } | ||||
@@ -40,6 +40,7 @@ class JUCE_API DrawableImage : public Drawable | |||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
DrawableImage(); | DrawableImage(); | ||||
DrawableImage (const DrawableImage& other); | |||||
/** Destructor. */ | /** Destructor. */ | ||||
virtual ~DrawableImage(); | virtual ~DrawableImage(); | ||||
@@ -59,7 +60,7 @@ public: | |||||
with ImageCache and pass it in here with releaseWhenNotNeeded = true, then | with ImageCache and pass it in here with releaseWhenNotNeeded = true, then | ||||
it'll be released neatly with its reference count being decreased. | it'll be released neatly with its reference count being decreased. | ||||
@param imageToUse the image to render | |||||
@param imageToUse the image to render (may be a null pointer) | |||||
@param releaseWhenNotNeeded if false, a simple pointer is kept to the image; if true, | @param releaseWhenNotNeeded if false, a simple pointer is kept to the image; if true, | ||||
then the image will be deleted when this object no longer | then the image will be deleted when this object no longer | ||||
needs it - unless the image was created by the ImageCache, | needs it - unless the image was created by the ImageCache, | ||||
@@ -70,9 +71,6 @@ public: | |||||
/** Returns the current image. */ | /** Returns the current image. */ | ||||
Image* getImage() const throw() { return image; } | Image* getImage() const throw() { return image; } | ||||
/** Clears (and possibly deletes) the currently set image. */ | |||||
void clearImage(); | |||||
/** Sets the opacity to use when drawing the image. */ | /** Sets the opacity to use when drawing the image. */ | ||||
void setOpacity (float newOpacity); | void setOpacity (float newOpacity); | ||||
@@ -103,27 +101,27 @@ public: | |||||
@param imageBottomLeftPosition the position that the image's bottom-left corner should be mapped to | @param imageBottomLeftPosition the position that the image's bottom-left corner should be mapped to | ||||
in the target coordinate space. | in the target coordinate space. | ||||
*/ | */ | ||||
void setTransform (const Point<float>& imageTopLeftPosition, | |||||
const Point<float>& imageTopRightPosition, | |||||
const Point<float>& imageBottomLeftPosition); | |||||
void setTransform (const RelativePoint& imageTopLeftPosition, | |||||
const RelativePoint& imageTopRightPosition, | |||||
const RelativePoint& imageBottomLeftPosition); | |||||
/** Returns the position to which the image's top-left corner should be remapped in the target | /** Returns the position to which the image's top-left corner should be remapped in the target | ||||
coordinate space when rendering this object. | coordinate space when rendering this object. | ||||
@see setTransform | @see setTransform | ||||
*/ | */ | ||||
const Point<float>& getTargetPositionForTopLeft() const throw() { return controlPoints[0]; } | |||||
const RelativePoint& getTargetPositionForTopLeft() const throw() { return controlPoints[0]; } | |||||
/** Returns the position to which the image's top-right corner should be remapped in the target | /** Returns the position to which the image's top-right corner should be remapped in the target | ||||
coordinate space when rendering this object. | coordinate space when rendering this object. | ||||
@see setTransform | @see setTransform | ||||
*/ | */ | ||||
const Point<float>& getTargetPositionForTopRight() const throw() { return controlPoints[1]; } | |||||
const RelativePoint& getTargetPositionForTopRight() const throw() { return controlPoints[1]; } | |||||
/** Returns the position to which the image's bottom-left corner should be remapped in the target | /** Returns the position to which the image's bottom-left corner should be remapped in the target | ||||
coordinate space when rendering this object. | coordinate space when rendering this object. | ||||
@see setTransform | @see setTransform | ||||
*/ | */ | ||||
const Point<float>& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; } | |||||
const RelativePoint& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; } | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
@@ -135,6 +133,8 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
Drawable* createCopy() const; | Drawable* createCopy() const; | ||||
/** @internal */ | /** @internal */ | ||||
void invalidatePoints(); | |||||
/** @internal */ | |||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | ||||
/** @internal */ | /** @internal */ | ||||
const ValueTree createValueTree (ImageProvider* imageProvider) const; | const ValueTree createValueTree (ImageProvider* imageProvider) const; | ||||
@@ -143,6 +143,35 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
const Identifier getValueTreeType() const { return valueTreeType; } | const Identifier getValueTreeType() const { return valueTreeType; } | ||||
//============================================================================== | |||||
/** Internally-used class for wrapping a DrawableImage's state into a ValueTree. */ | |||||
class ValueTreeWrapper : public ValueTreeWrapperBase | |||||
{ | |||||
public: | |||||
ValueTreeWrapper (const ValueTree& state); | |||||
const var getImageIdentifier() const; | |||||
void setImageIdentifier (const var& newIdentifier, UndoManager* undoManager); | |||||
float getOpacity() const; | |||||
void setOpacity (float newOpacity, UndoManager* undoManager); | |||||
const Colour getOverlayColour() const; | |||||
void setOverlayColour (const Colour& newColour, UndoManager* undoManager); | |||||
const RelativePoint getTargetPositionForTopLeft() const; | |||||
void setTargetPositionForTopLeft (const RelativePoint& newPoint, UndoManager* undoManager); | |||||
const RelativePoint getTargetPositionForTopRight() const; | |||||
void setTargetPositionForTopRight (const RelativePoint& newPoint, UndoManager* undoManager); | |||||
const RelativePoint getTargetPositionForBottomLeft() const; | |||||
void setTargetPositionForBottomLeft (const RelativePoint& newPoint, UndoManager* undoManager); | |||||
private: | |||||
static const Identifier opacity, overlay, image, topLeft, topRight, bottomLeft; | |||||
}; | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
@@ -151,11 +180,10 @@ private: | |||||
bool canDeleteImage; | bool canDeleteImage; | ||||
float opacity; | float opacity; | ||||
Colour overlayColour; | Colour overlayColour; | ||||
Point<float> controlPoints[3]; | |||||
RelativePoint controlPoints[3]; | |||||
const AffineTransform getTransform() const; | |||||
const AffineTransform calculateTransform() const; | |||||
DrawableImage (const DrawableImage&); | |||||
DrawableImage& operator= (const DrawableImage&); | DrawableImage& operator= (const DrawableImage&); | ||||
}; | }; | ||||
@@ -28,6 +28,7 @@ | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
#include "juce_DrawablePath.h" | #include "juce_DrawablePath.h" | ||||
#include "juce_DrawableComposite.h" | |||||
#include "../../../io/streams/juce_MemoryOutputStream.h" | #include "../../../io/streams/juce_MemoryOutputStream.h" | ||||
@@ -35,10 +36,25 @@ BEGIN_JUCE_NAMESPACE | |||||
DrawablePath::DrawablePath() | DrawablePath::DrawablePath() | ||||
: mainFill (Colours::black), | : mainFill (Colours::black), | ||||
strokeFill (Colours::transparentBlack), | strokeFill (Colours::transparentBlack), | ||||
strokeType (0.0f) | |||||
strokeType (0.0f), | |||||
pathNeedsUpdating (true), | |||||
strokeNeedsUpdating (true) | |||||
{ | { | ||||
} | } | ||||
DrawablePath::DrawablePath (const DrawablePath& other) | |||||
: mainFill (other.mainFill), | |||||
strokeFill (other.strokeFill), | |||||
strokeType (other.strokeType), | |||||
pathNeedsUpdating (true), | |||||
strokeNeedsUpdating (true) | |||||
{ | |||||
if (other.relativePath != 0) | |||||
relativePath = new RelativePointPath (*other.relativePath); | |||||
else | |||||
path = other.path; | |||||
} | |||||
DrawablePath::~DrawablePath() | DrawablePath::~DrawablePath() | ||||
{ | { | ||||
} | } | ||||
@@ -47,7 +63,7 @@ DrawablePath::~DrawablePath() | |||||
void DrawablePath::setPath (const Path& newPath) | void DrawablePath::setPath (const Path& newPath) | ||||
{ | { | ||||
path = newPath; | path = newPath; | ||||
updateOutline(); | |||||
strokeNeedsUpdating = true; | |||||
} | } | ||||
void DrawablePath::setFill (const FillType& newFill) | void DrawablePath::setFill (const FillType& newFill) | ||||
@@ -63,7 +79,7 @@ void DrawablePath::setStrokeFill (const FillType& newFill) | |||||
void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) | void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) | ||||
{ | { | ||||
strokeType = newStrokeType; | strokeType = newStrokeType; | ||||
updateOutline(); | |||||
strokeNeedsUpdating = true; | |||||
} | } | ||||
void DrawablePath::setStrokeThickness (const float newThickness) | void DrawablePath::setStrokeThickness (const float newThickness) | ||||
@@ -71,6 +87,55 @@ void DrawablePath::setStrokeThickness (const float newThickness) | |||||
setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); | setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); | ||||
} | } | ||||
void DrawablePath::updatePath() const | |||||
{ | |||||
if (pathNeedsUpdating) | |||||
{ | |||||
pathNeedsUpdating = false; | |||||
if (relativePath != 0) | |||||
{ | |||||
path.clear(); | |||||
relativePath->createPath (path, parent); | |||||
strokeNeedsUpdating = true; | |||||
} | |||||
} | |||||
} | |||||
void DrawablePath::updateStroke() const | |||||
{ | |||||
if (strokeNeedsUpdating) | |||||
{ | |||||
strokeNeedsUpdating = false; | |||||
updatePath(); | |||||
stroke.clear(); | |||||
strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); | |||||
} | |||||
} | |||||
const Path& DrawablePath::getPath() const | |||||
{ | |||||
updatePath(); | |||||
return path; | |||||
} | |||||
const Path& DrawablePath::getStrokePath() const | |||||
{ | |||||
updateStroke(); | |||||
return stroke; | |||||
} | |||||
bool DrawablePath::isStrokeVisible() const throw() | |||||
{ | |||||
return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); | |||||
} | |||||
void DrawablePath::invalidatePoints() | |||||
{ | |||||
pathNeedsUpdating = true; | |||||
strokeNeedsUpdating = true; | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
void DrawablePath::render (const Drawable::RenderingContext& context) const | void DrawablePath::render (const Drawable::RenderingContext& context) const | ||||
{ | { | ||||
@@ -81,10 +146,10 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const | |||||
f.transform = f.transform.followedBy (context.transform); | f.transform = f.transform.followedBy (context.transform); | ||||
context.g.setFillType (f); | context.g.setFillType (f); | ||||
context.g.fillPath (path, context.transform); | |||||
context.g.fillPath (getPath(), context.transform); | |||||
} | } | ||||
if (strokeType.getStrokeThickness() > 0.0f) | |||||
if (isStrokeVisible()) | |||||
{ | { | ||||
FillType f (strokeFill); | FillType f (strokeFill); | ||||
if (f.isGradient()) | if (f.isGradient()) | ||||
@@ -92,162 +157,133 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const | |||||
f.transform = f.transform.followedBy (context.transform); | f.transform = f.transform.followedBy (context.transform); | ||||
context.g.setFillType (f); | context.g.setFillType (f); | ||||
context.g.fillPath (stroke, context.transform); | |||||
context.g.fillPath (getStrokePath(), context.transform); | |||||
} | } | ||||
} | } | ||||
void DrawablePath::updateOutline() | |||||
{ | |||||
stroke.clear(); | |||||
strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); | |||||
} | |||||
const Rectangle<float> DrawablePath::getBounds() const | const Rectangle<float> DrawablePath::getBounds() const | ||||
{ | { | ||||
if (strokeType.getStrokeThickness() > 0.0f) | |||||
return stroke.getBounds(); | |||||
if (isStrokeVisible()) | |||||
return getStrokePath().getBounds(); | |||||
else | else | ||||
return path.getBounds(); | |||||
return getPath().getBounds(); | |||||
} | } | ||||
bool DrawablePath::hitTest (float x, float y) const | bool DrawablePath::hitTest (float x, float y) const | ||||
{ | { | ||||
return path.contains (x, y) | |||||
|| stroke.contains (x, y); | |||||
return getPath().contains (x, y) | |||||
|| (isStrokeVisible() && getStrokePath().contains (x, y)); | |||||
} | } | ||||
Drawable* DrawablePath::createCopy() const | Drawable* DrawablePath::createCopy() const | ||||
{ | { | ||||
DrawablePath* const dp = new DrawablePath(); | |||||
dp->path = path; | |||||
dp->stroke = stroke; | |||||
dp->mainFill = mainFill; | |||||
dp->strokeFill = strokeFill; | |||||
dp->strokeType = strokeType; | |||||
return dp; | |||||
return new DrawablePath (*this); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
const Identifier DrawablePath::valueTreeType ("Path"); | const Identifier DrawablePath::valueTreeType ("Path"); | ||||
namespace DrawablePathHelpers | |||||
{ | |||||
static const Identifier type ("type"); | |||||
static const Identifier solid ("solid"); | |||||
static const Identifier colour ("colour"); | |||||
static const Identifier gradient ("gradient"); | |||||
static const Identifier x1 ("x1"); | |||||
static const Identifier x2 ("x2"); | |||||
static const Identifier y1 ("y1"); | |||||
static const Identifier y2 ("y2"); | |||||
static const Identifier radial ("radial"); | |||||
static const Identifier colours ("colours"); | |||||
static const Identifier fill ("fill"); | |||||
static const Identifier stroke ("stroke"); | |||||
static const Identifier jointStyle ("jointStyle"); | |||||
static const Identifier capStyle ("capStyle"); | |||||
static const Identifier strokeWidth ("strokeWidth"); | |||||
static const Identifier path ("path"); | |||||
static bool updateFillType (const ValueTree& v, FillType& fillType) | |||||
{ | |||||
const String type (v[type].toString()); | |||||
if (type.equalsIgnoreCase (solid)) | |||||
{ | |||||
const String colourString (v [colour].toString()); | |||||
const Colour newColour (colourString.isEmpty() ? (uint32) 0xff000000 | |||||
: (uint32) colourString.getHexValue32()); | |||||
if (fillType.isColour() && fillType.colour == newColour) | |||||
return false; | |||||
const Identifier DrawablePath::ValueTreeWrapper::fill ("fill"); | |||||
const Identifier DrawablePath::ValueTreeWrapper::stroke ("stroke"); | |||||
const Identifier DrawablePath::ValueTreeWrapper::jointStyle ("jointStyle"); | |||||
const Identifier DrawablePath::ValueTreeWrapper::capStyle ("capStyle"); | |||||
const Identifier DrawablePath::ValueTreeWrapper::strokeWidth ("strokeWidth"); | |||||
const Identifier DrawablePath::ValueTreeWrapper::path ("path"); | |||||
fillType.setColour (newColour); | |||||
return true; | |||||
} | |||||
else if (type.equalsIgnoreCase (gradient)) | |||||
{ | |||||
ColourGradient g; | |||||
g.point1.setXY (v[x1], v[y1]); | |||||
g.point2.setXY (v[x2], v[y2]); | |||||
g.isRadial = v[radial]; | |||||
//============================================================================== | |||||
DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) | |||||
: ValueTreeWrapperBase (state_) | |||||
{ | |||||
jassert (state.hasType (valueTreeType)); | |||||
} | |||||
StringArray colourSteps; | |||||
colourSteps.addTokens (v[colours].toString(), false); | |||||
const FillType DrawablePath::ValueTreeWrapper::getMainFill() const | |||||
{ | |||||
return readFillType (state.getChildWithName (fill)); | |||||
} | |||||
for (int i = 0; i < colourSteps.size() / 2; ++i) | |||||
g.addColour (colourSteps[i * 2].getDoubleValue(), | |||||
Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); | |||||
void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, UndoManager* undoManager) | |||||
{ | |||||
replaceFillType (fill, newFill, undoManager); | |||||
} | |||||
if (fillType.isGradient() && *fillType.gradient == g) | |||||
return false; | |||||
const FillType DrawablePath::ValueTreeWrapper::getStrokeFill() const | |||||
{ | |||||
return readFillType (state.getChildWithName (stroke)); | |||||
} | |||||
fillType.setGradient (g); | |||||
return true; | |||||
} | |||||
void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, UndoManager* undoManager) | |||||
{ | |||||
replaceFillType (stroke, newFill, undoManager); | |||||
} | |||||
jassertfalse; | |||||
return false; | |||||
} | |||||
const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const | |||||
{ | |||||
const String jointStyleString (state [jointStyle].toString()); | |||||
const String capStyleString (state [capStyle].toString()); | |||||
return PathStrokeType (state [strokeWidth], | |||||
jointStyleString == "curved" ? PathStrokeType::curved | |||||
: (jointStyleString == "bevel" ? PathStrokeType::beveled | |||||
: PathStrokeType::mitered), | |||||
capStyleString == "square" ? PathStrokeType::square | |||||
: (capStyleString == "round" ? PathStrokeType::rounded | |||||
: PathStrokeType::butt)); | |||||
} | |||||
static ValueTree createFillType (const Identifier& tagName, const FillType& fillType) | |||||
{ | |||||
ValueTree v (tagName); | |||||
void DrawablePath::ValueTreeWrapper::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); | |||||
state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered | |||||
? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); | |||||
state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt | |||||
? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); | |||||
} | |||||
if (fillType.isColour()) | |||||
{ | |||||
v.setProperty (type, "solid", 0); | |||||
v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), 0); | |||||
} | |||||
else if (fillType.isGradient()) | |||||
{ | |||||
v.setProperty (type, "gradient", 0); | |||||
v.setProperty (x1, fillType.gradient->point1.getX(), 0); | |||||
v.setProperty (y1, fillType.gradient->point1.getY(), 0); | |||||
v.setProperty (x2, fillType.gradient->point2.getX(), 0); | |||||
v.setProperty (y2, fillType.gradient->point2.getY(), 0); | |||||
v.setProperty (radial, fillType.gradient->isRadial, 0); | |||||
String s; | |||||
for (int i = 0; i < fillType.gradient->getNumColours(); ++i) | |||||
s << " " << fillType.gradient->getColourPosition (i) | |||||
<< " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); | |||||
v.setProperty (colours, s.trimStart(), 0); | |||||
} | |||||
else | |||||
{ | |||||
jassertfalse; //xxx | |||||
} | |||||
void DrawablePath::ValueTreeWrapper::getPath (RelativePointPath& p) const | |||||
{ | |||||
RelativePointPath newPath (state [path]); | |||||
p.swapWith (newPath); | |||||
} | |||||
return v; | |||||
} | |||||
void DrawablePath::ValueTreeWrapper::setPath (const String& newPath, UndoManager* undoManager) | |||||
{ | |||||
state.setProperty (path, newPath, undoManager); | |||||
} | } | ||||
const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | ||||
{ | { | ||||
jassert (tree.hasType (valueTreeType)); | |||||
Rectangle<float> damageRect; | Rectangle<float> damageRect; | ||||
setName (tree [idProperty]); | |||||
ValueTreeWrapper v (tree); | |||||
setName (v.getID()); | |||||
bool needsRedraw = false; | |||||
const FillType newFill (v.getMainFill()); | |||||
if (mainFill != newFill) | |||||
{ | |||||
needsRedraw = true; | |||||
mainFill = newFill; | |||||
} | |||||
const FillType newStrokeFill (v.getStrokeFill()); | |||||
bool needsRedraw = DrawablePathHelpers::updateFillType (tree.getChildWithName (DrawablePathHelpers::fill), mainFill); | |||||
needsRedraw = DrawablePathHelpers::updateFillType (tree.getChildWithName (DrawablePathHelpers::stroke), strokeFill) || needsRedraw; | |||||
if (strokeFill != newStrokeFill) | |||||
{ | |||||
needsRedraw = true; | |||||
strokeFill = newStrokeFill; | |||||
} | |||||
const String jointStyle (tree [DrawablePathHelpers::jointStyle].toString()); | |||||
const String endStyle (tree [DrawablePathHelpers::capStyle].toString()); | |||||
const PathStrokeType newStroke (v.getStrokeType()); | |||||
PathStrokeType newStroke (tree [DrawablePathHelpers::strokeWidth], | |||||
jointStyle == "curved" ? PathStrokeType::curved | |||||
: (jointStyle == "bevel" ? PathStrokeType::beveled | |||||
: PathStrokeType::mitered), | |||||
endStyle == "square" ? PathStrokeType::square | |||||
: (endStyle == "round" ? PathStrokeType::rounded | |||||
: PathStrokeType::butt)); | |||||
ScopedPointer<RelativePointPath> newRelativePath (new RelativePointPath()); | |||||
v.getPath (*newRelativePath); | |||||
Path newPath; | Path newPath; | ||||
newPath.restoreFromString (tree [DrawablePathHelpers::path]); | |||||
newRelativePath->createPath (newPath, parent); | |||||
if (! newRelativePath->containsAnyDynamicPoints()) | |||||
newRelativePath = 0; | |||||
if (strokeType != newStroke || path != newPath) | if (strokeType != newStroke || path != newPath) | ||||
{ | { | ||||
@@ -257,6 +293,8 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree | |||||
needsRedraw = true; | needsRedraw = true; | ||||
} | } | ||||
relativePath = newRelativePath.release(); | |||||
if (needsRedraw) | if (needsRedraw) | ||||
damageRect = damageRect.getUnion (getBounds()); | damageRect = damageRect.getUnion (getBounds()); | ||||
@@ -265,22 +303,20 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree | |||||
const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) const | const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) const | ||||
{ | { | ||||
ValueTree v (valueTreeType); | |||||
ValueTree tree (valueTreeType); | |||||
ValueTreeWrapper v (tree); | |||||
v.addChild (DrawablePathHelpers::createFillType (DrawablePathHelpers::fill, mainFill), -1, 0); | |||||
v.addChild (DrawablePathHelpers::createFillType (DrawablePathHelpers::stroke, strokeFill), -1, 0); | |||||
v.setID (getName(), 0); | |||||
v.setMainFill (mainFill, 0); | |||||
v.setStrokeFill (strokeFill, 0); | |||||
v.setStrokeType (strokeType, 0); | |||||
if (getName().isNotEmpty()) | |||||
v.setProperty (idProperty, getName(), 0); | |||||
v.setProperty (DrawablePathHelpers::strokeWidth, (double) strokeType.getStrokeThickness(), 0); | |||||
v.setProperty (DrawablePathHelpers::jointStyle, strokeType.getJointStyle() == PathStrokeType::mitered | |||||
? "miter" : (strokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), 0); | |||||
v.setProperty (DrawablePathHelpers::capStyle, strokeType.getEndStyle() == PathStrokeType::butt | |||||
? "butt" : (strokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), 0); | |||||
v.setProperty (DrawablePathHelpers::path, path.toString(), 0); | |||||
if (relativePath != 0) | |||||
v.setPath (relativePath->toString(), 0); | |||||
else | |||||
v.setPath (path.toString(), 0); | |||||
return v; | |||||
return tree; | |||||
} | } | ||||
@@ -40,9 +40,9 @@ class JUCE_API DrawablePath : public Drawable | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
/** Creates a DrawablePath. | |||||
*/ | |||||
/** Creates a DrawablePath. */ | |||||
DrawablePath(); | DrawablePath(); | ||||
DrawablePath (const DrawablePath& other); | |||||
/** Destructor. */ | /** Destructor. */ | ||||
virtual ~DrawablePath(); | virtual ~DrawablePath(); | ||||
@@ -54,9 +54,6 @@ public: | |||||
*/ | */ | ||||
void setPath (const Path& newPath); | void setPath (const Path& newPath); | ||||
/** Returns the current path. */ | |||||
const Path& getPath() const throw() { return path; } | |||||
/** Sets a fill type for the path. | /** Sets a fill type for the path. | ||||
This colour is used to fill the path - if you don't want the path to be | This colour is used to fill the path - if you don't want the path to be | ||||
@@ -97,6 +94,13 @@ public: | |||||
const PathStrokeType& getStrokeType() const throw() { return strokeType; } | const PathStrokeType& getStrokeType() const throw() { return strokeType; } | ||||
//============================================================================== | |||||
/** Returns the current path. */ | |||||
const Path& getPath() const; | |||||
/** Returns the current path for the outline. */ | |||||
const Path& getStrokePath() const; | |||||
//============================================================================== | //============================================================================== | ||||
/** @internal */ | /** @internal */ | ||||
void render (const Drawable::RenderingContext& context) const; | void render (const Drawable::RenderingContext& context) const; | ||||
@@ -107,6 +111,8 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
Drawable* createCopy() const; | Drawable* createCopy() const; | ||||
/** @internal */ | /** @internal */ | ||||
void invalidatePoints(); | |||||
/** @internal */ | |||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | ||||
/** @internal */ | /** @internal */ | ||||
const ValueTree createValueTree (ImageProvider* imageProvider) const; | const ValueTree createValueTree (ImageProvider* imageProvider) const; | ||||
@@ -115,17 +121,43 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
const Identifier getValueTreeType() const { return valueTreeType; } | const Identifier getValueTreeType() const { return valueTreeType; } | ||||
//============================================================================== | |||||
/** Internally-used class for wrapping a DrawablePath's state into a ValueTree. */ | |||||
class ValueTreeWrapper : public ValueTreeWrapperBase | |||||
{ | |||||
public: | |||||
ValueTreeWrapper (const ValueTree& state); | |||||
const FillType getMainFill() const; | |||||
void setMainFill (const FillType& newFill, UndoManager* undoManager); | |||||
const FillType getStrokeFill() const; | |||||
void setStrokeFill (const FillType& newFill, UndoManager* undoManager); | |||||
const PathStrokeType getStrokeType() const; | |||||
void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); | |||||
void getPath (RelativePointPath& path) const; | |||||
void setPath (const String& newPath, UndoManager* undoManager); | |||||
private: | |||||
static const Identifier fill, stroke, jointStyle, capStyle, strokeWidth, path; | |||||
}; | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
Path path, stroke; | |||||
FillType mainFill, strokeFill; | FillType mainFill, strokeFill; | ||||
PathStrokeType strokeType; | PathStrokeType strokeType; | ||||
ScopedPointer<RelativePointPath> relativePath; | |||||
mutable Path path, stroke; | |||||
mutable bool pathNeedsUpdating, strokeNeedsUpdating; | |||||
void updateOutline(); | |||||
void updatePath() const; | |||||
void updateStroke() const; | |||||
bool isStrokeVisible() const throw(); | |||||
DrawablePath (const DrawablePath&); | |||||
DrawablePath& operator= (const DrawablePath&); | DrawablePath& operator= (const DrawablePath&); | ||||
}; | }; | ||||
@@ -36,6 +36,12 @@ DrawableText::DrawableText() | |||||
{ | { | ||||
} | } | ||||
DrawableText::DrawableText (const DrawableText& other) | |||||
: text (other.text), | |||||
colour (other.colour) | |||||
{ | |||||
} | |||||
DrawableText::~DrawableText() | DrawableText::~DrawableText() | ||||
{ | { | ||||
} | } | ||||
@@ -76,21 +82,28 @@ bool DrawableText::hitTest (float x, float y) const | |||||
Drawable* DrawableText::createCopy() const | Drawable* DrawableText::createCopy() const | ||||
{ | { | ||||
DrawableText* const dt = new DrawableText(); | |||||
dt->text = text; | |||||
dt->colour = colour; | |||||
return new DrawableText (*this); | |||||
} | |||||
return dt; | |||||
void DrawableText::invalidatePoints() | |||||
{ | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
const Identifier DrawableText::valueTreeType ("Text"); | const Identifier DrawableText::valueTreeType ("Text"); | ||||
const Identifier DrawableText::ValueTreeWrapper::text ("text"); | |||||
DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) | |||||
: ValueTreeWrapperBase (state_) | |||||
{ | |||||
jassert (state.hasType (valueTreeType)); | |||||
} | |||||
const Rectangle<float> DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | const Rectangle<float> DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) | ||||
{ | { | ||||
jassert (tree.hasType (valueTreeType)); | |||||
setName (tree [idProperty]); | |||||
ValueTreeWrapper v (tree); | |||||
setName (v.getID()); | |||||
jassertfalse; // xxx not finished! | jassertfalse; // xxx not finished! | ||||
@@ -99,13 +112,14 @@ const Rectangle<float> DrawableText::refreshFromValueTree (const ValueTree& tree | |||||
const ValueTree DrawableText::createValueTree (ImageProvider* imageProvider) const | const ValueTree DrawableText::createValueTree (ImageProvider* imageProvider) const | ||||
{ | { | ||||
ValueTree v (valueTreeType); | |||||
ValueTree tree (valueTreeType); | |||||
ValueTreeWrapper v (tree); | |||||
if (getName().isNotEmpty()) | |||||
v.setProperty (idProperty, getName(), 0); | |||||
v.setID (getName(), 0); | |||||
jassertfalse; // xxx not finished! | jassertfalse; // xxx not finished! | ||||
return v; | |||||
return tree; | |||||
} | } | ||||
@@ -42,6 +42,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** Creates a DrawableText object. */ | /** Creates a DrawableText object. */ | ||||
DrawableText(); | DrawableText(); | ||||
DrawableText (const DrawableText& other); | |||||
/** Destructor. */ | /** Destructor. */ | ||||
virtual ~DrawableText(); | virtual ~DrawableText(); | ||||
@@ -78,6 +79,8 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
Drawable* createCopy() const; | Drawable* createCopy() const; | ||||
/** @internal */ | /** @internal */ | ||||
void invalidatePoints(); | |||||
/** @internal */ | |||||
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); | ||||
/** @internal */ | /** @internal */ | ||||
const ValueTree createValueTree (ImageProvider* imageProvider) const; | const ValueTree createValueTree (ImageProvider* imageProvider) const; | ||||
@@ -86,6 +89,19 @@ public: | |||||
/** @internal */ | /** @internal */ | ||||
const Identifier getValueTreeType() const { return valueTreeType; } | const Identifier getValueTreeType() const { return valueTreeType; } | ||||
//============================================================================== | |||||
/** Internally-used class for wrapping a DrawableText's state into a ValueTree. */ | |||||
class ValueTreeWrapper : public ValueTreeWrapperBase | |||||
{ | |||||
public: | |||||
ValueTreeWrapper (const ValueTree& state); | |||||
//xxx todo | |||||
private: | |||||
static const Identifier text; | |||||
}; | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
@@ -93,7 +109,6 @@ private: | |||||
GlyphArrangement text; | GlyphArrangement text; | ||||
Colour colour; | Colour colour; | ||||
DrawableText (const DrawableText&); | |||||
DrawableText& operator= (const DrawableText&); | DrawableText& operator= (const DrawableText&); | ||||
}; | }; | ||||
@@ -74,12 +74,7 @@ namespace PathHelpers | |||||
while (*t != 0 && ! CharacterFunctions::isWhitespace (*t)) | while (*t != 0 && ! CharacterFunctions::isWhitespace (*t)) | ||||
++t; | ++t; | ||||
const int length = (int) (t - start); | |||||
while (CharacterFunctions::isWhitespace (*t)) | |||||
++t; | |||||
return String (start, length); | |||||
return String (start, (int) (t - start)); | |||||
} | } | ||||
} | } | ||||
@@ -1479,12 +1474,15 @@ void Path::restoreFromString (const String& stringVersion) | |||||
int numValues = 2; | int numValues = 2; | ||||
float values [6]; | float values [6]; | ||||
while (*t != 0) | |||||
for (;;) | |||||
{ | { | ||||
const String token (PathHelpers::nextToken (t)); | const String token (PathHelpers::nextToken (t)); | ||||
const juce_wchar firstChar = token[0]; | const juce_wchar firstChar = token[0]; | ||||
int startNum = 0; | int startNum = 0; | ||||
if (firstChar == 0) | |||||
break; | |||||
if (firstChar == 'm' || firstChar == 'l') | if (firstChar == 'm' || firstChar == 'l') | ||||
{ | { | ||||
marker = firstChar; | marker = firstChar; | ||||
@@ -28,6 +28,8 @@ | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
#include "juce_RelativeCoordinate.h" | #include "juce_RelativeCoordinate.h" | ||||
#include "../../../io/streams/juce_MemoryOutputStream.h" | |||||
//============================================================================== | //============================================================================== | ||||
namespace RelativeCoordinateHelpers | namespace RelativeCoordinateHelpers | ||||
@@ -61,9 +63,10 @@ namespace RelativeCoordinateHelpers | |||||
return fullName.fromFirstOccurrenceOf (".", false, false); | return fullName.fromFirstOccurrenceOf (".", false, false); | ||||
} | } | ||||
static const RelativeCoordinate findCoordinate (const String& name, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) | |||||
static const RelativeCoordinate findCoordinate (const String& name, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
return nameFinder.findNamedCoordinate (getObjectName (name), getEdgeName (name)); | |||||
return nameFinder != 0 ? nameFinder->findNamedCoordinate (getObjectName (name), getEdgeName (name)) | |||||
: RelativeCoordinate(); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -81,6 +84,13 @@ namespace RelativeCoordinateHelpers | |||||
++i; | ++i; | ||||
} | } | ||||
static void skipComma (const String& s, int& i) | |||||
{ | |||||
skipWhitespace (s, i); | |||||
if (s[i] == ',') | |||||
++i; | |||||
} | |||||
static const String readAnchorName (const String& s, int& i) | static const String readAnchorName (const String& s, int& i) | ||||
{ | { | ||||
skipWhitespace (s, i); | skipWhitespace (s, i); | ||||
@@ -126,10 +136,89 @@ namespace RelativeCoordinateHelpers | |||||
return value; | return value; | ||||
} | } | ||||
static const RelativeCoordinate readNextCoordinate (const String& s, int& i, const bool isHorizontal) | |||||
{ | |||||
String anchor1 (readAnchorName (s, i)); | |||||
double value = 0; | |||||
if (anchor1.isNotEmpty()) | |||||
{ | |||||
skipWhitespace (s, i); | |||||
if (s[i] == '+') | |||||
value = readNumber (s, ++i); | |||||
else if (s[i] == '-') | |||||
value = -readNumber (s, ++i); | |||||
return RelativeCoordinate (value, anchor1); | |||||
} | |||||
else | |||||
{ | |||||
value = readNumber (s, i); | |||||
skipWhitespace (s, i); | |||||
if (s[i] == '%') | |||||
{ | |||||
value /= 100.0; | |||||
skipWhitespace (s, ++i); | |||||
String anchor2; | |||||
if (s[i] == '*') | |||||
{ | |||||
anchor1 = readAnchorName (s, ++i); | |||||
if (anchor1.isEmpty()) | |||||
anchor1 = getOriginAnchorName (isHorizontal); | |||||
skipWhitespace (s, i); | |||||
if (s[i] == '-' && s[i + 1] == '>') | |||||
{ | |||||
i += 2; | |||||
anchor2 = readAnchorName (s, i); | |||||
} | |||||
else | |||||
{ | |||||
anchor2 = anchor1; | |||||
anchor1 = getOriginAnchorName (isHorizontal); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
anchor1 = getOriginAnchorName (isHorizontal); | |||||
anchor2 = getExtentAnchorName (isHorizontal); | |||||
} | |||||
return RelativeCoordinate (value, anchor1, anchor2); | |||||
} | |||||
return RelativeCoordinate (value, isHorizontal); | |||||
} | |||||
} | |||||
static const String limitedAccuracyString (const double n) | static const String limitedAccuracyString (const double n) | ||||
{ | { | ||||
return String (n, 3).trimCharactersAtEnd ("0").trimCharactersAtEnd ("."); | return String (n, 3).trimCharactersAtEnd ("0").trimCharactersAtEnd ("."); | ||||
} | } | ||||
static bool couldBeMistakenForPathCommand (const String& s) | |||||
{ | |||||
switch (s[0]) | |||||
{ | |||||
case 'a': | |||||
case 'm': | |||||
case 'l': | |||||
case 'z': | |||||
case 'q': | |||||
case 'c': | |||||
return s[1] == 0 || CharacterFunctions::isWhitespace (s[1]); | |||||
default: | |||||
break; | |||||
} | |||||
return false; | |||||
} | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -171,10 +260,27 @@ RelativeCoordinate::RelativeCoordinate (const double relativeProportion, const S | |||||
jassert (anchor2.isNotEmpty()); | jassert (anchor2.isNotEmpty()); | ||||
} | } | ||||
RelativeCoordinate::RelativeCoordinate (const String& s, const bool isHorizontal) | |||||
: value (0) | |||||
{ | |||||
int i = 0; | |||||
*this = RelativeCoordinateHelpers::readNextCoordinate (s, i, isHorizontal); | |||||
} | |||||
RelativeCoordinate::~RelativeCoordinate() | RelativeCoordinate::~RelativeCoordinate() | ||||
{ | { | ||||
} | } | ||||
bool RelativeCoordinate::operator== (const RelativeCoordinate& other) const throw() | |||||
{ | |||||
return value == other.value && anchor1 == other.anchor1 && anchor2 == other.anchor2; | |||||
} | |||||
bool RelativeCoordinate::operator!= (const RelativeCoordinate& other) const throw() | |||||
{ | |||||
return ! operator== (other); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate1() const | const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate1() const | ||||
{ | { | ||||
@@ -186,7 +292,7 @@ const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate2() const | |||||
return RelativeCoordinate (0.0, anchor2); | return RelativeCoordinate (0.0, anchor2); | ||||
} | } | ||||
double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedCoordinateFinder& nameFinder, int recursionCounter) | |||||
double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedCoordinateFinder* nameFinder, int recursionCounter) | |||||
{ | { | ||||
if (RelativeCoordinateHelpers::isOrigin (anchorName)) | if (RelativeCoordinateHelpers::isOrigin (anchorName)) | ||||
return 0.0; | return 0.0; | ||||
@@ -194,7 +300,7 @@ double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedC | |||||
return RelativeCoordinateHelpers::findCoordinate (anchorName, nameFinder).resolve (nameFinder, recursionCounter + 1); | return RelativeCoordinateHelpers::findCoordinate (anchorName, nameFinder).resolve (nameFinder, recursionCounter + 1); | ||||
} | } | ||||
double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder, int recursionCounter) const | |||||
double RelativeCoordinate::resolve (const NamedCoordinateFinder* nameFinder, int recursionCounter) const | |||||
{ | { | ||||
if (recursionCounter > 150) | if (recursionCounter > 150) | ||||
{ | { | ||||
@@ -208,7 +314,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder, int | |||||
: pos1 + value; | : pos1 + value; | ||||
} | } | ||||
double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) const | |||||
double RelativeCoordinate::resolve (const NamedCoordinateFinder* nameFinder) const | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -220,7 +326,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) con | |||||
return 0.0; | return 0.0; | ||||
} | } | ||||
bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) const | |||||
bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder* nameFinder) const | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -234,7 +340,7 @@ bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) c | |||||
return false; | return false; | ||||
} | } | ||||
void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder& nameFinder) | |||||
void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
@@ -256,7 +362,7 @@ void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFin | |||||
{} | {} | ||||
} | } | ||||
void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder& nameFinder, bool isHorizontal) | |||||
void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder* nameFinder, bool isHorizontal) | |||||
{ | { | ||||
const double oldValue = resolve (nameFinder); | const double oldValue = resolve (nameFinder); | ||||
@@ -267,8 +373,7 @@ void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder& nam | |||||
moveToAbsolute (oldValue, nameFinder); | moveToAbsolute (oldValue, nameFinder); | ||||
} | } | ||||
//============================================================================== | |||||
bool RelativeCoordinate::references (const String& coordName, const NamedCoordinateFinder& nameFinder) const | |||||
bool RelativeCoordinate::references (const String& coordName, const NamedCoordinateFinder* nameFinder) const | |||||
{ | { | ||||
using namespace RelativeCoordinateHelpers; | using namespace RelativeCoordinateHelpers; | ||||
@@ -281,65 +386,12 @@ bool RelativeCoordinate::references (const String& coordName, const NamedCoordin | |||||
|| (isProportional() && findCoordinate (anchor2, nameFinder).references (coordName, nameFinder)); | || (isProportional() && findCoordinate (anchor2, nameFinder).references (coordName, nameFinder)); | ||||
} | } | ||||
//============================================================================== | |||||
RelativeCoordinate::RelativeCoordinate (const String& s, bool isHorizontal) | |||||
: value (0) | |||||
bool RelativeCoordinate::isDynamic() const | |||||
{ | { | ||||
using namespace RelativeCoordinateHelpers; | |||||
int i = 0; | |||||
anchor1 = readAnchorName (s, i); | |||||
if (anchor1.isNotEmpty()) | |||||
{ | |||||
skipWhitespace (s, i); | |||||
if (s[i] == '+') | |||||
value = readNumber (s, ++i); | |||||
else if (s[i] == '-') | |||||
value = -readNumber (s, ++i); | |||||
} | |||||
else | |||||
{ | |||||
anchor1 = getOriginAnchorName (isHorizontal); | |||||
value = readNumber (s, i); | |||||
skipWhitespace (s, i); | |||||
if (s[i] == '%') | |||||
{ | |||||
value /= 100.0; | |||||
skipWhitespace (s, ++i); | |||||
if (s[i] == '*') | |||||
{ | |||||
anchor1 = readAnchorName (s, ++i); | |||||
if (anchor1.isEmpty()) | |||||
anchor1 = getOriginAnchorName (isHorizontal); | |||||
skipWhitespace (s, i); | |||||
if (s[i] == '-' && s[i + 1] == '>') | |||||
{ | |||||
i += 2; | |||||
anchor2 = readAnchorName (s, i); | |||||
} | |||||
else | |||||
{ | |||||
anchor2 = anchor1; | |||||
anchor1 = getOriginAnchorName (isHorizontal); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
anchor1 = getOriginAnchorName (isHorizontal); | |||||
anchor2 = getExtentAnchorName (isHorizontal); | |||||
} | |||||
} | |||||
} | |||||
return anchor2.isNotEmpty() || ! RelativeCoordinateHelpers::isOrigin (anchor1); | |||||
} | } | ||||
//============================================================================== | |||||
const String RelativeCoordinate::toString() const | const String RelativeCoordinate::toString() const | ||||
{ | { | ||||
using namespace RelativeCoordinateHelpers; | using namespace RelativeCoordinateHelpers; | ||||
@@ -383,7 +435,7 @@ void RelativeCoordinate::setEditableNumber (const double newValue) | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const NamedCoordinateFinder& nameFinder) | |||||
void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | ||||
@@ -392,7 +444,7 @@ void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const Named | |||||
moveToAbsolute (oldValue, nameFinder); | moveToAbsolute (oldValue, nameFinder); | ||||
} | } | ||||
void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder& nameFinder) | |||||
void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
jassert (isProportional()); | jassert (isProportional()); | ||||
jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | ||||
@@ -402,7 +454,7 @@ void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const Named | |||||
moveToAbsolute (oldValue, nameFinder); | moveToAbsolute (oldValue, nameFinder); | ||||
} | } | ||||
void RelativeCoordinate::renameAnchorIfUsed (const String& oldName, const String& newName, const NamedCoordinateFinder& nameFinder) | |||||
void RelativeCoordinate::renameAnchorIfUsed (const String& oldName, const String& newName, const NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
using namespace RelativeCoordinateHelpers; | using namespace RelativeCoordinateHelpers; | ||||
jassert (oldName.isNotEmpty()); | jassert (oldName.isNotEmpty()); | ||||
@@ -439,21 +491,36 @@ RelativePoint::RelativePoint (const Point<float>& absolutePoint) | |||||
{ | { | ||||
} | } | ||||
RelativePoint::RelativePoint (const String& stringVersion) | |||||
RelativePoint::RelativePoint (const RelativeCoordinate& x_, const RelativeCoordinate& y_) | |||||
: x (x_), y (y_) | |||||
{ | { | ||||
const int separator = stringVersion.indexOfChar (','); | |||||
} | |||||
x = RelativeCoordinate (stringVersion.substring (0, separator), true); | |||||
y = RelativeCoordinate (stringVersion.substring (separator + 1), false); | |||||
RelativePoint::RelativePoint (const String& s) | |||||
{ | |||||
int i = 0; | |||||
x = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); | |||||
RelativeCoordinateHelpers::skipComma (s, i); | |||||
y = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); | |||||
} | } | ||||
const Point<float> RelativePoint::resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const | |||||
bool RelativePoint::operator== (const RelativePoint& other) const throw() | |||||
{ | |||||
return x == other.x && y == other.y; | |||||
} | |||||
bool RelativePoint::operator!= (const RelativePoint& other) const throw() | |||||
{ | |||||
return ! operator== (other); | |||||
} | |||||
const Point<float> RelativePoint::resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const | |||||
{ | { | ||||
return Point<float> ((float) x.resolve (nameFinder), | return Point<float> ((float) x.resolve (nameFinder), | ||||
(float) y.resolve (nameFinder)); | (float) y.resolve (nameFinder)); | ||||
} | } | ||||
void RelativePoint::moveToAbsolute (const Point<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) | |||||
void RelativePoint::moveToAbsolute (const Point<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
x.moveToAbsolute (newPos.getX(), nameFinder); | x.moveToAbsolute (newPos.getX(), nameFinder); | ||||
y.moveToAbsolute (newPos.getY(), nameFinder); | y.moveToAbsolute (newPos.getY(), nameFinder); | ||||
@@ -464,12 +531,17 @@ const String RelativePoint::toString() const | |||||
return x.toString() + ", " + y.toString(); | return x.toString() + ", " + y.toString(); | ||||
} | } | ||||
void RelativePoint::renameAnchorIfUsed (const String& oldName, const String& newName, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) | |||||
void RelativePoint::renameAnchorIfUsed (const String& oldName, const String& newName, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
x.renameAnchorIfUsed (oldName, newName, nameFinder); | x.renameAnchorIfUsed (oldName, newName, nameFinder); | ||||
y.renameAnchorIfUsed (oldName, newName, nameFinder); | y.renameAnchorIfUsed (oldName, newName, nameFinder); | ||||
} | } | ||||
bool RelativePoint::isDynamic() const | |||||
{ | |||||
return x.isDynamic() || y.isDynamic(); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
RelativeRectangle::RelativeRectangle() | RelativeRectangle::RelativeRectangle() | ||||
@@ -484,18 +556,29 @@ RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect, const String | |||||
{ | { | ||||
} | } | ||||
RelativeRectangle::RelativeRectangle (const String& stringVersion) | |||||
RelativeRectangle::RelativeRectangle (const String& s) | |||||
{ | { | ||||
StringArray tokens; | |||||
tokens.addTokens (stringVersion, ",", String::empty); | |||||
int i = 0; | |||||
left = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); | |||||
RelativeCoordinateHelpers::skipComma (s, i); | |||||
top = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); | |||||
RelativeCoordinateHelpers::skipComma (s, i); | |||||
right = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); | |||||
RelativeCoordinateHelpers::skipComma (s, i); | |||||
bottom = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); | |||||
} | |||||
left = RelativeCoordinate (tokens [0], true); | |||||
top = RelativeCoordinate (tokens [1], false); | |||||
right = RelativeCoordinate (tokens [2], true); | |||||
bottom = RelativeCoordinate (tokens [3], false); | |||||
bool RelativeRectangle::operator== (const RelativeRectangle& other) const throw() | |||||
{ | |||||
return left == other.left && top == other.top && right == other.right && bottom == other.bottom; | |||||
} | } | ||||
const Rectangle<float> RelativeRectangle::resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const | |||||
bool RelativeRectangle::operator!= (const RelativeRectangle& other) const throw() | |||||
{ | |||||
return ! operator== (other); | |||||
} | |||||
const Rectangle<float> RelativeRectangle::resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const | |||||
{ | { | ||||
const double l = left.resolve (nameFinder); | const double l = left.resolve (nameFinder); | ||||
const double r = right.resolve (nameFinder); | const double r = right.resolve (nameFinder); | ||||
@@ -505,7 +588,7 @@ const Rectangle<float> RelativeRectangle::resolve (const RelativeCoordinate::Nam | |||||
return Rectangle<float> ((float) l, (float) t, (float) (r - l), (float) (b - t)); | return Rectangle<float> ((float) l, (float) t, (float) (r - l), (float) (b - t)); | ||||
} | } | ||||
void RelativeRectangle::moveToAbsolute (const Rectangle<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) | |||||
void RelativeRectangle::moveToAbsolute (const Rectangle<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
left.moveToAbsolute (newPos.getX(), nameFinder); | left.moveToAbsolute (newPos.getX(), nameFinder); | ||||
right.moveToAbsolute (newPos.getRight(), nameFinder); | right.moveToAbsolute (newPos.getRight(), nameFinder); | ||||
@@ -519,7 +602,7 @@ const String RelativeRectangle::toString() const | |||||
} | } | ||||
void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& newName, | void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& newName, | ||||
const RelativeCoordinate::NamedCoordinateFinder& nameFinder) | |||||
const RelativeCoordinate::NamedCoordinateFinder* nameFinder) | |||||
{ | { | ||||
left.renameAnchorIfUsed (oldName, newName, nameFinder); | left.renameAnchorIfUsed (oldName, newName, nameFinder); | ||||
right.renameAnchorIfUsed (oldName, newName, nameFinder); | right.renameAnchorIfUsed (oldName, newName, nameFinder); | ||||
@@ -528,4 +611,264 @@ void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& | |||||
} | } | ||||
//============================================================================== | |||||
RelativePointPath::RelativePointPath() | |||||
: usesNonZeroWinding (true), | |||||
containsDynamicPoints (false) | |||||
{ | |||||
} | |||||
RelativePointPath::RelativePointPath (const RelativePointPath& other) | |||||
: usesNonZeroWinding (true), | |||||
containsDynamicPoints (false) | |||||
{ | |||||
parseString (other.toString()); | |||||
} | |||||
RelativePointPath::RelativePointPath (const String& s) | |||||
: usesNonZeroWinding (true), | |||||
containsDynamicPoints (false) | |||||
{ | |||||
parseString (s); | |||||
} | |||||
void RelativePointPath::parseString (const String& s) | |||||
{ | |||||
int i = 0; | |||||
juce_wchar marker = 'm'; | |||||
int numValues = 2; | |||||
RelativePoint points [3]; | |||||
for (;;) | |||||
{ | |||||
RelativeCoordinateHelpers::skipWhitespace (s, i); | |||||
const juce_wchar firstChar = s[i]; | |||||
if (firstChar == 0) | |||||
break; | |||||
const juce_wchar secondChar = s[i + 1]; | |||||
if (secondChar == 0 || CharacterFunctions::isWhitespace (secondChar)) | |||||
{ | |||||
if (firstChar == 'm' || firstChar == 'l') | |||||
{ | |||||
++i; | |||||
marker = firstChar; | |||||
numValues = 1; | |||||
} | |||||
else if (firstChar == 'q') | |||||
{ | |||||
++i; | |||||
marker = firstChar; | |||||
numValues = 2; | |||||
} | |||||
else if (firstChar == 'c') | |||||
{ | |||||
++i; | |||||
marker = firstChar; | |||||
numValues = 3; | |||||
} | |||||
else if (firstChar == 'z') | |||||
{ | |||||
++i; | |||||
marker = 'm'; | |||||
numValues = 2; | |||||
elements.add (new CloseSubPath()); | |||||
continue; | |||||
} | |||||
else if (firstChar == 'a') | |||||
{ | |||||
++i; | |||||
usesNonZeroWinding = false; | |||||
continue; | |||||
} | |||||
} | |||||
if (firstChar == '#') | |||||
++i; | |||||
for (int j = 0; j < numValues; ++j) | |||||
{ | |||||
const RelativeCoordinate x (RelativeCoordinateHelpers::readNextCoordinate (s, i, true)); | |||||
const RelativeCoordinate y (RelativeCoordinateHelpers::readNextCoordinate (s, i, false)); | |||||
points[j] = RelativePoint (x, y); | |||||
containsDynamicPoints = containsDynamicPoints || points[j].isDynamic(); | |||||
} | |||||
switch (marker) | |||||
{ | |||||
case 'm': elements.add (new StartSubPath (points[0])); break; | |||||
case 'l': elements.add (new LineTo (points[0])); break; | |||||
case 'q': elements.add (new QuadraticTo (points[0], points[1])); break; | |||||
case 'c': elements.add (new CubicTo (points[0], points[1], points[2])); break; | |||||
default: jassertfalse; break; // illegal string format? | |||||
} | |||||
} | |||||
} | |||||
RelativePointPath::~RelativePointPath() | |||||
{ | |||||
} | |||||
void RelativePointPath::swapWith (RelativePointPath& other) throw() | |||||
{ | |||||
elements.swapWithArray (other.elements); | |||||
swapVariables (usesNonZeroWinding, other.usesNonZeroWinding); | |||||
} | |||||
void RelativePointPath::createPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) | |||||
{ | |||||
for (int i = 0; i < elements.size(); ++i) | |||||
elements.getUnchecked(i)->addToPath (path, coordFinder); | |||||
} | |||||
bool RelativePointPath::containsAnyDynamicPoints() const | |||||
{ | |||||
return containsDynamicPoints; | |||||
} | |||||
const String RelativePointPath::toString() const | |||||
{ | |||||
ElementType lastType = nullElement; | |||||
MemoryOutputStream out; | |||||
if (! usesNonZeroWinding) | |||||
out << 'a'; | |||||
for (int i = 0; i < elements.size(); ++i) | |||||
{ | |||||
if (out.getDataSize() > 0) | |||||
out << ' '; | |||||
const ElementBase* const e = elements.getUnchecked(i); | |||||
e->write (out, lastType); | |||||
lastType = e->type; | |||||
} | |||||
return out.toUTF8(); | |||||
} | |||||
//============================================================================== | |||||
RelativePointPath::ElementBase::ElementBase (const ElementType type_) : type (type_) | |||||
{ | |||||
} | |||||
//============================================================================== | |||||
RelativePointPath::StartSubPath::StartSubPath (const RelativePoint& pos) | |||||
: ElementBase (startSubPathElement), startPos (pos) | |||||
{ | |||||
} | |||||
void RelativePointPath::StartSubPath::write (OutputStream& out, ElementType lastTypeWritten) const | |||||
{ | |||||
const String p (startPos.toString()); | |||||
if (lastTypeWritten != startSubPathElement) | |||||
out << "m "; | |||||
else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p)) | |||||
out << '#'; | |||||
out << p; | |||||
} | |||||
void RelativePointPath::StartSubPath::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const | |||||
{ | |||||
const Point<float> p (startPos.resolve (coordFinder)); | |||||
path.startNewSubPath (p.getX(), p.getY()); | |||||
} | |||||
//============================================================================== | |||||
RelativePointPath::CloseSubPath::CloseSubPath() | |||||
: ElementBase (closeSubPathElement) | |||||
{ | |||||
} | |||||
void RelativePointPath::CloseSubPath::write (OutputStream& out, ElementType lastTypeWritten) const | |||||
{ | |||||
if (lastTypeWritten != closeSubPathElement) | |||||
out << 'z'; | |||||
} | |||||
void RelativePointPath::CloseSubPath::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder*) const | |||||
{ | |||||
path.closeSubPath(); | |||||
} | |||||
//============================================================================== | |||||
RelativePointPath::LineTo::LineTo (const RelativePoint& endPoint_) | |||||
: ElementBase (lineToElement), endPoint (endPoint_) | |||||
{ | |||||
} | |||||
void RelativePointPath::LineTo::write (OutputStream& out, ElementType lastTypeWritten) const | |||||
{ | |||||
const String p (endPoint.toString()); | |||||
if (lastTypeWritten != lineToElement) | |||||
out << "l "; | |||||
else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p)) | |||||
out << '#'; | |||||
out << p; | |||||
} | |||||
void RelativePointPath::LineTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const | |||||
{ | |||||
const Point<float> p (endPoint.resolve (coordFinder)); | |||||
path.lineTo (p.getX(), p.getY()); | |||||
} | |||||
//============================================================================== | |||||
RelativePointPath::QuadraticTo::QuadraticTo (const RelativePoint& controlPoint_, const RelativePoint& endPoint_) | |||||
: ElementBase (quadraticToElement), controlPoint (controlPoint_), endPoint (endPoint_) | |||||
{ | |||||
} | |||||
void RelativePointPath::QuadraticTo::write (OutputStream& out, ElementType lastTypeWritten) const | |||||
{ | |||||
const String p1 (controlPoint.toString()); | |||||
if (lastTypeWritten != quadraticToElement) | |||||
out << "q "; | |||||
else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p1)) | |||||
out << '#'; | |||||
out << p1 << ' ' << endPoint.toString(); | |||||
} | |||||
void RelativePointPath::QuadraticTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const | |||||
{ | |||||
const Point<float> p1 (controlPoint.resolve (coordFinder)); | |||||
const Point<float> p2 (endPoint.resolve (coordFinder)); | |||||
path.quadraticTo (p1.getX(), p1.getY(), p2.getX(), p2.getY()); | |||||
} | |||||
//============================================================================== | |||||
RelativePointPath::CubicTo::CubicTo (const RelativePoint& controlPoint1_, const RelativePoint& controlPoint2_, const RelativePoint& endPoint_) | |||||
: ElementBase (cubicToElement), controlPoint1 (controlPoint1_), controlPoint2 (controlPoint2_), endPoint (endPoint_) | |||||
{ | |||||
} | |||||
void RelativePointPath::CubicTo::write (OutputStream& out, ElementType lastTypeWritten) const | |||||
{ | |||||
const String p1 (controlPoint1.toString()); | |||||
if (lastTypeWritten != cubicToElement) | |||||
out << "c "; | |||||
else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p1)) | |||||
out << '#'; | |||||
out << p1 << ' ' << controlPoint2.toString() << ' ' << endPoint.toString(); | |||||
} | |||||
void RelativePointPath::CubicTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const | |||||
{ | |||||
const Point<float> p1 (controlPoint1.resolve (coordFinder)); | |||||
const Point<float> p2 (controlPoint2.resolve (coordFinder)); | |||||
const Point<float> p3 (endPoint.resolve (coordFinder)); | |||||
path.cubicTo (p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY()); | |||||
} | |||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE |
@@ -26,7 +26,9 @@ | |||||
#ifndef __JUCE_RELATIVECOORDINATE_JUCEHEADER__ | #ifndef __JUCE_RELATIVECOORDINATE_JUCEHEADER__ | ||||
#define __JUCE_RELATIVECOORDINATE_JUCEHEADER__ | #define __JUCE_RELATIVECOORDINATE_JUCEHEADER__ | ||||
#include "juce_Path.h" | |||||
#include "juce_Rectangle.h" | #include "juce_Rectangle.h" | ||||
#include "../../../containers/juce_OwnedArray.h" | |||||
//============================================================================== | //============================================================================== | ||||
@@ -101,8 +103,8 @@ public: | |||||
e.g. "marker1", or it can be a two-part name in the form "objectName.edge". For example "parent.left" is | e.g. "marker1", or it can be a two-part name in the form "objectName.edge". For example "parent.left" is | ||||
the origin, or "myComponent.top" is the top edge of a component called "myComponent". The exact names that | the origin, or "myComponent.top" is the top edge of a component called "myComponent". The exact names that | ||||
will be recognised are dependent on the NamedCoordinateFinder that you provide for looking them up, but | will be recognised are dependent on the NamedCoordinateFinder that you provide for looking them up, but | ||||
"parent.left", "parent.top", "parent.right" and "parent.bottom" are always available, representing the | |||||
extents of the target coordinate space. | |||||
"parent.left" and "parent.top" are always available, meaning the origin. "parent.right" and "parent.bottom" | |||||
may also be available if the coordinate space has a fixed size. | |||||
@param stringVersion the string to parse | @param stringVersion the string to parse | ||||
@param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. | @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. | ||||
@@ -114,6 +116,9 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~RelativeCoordinate(); | ~RelativeCoordinate(); | ||||
bool operator== (const RelativeCoordinate& other) const throw(); | |||||
bool operator!= (const RelativeCoordinate& other) const throw(); | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
Provides an interface for looking up the position of a named anchor when resolving a RelativeCoordinate. | Provides an interface for looking up the position of a named anchor when resolving a RelativeCoordinate. | ||||
@@ -145,15 +150,18 @@ public: | |||||
You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may | You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may | ||||
be needed to calculate the result. | be needed to calculate the result. | ||||
*/ | */ | ||||
double resolve (const NamedCoordinateFinder& nameFinder) const; | |||||
double resolve (const NamedCoordinateFinder* nameFinder) const; | |||||
/** Returns true if this coordinate uses the specified coord name at any level in its evaluation. | /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. | ||||
This will recursively check any coordinates upon which this one depends. | This will recursively check any coordinates upon which this one depends. | ||||
*/ | */ | ||||
bool references (const String& coordName, const NamedCoordinateFinder& nameFinder) const; | |||||
bool references (const String& coordName, const NamedCoordinateFinder* nameFinder) const; | |||||
/** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ | /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ | ||||
bool isRecursive (const NamedCoordinateFinder& nameFinder) const; | |||||
bool isRecursive (const NamedCoordinateFinder* nameFinder) const; | |||||
/** Returns true if this coordinate depends on any other coordinates for its position. */ | |||||
bool isDynamic() const; | |||||
//============================================================================== | //============================================================================== | ||||
/** Changes the value of this coord to make it resolve to the specified position. | /** Changes the value of this coord to make it resolve to the specified position. | ||||
@@ -162,7 +170,7 @@ public: | |||||
or relative position to whatever value is necessary to make its resultant position | or relative position to whatever value is necessary to make its resultant position | ||||
match the position that is provided. | match the position that is provided. | ||||
*/ | */ | ||||
void moveToAbsolute (double absoluteTargetPosition, const NamedCoordinateFinder& nameFinder); | |||||
void moveToAbsolute (double absoluteTargetPosition, const NamedCoordinateFinder* nameFinder); | |||||
/** Returns true if the coordinate is calculated as a proportion of the distance between two other points. | /** Returns true if the coordinate is calculated as a proportion of the distance between two other points. | ||||
@see toggleProportionality | @see toggleProportionality | ||||
@@ -173,7 +181,7 @@ public: | |||||
Note that calling this will reset the names of any anchor points, and just make the | Note that calling this will reset the names of any anchor points, and just make the | ||||
coordinate relative to the parent origin and parent size. | coordinate relative to the parent origin and parent size. | ||||
*/ | */ | ||||
void toggleProportionality (const NamedCoordinateFinder& nameFinder, bool isHorizontal); | |||||
void toggleProportionality (const NamedCoordinateFinder* nameFinder, bool isHorizontal); | |||||
/** Returns a value that can be edited to set this coordinate's position. | /** Returns a value that can be edited to set this coordinate's position. | ||||
The meaning of this number depends on the coordinate's mode. If the coordinate is | The meaning of this number depends on the coordinate's mode. If the coordinate is | ||||
@@ -212,12 +220,12 @@ public: | |||||
/** Changes the first anchor point, keeping the resultant position of this coordinate in | /** Changes the first anchor point, keeping the resultant position of this coordinate in | ||||
the same place it was previously. | the same place it was previously. | ||||
*/ | */ | ||||
void changeAnchor1 (const String& newAnchor, const NamedCoordinateFinder& nameFinder); | |||||
void changeAnchor1 (const String& newAnchor, const NamedCoordinateFinder* nameFinder); | |||||
/** Changes the second anchor point, keeping the resultant position of this coordinate in | /** Changes the second anchor point, keeping the resultant position of this coordinate in | ||||
the same place it was previously. | the same place it was previously. | ||||
*/ | */ | ||||
void changeAnchor2 (const String& newAnchor, const NamedCoordinateFinder& nameFinder); | |||||
void changeAnchor2 (const String& newAnchor, const NamedCoordinateFinder* nameFinder); | |||||
/** Tells the coordinate that an object is changing its name or being deleted. | /** Tells the coordinate that an object is changing its name or being deleted. | ||||
@@ -227,7 +235,7 @@ public: | |||||
instead. | instead. | ||||
*/ | */ | ||||
void renameAnchorIfUsed (const String& oldName, const String& newName, | void renameAnchorIfUsed (const String& oldName, const String& newName, | ||||
const NamedCoordinateFinder& nameFinder); | |||||
const NamedCoordinateFinder* nameFinder); | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns a string which represents this coordinate. | /** Returns a string which represents this coordinate. | ||||
@@ -261,8 +269,8 @@ private: | |||||
String anchor1, anchor2; | String anchor1, anchor2; | ||||
double value; | double value; | ||||
double resolve (const NamedCoordinateFinder& nameFinder, int recursionCounter) const; | |||||
static double resolveAnchor (const String& anchorName, const NamedCoordinateFinder& nameFinder, int recursionCounter); | |||||
double resolve (const NamedCoordinateFinder* nameFinder, int recursionCounter) const; | |||||
static double resolveAnchor (const String& anchorName, const NamedCoordinateFinder* nameFinder, int recursionCounter); | |||||
}; | }; | ||||
@@ -281,19 +289,25 @@ public: | |||||
/** Creates an absolute point, relative to the origin. */ | /** Creates an absolute point, relative to the origin. */ | ||||
RelativePoint (const Point<float>& absolutePoint); | RelativePoint (const Point<float>& absolutePoint); | ||||
/** Creates an absolute point from two coordinates. */ | |||||
RelativePoint (const RelativeCoordinate& x, const RelativeCoordinate& y); | |||||
/** Creates a point from a stringified representation. | /** Creates a point from a stringified representation. | ||||
The string must contain a pair of coordinates, separated by a comma. The syntax for the coordinate | |||||
The string must contain a pair of coordinates, separated by space or a comma. The syntax for the coordinate | |||||
strings is explained in the RelativeCoordinate class. | strings is explained in the RelativeCoordinate class. | ||||
@see toString | @see toString | ||||
*/ | */ | ||||
RelativePoint (const String& stringVersion); | RelativePoint (const String& stringVersion); | ||||
bool operator== (const RelativePoint& other) const throw(); | |||||
bool operator!= (const RelativePoint& other) const throw(); | |||||
/** Calculates the absolute position of this point. | /** Calculates the absolute position of this point. | ||||
You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may | You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may | ||||
be needed to calculate the result. | be needed to calculate the result. | ||||
*/ | */ | ||||
const Point<float> resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const; | |||||
const Point<float> resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; | |||||
/** Changes the values of this point's coordinates to make it resolve to the specified position. | /** Changes the values of this point's coordinates to make it resolve to the specified position. | ||||
@@ -301,7 +315,7 @@ public: | |||||
or relative positions to whatever values are necessary to make the resultant position | or relative positions to whatever values are necessary to make the resultant position | ||||
match the position that is provided. | match the position that is provided. | ||||
*/ | */ | ||||
void moveToAbsolute (const Point<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder); | |||||
void moveToAbsolute (const Point<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder); | |||||
/** Returns a string which represents this point. | /** Returns a string which represents this point. | ||||
This returns a comma-separated pair of coordinates. For details of the string syntax used by the | This returns a comma-separated pair of coordinates. For details of the string syntax used by the | ||||
@@ -314,7 +328,10 @@ public: | |||||
This calls RelativeCoordinate::renameAnchorIfUsed() on its X and Y coordinates. | This calls RelativeCoordinate::renameAnchorIfUsed() on its X and Y coordinates. | ||||
*/ | */ | ||||
void renameAnchorIfUsed (const String& oldName, const String& newName, | void renameAnchorIfUsed (const String& oldName, const String& newName, | ||||
const RelativeCoordinate::NamedCoordinateFinder& nameFinder); | |||||
const RelativeCoordinate::NamedCoordinateFinder* nameFinder); | |||||
/** Returns true if this point depends on any other coordinates for its position. */ | |||||
bool isDynamic() const; | |||||
// The actual X and Y coords... | // The actual X and Y coords... | ||||
RelativeCoordinate x, y; | RelativeCoordinate x, y; | ||||
@@ -347,13 +364,16 @@ public: | |||||
*/ | */ | ||||
explicit RelativeRectangle (const String& stringVersion); | explicit RelativeRectangle (const String& stringVersion); | ||||
bool operator== (const RelativeRectangle& other) const throw(); | |||||
bool operator!= (const RelativeRectangle& other) const throw(); | |||||
//============================================================================== | //============================================================================== | ||||
/** Calculates the absolute position of this rectangle. | /** Calculates the absolute position of this rectangle. | ||||
You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may | You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may | ||||
be needed to calculate the result. | be needed to calculate the result. | ||||
*/ | */ | ||||
const Rectangle<float> resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const; | |||||
const Rectangle<float> resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; | |||||
/** Changes the values of this rectangle's coordinates to make it resolve to the specified position. | /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. | ||||
@@ -361,7 +381,7 @@ public: | |||||
or relative positions to whatever values are necessary to make the resultant position | or relative positions to whatever values are necessary to make the resultant position | ||||
match the position that is provided. | match the position that is provided. | ||||
*/ | */ | ||||
void moveToAbsolute (const Rectangle<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder); | |||||
void moveToAbsolute (const Rectangle<float>& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder); | |||||
/** Returns a string which represents this point. | /** Returns a string which represents this point. | ||||
This returns a comma-separated list of coordinates, in the order left, top, right, bottom. For details of | This returns a comma-separated list of coordinates, in the order left, top, right, bottom. For details of | ||||
@@ -374,11 +394,139 @@ public: | |||||
This calls RelativeCoordinate::renameAnchorIfUsed() on the rectangle's coordinates. | This calls RelativeCoordinate::renameAnchorIfUsed() on the rectangle's coordinates. | ||||
*/ | */ | ||||
void renameAnchorIfUsed (const String& oldName, const String& newName, | void renameAnchorIfUsed (const String& oldName, const String& newName, | ||||
const RelativeCoordinate::NamedCoordinateFinder& nameFinder); | |||||
const RelativeCoordinate::NamedCoordinateFinder* nameFinder); | |||||
// The actual rectangle coords... | // The actual rectangle coords... | ||||
RelativeCoordinate left, right, top, bottom; | RelativeCoordinate left, right, top, bottom; | ||||
}; | }; | ||||
//============================================================================== | |||||
/** | |||||
A path object that consists of RelativePoint coordinates rather than the normal fixed ones. | |||||
One of these paths can be converted into a Path object for drawing and manipulation, but | |||||
unlike a Path, its points can be dynamic instead of just fixed. | |||||
@see RelativePoint, RelativeCoordinate | |||||
*/ | |||||
class JUCE_API RelativePointPath | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
RelativePointPath(); | |||||
RelativePointPath (const RelativePointPath& other); | |||||
RelativePointPath (const String& stringVersion); | |||||
~RelativePointPath(); | |||||
//============================================================================== | |||||
/** Resolves this points in this path and adds them to a normal Path object. */ | |||||
void createPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder); | |||||
/** Returns true if the path contains any non-fixed points. */ | |||||
bool containsAnyDynamicPoints() const; | |||||
/** Returns a string version of the path. | |||||
This has the same format as Path::toString(), but since it can contain RelativeCoordinate | |||||
positions, it can't be parsed by the Path class if any of the points are dynamic. | |||||
*/ | |||||
const String toString() const; | |||||
/** Quickly swaps the contents of this path with another. */ | |||||
void swapWith (RelativePointPath& other) throw(); | |||||
//============================================================================== | |||||
/** The types of element that may be contained in this path. | |||||
@see RelativePointPath::ElementBase | |||||
*/ | |||||
enum ElementType | |||||
{ | |||||
nullElement, | |||||
startSubPathElement, | |||||
closeSubPathElement, | |||||
lineToElement, | |||||
quadraticToElement, | |||||
cubicToElement | |||||
}; | |||||
//============================================================================== | |||||
/** Base class for the elements that make up a RelativePointPath. | |||||
*/ | |||||
class JUCE_API ElementBase | |||||
{ | |||||
public: | |||||
ElementBase (ElementType type); | |||||
virtual ~ElementBase() {} | |||||
virtual void write (OutputStream& out, ElementType lastTypeWritten) const = 0; | |||||
virtual void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const = 0; | |||||
const ElementType type; | |||||
}; | |||||
class JUCE_API StartSubPath : public ElementBase | |||||
{ | |||||
public: | |||||
StartSubPath (const RelativePoint& pos); | |||||
~StartSubPath() {} | |||||
void write (OutputStream& out, ElementType lastTypeWritten) const; | |||||
void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; | |||||
RelativePoint startPos; | |||||
}; | |||||
class JUCE_API CloseSubPath : public ElementBase | |||||
{ | |||||
public: | |||||
CloseSubPath(); | |||||
~CloseSubPath() {} | |||||
void write (OutputStream& out, ElementType lastTypeWritten) const; | |||||
void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; | |||||
}; | |||||
class JUCE_API LineTo : public ElementBase | |||||
{ | |||||
public: | |||||
LineTo (const RelativePoint& endPoint); | |||||
~LineTo() {} | |||||
void write (OutputStream& out, ElementType lastTypeWritten) const; | |||||
void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; | |||||
RelativePoint endPoint; | |||||
}; | |||||
class JUCE_API QuadraticTo : public ElementBase | |||||
{ | |||||
public: | |||||
QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); | |||||
~QuadraticTo() {} | |||||
void write (OutputStream& out, ElementType lastTypeWritten) const; | |||||
void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; | |||||
RelativePoint controlPoint, endPoint; | |||||
}; | |||||
class JUCE_API CubicTo : public ElementBase | |||||
{ | |||||
public: | |||||
CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); | |||||
~CubicTo() {} | |||||
void write (OutputStream& out, ElementType lastTypeWritten) const; | |||||
void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; | |||||
RelativePoint controlPoint1, controlPoint2, endPoint; | |||||
}; | |||||
//============================================================================== | |||||
OwnedArray <ElementBase> elements; | |||||
bool usesNonZeroWinding; | |||||
private: | |||||
bool containsDynamicPoints; | |||||
void parseString (const String& s); | |||||
RelativePointPath& operator= (const RelativePointPath&); | |||||
}; | |||||
#endif // __JUCE_RELATIVECOORDINATE_JUCEHEADER__ | #endif // __JUCE_RELATIVECOORDINATE_JUCEHEADER__ |
@@ -131,6 +131,9 @@ void ImageCache::releaseOrDelete (Image* const imageToRelease) | |||||
bool ImageCache::isImageInCache (Image* const imageToLookFor) | bool ImageCache::isImageInCache (Image* const imageToLookFor) | ||||
{ | { | ||||
if (imageToLookFor == 0) | |||||
return false; | |||||
if (instance != 0) | if (instance != 0) | ||||
{ | { | ||||
const ScopedLock sl (instance->lock); | const ScopedLock sl (instance->lock); | ||||
@@ -35,7 +35,7 @@ DirectoryIterator::DirectoryIterator (const File& directory, | |||||
bool isRecursive_, | bool isRecursive_, | ||||
const String& wildCard_, | const String& wildCard_, | ||||
const int whatToLookFor_) | const int whatToLookFor_) | ||||
: fileFinder (directory, isRecursive ? "*" : wildCard_), | |||||
: fileFinder (directory, isRecursive_ ? "*" : wildCard_), | |||||
wildCard (wildCard_), | wildCard (wildCard_), | ||||
path (File::addTrailingSeparator (directory.getFullPathName())), | path (File::addTrailingSeparator (directory.getFullPathName())), | ||||
index (-1), | index (-1), | ||||
@@ -1091,15 +1091,9 @@ public: | |||||
{ | { | ||||
} | } | ||||
void repaint (int x, int y, int w, int h) | |||||
void repaint (const Rectangle<int>& area) | |||||
{ | { | ||||
if (Rectangle<int>::intersectRectangles (x, y, w, h, | |||||
0, 0, | |||||
getComponent()->getWidth(), | |||||
getComponent()->getHeight())) | |||||
{ | |||||
repainter->repaint (x, y, w, h); | |||||
} | |||||
repainter->repaint (area.getIntersection (getComponent()->getLocalBounds())); | |||||
} | } | ||||
void performAnyPendingRepaintsNow() | void performAnyPendingRepaintsNow() | ||||
@@ -1526,8 +1520,8 @@ public: | |||||
&child); | &child); | ||||
} | } | ||||
repaint (exposeEvent->x, exposeEvent->y, | |||||
exposeEvent->width, exposeEvent->height); | |||||
repaint (Rectangle<int> (exposeEvent->x, exposeEvent->y, | |||||
exposeEvent->width, exposeEvent->height)); | |||||
while (XEventsQueued (display, QueuedAfterFlush) > 0) | while (XEventsQueued (display, QueuedAfterFlush) > 0) | ||||
{ | { | ||||
@@ -1537,8 +1531,8 @@ public: | |||||
XNextEvent (display, (XEvent*) &nextEvent); | XNextEvent (display, (XEvent*) &nextEvent); | ||||
XExposeEvent* nextExposeEvent = (XExposeEvent*) &nextEvent.xexpose; | XExposeEvent* nextExposeEvent = (XExposeEvent*) &nextEvent.xexpose; | ||||
repaint (nextExposeEvent->x, nextExposeEvent->y, | |||||
nextExposeEvent->width, nextExposeEvent->height); | |||||
repaint (Rectangle<int> (nextExposeEvent->x, nextExposeEvent->y, | |||||
nextExposeEvent->width, nextExposeEvent->height)); | |||||
} | } | ||||
break; | break; | ||||
@@ -1838,12 +1832,12 @@ private: | |||||
} | } | ||||
} | } | ||||
void repaint (int x, int y, int w, int h) | |||||
void repaint (const Rectangle<int>& area) | |||||
{ | { | ||||
if (! isTimerRunning()) | if (! isTimerRunning()) | ||||
startTimer (repaintTimerPeriod); | startTimer (repaintTimerPeriod); | ||||
regionsNeedingRepaint.add (x, y, w, h); | |||||
regionsNeedingRepaint.add (area); | |||||
} | } | ||||
void performAnyPendingRepaintsNow() | void performAnyPendingRepaintsNow() | ||||
@@ -138,7 +138,7 @@ public: | |||||
void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); | void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); | ||||
//============================================================================== | //============================================================================== | ||||
void repaint (int x, int y, int w, int h); | |||||
void repaint (const Rectangle<int>& area); | |||||
void performAnyPendingRepaintsNow(); | void performAnyPendingRepaintsNow(); | ||||
//============================================================================== | //============================================================================== | ||||
@@ -849,19 +849,20 @@ public: | |||||
void messageCallback() | void messageCallback() | ||||
{ | { | ||||
if (ComponentPeer::isValidPeer (peer)) | if (ComponentPeer::isValidPeer (peer)) | ||||
peer->repaint (rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); | |||||
peer->repaint (rect); | |||||
} | } | ||||
}; | }; | ||||
void UIViewComponentPeer::repaint (int x, int y, int w, int h) | |||||
void UIViewComponentPeer::repaint (const Rectangle<int>& area) | |||||
{ | { | ||||
if (insideDrawRect || ! MessageManager::getInstance()->isThisTheMessageThread()) | if (insideDrawRect || ! MessageManager::getInstance()->isThisTheMessageThread()) | ||||
{ | { | ||||
(new AsyncRepaintMessage (this, Rectangle<int> (x, y, w, h)))->post(); | |||||
(new AsyncRepaintMessage (this, area))->post(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
[view setNeedsDisplayInRect: CGRectMake ((float) x, (float) y, (float) w, (float) h)]; | |||||
[view setNeedsDisplayInRect: CGRectMake ((float) area.getX(), (float) area.getY(), | |||||
(float) area.getWidth(), (float) area.getHeight())]; | |||||
} | } | ||||
} | } | ||||
@@ -253,7 +253,7 @@ public: | |||||
void textInputRequired (const Point<int>& position); | void textInputRequired (const Point<int>& position); | ||||
//============================================================================== | //============================================================================== | ||||
void repaint (int x, int y, int w, int h); | |||||
void repaint (const Rectangle<int>& area); | |||||
void performAnyPendingRepaintsNow(); | void performAnyPendingRepaintsNow(); | ||||
//============================================================================== | //============================================================================== | ||||
@@ -1631,20 +1631,20 @@ public: | |||||
void messageCallback() | void messageCallback() | ||||
{ | { | ||||
if (ComponentPeer::isValidPeer (peer)) | if (ComponentPeer::isValidPeer (peer)) | ||||
peer->repaint (rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); | |||||
peer->repaint (rect); | |||||
} | } | ||||
}; | }; | ||||
void NSViewComponentPeer::repaint (int x, int y, int w, int h) | |||||
void NSViewComponentPeer::repaint (const Rectangle<int>& area) | |||||
{ | { | ||||
if (insideDrawRect) | if (insideDrawRect) | ||||
{ | { | ||||
(new AsyncRepaintMessage (this, Rectangle<int> (x, y, w, h)))->post(); | |||||
(new AsyncRepaintMessage (this, area))->post(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
[view setNeedsDisplayInRect: NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)), | |||||
(float) w, (float) h)]; | |||||
[view setNeedsDisplayInRect: NSMakeRect ((float) area.getX(), [view frame].size.height - (float) area.getBottom(), | |||||
(float) area.getWidth(), (float) area.getHeight())]; | |||||
} | } | ||||
} | } | ||||
@@ -597,7 +597,10 @@ public: | |||||
Thread::sleep (20); | Thread::sleep (20); | ||||
isStarted = false; | isStarted = false; | ||||
isOpen_ = false; | isOpen_ = false; | ||||
close(); | |||||
const String errorCopy (error); | |||||
close(); // (this resets the error string) | |||||
error = errorCopy; | |||||
} | } | ||||
needToReset = false; | needToReset = false; | ||||
@@ -288,8 +288,7 @@ public: | |||||
void repaint() | void repaint() | ||||
{ | { | ||||
const Rectangle<int> bounds (nativeWindow->getBounds()); | |||||
nativeWindow->repaint (0, 0, bounds.getWidth(), bounds.getHeight()); | |||||
nativeWindow->repaint (nativeWindow->getBounds().withPosition (Point<int>())); | |||||
} | } | ||||
void swapBuffers() | void swapBuffers() | ||||
@@ -685,7 +685,7 @@ public: | |||||
int getInputLatencyInSamples() { return latencyIn; } | int getInputLatencyInSamples() { return latencyIn; } | ||||
const BigInteger getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BigInteger(); } | const BigInteger getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BigInteger(); } | ||||
const BigInteger getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BigInteger(); } | const BigInteger getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BigInteger(); } | ||||
const String getLastError() { return lastError; } | |||||
const String getLastError() { return lastError; } | |||||
const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, | const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, | ||||
@@ -705,9 +705,9 @@ public: | |||||
SetCaretPos (0, 0); | SetCaretPos (0, 0); | ||||
} | } | ||||
void repaint (int x, int y, int w, int h) | |||||
void repaint (const Rectangle<int>& area) | |||||
{ | { | ||||
const RECT r = { x, y, x + w, y + h }; | |||||
const RECT r = { area.getX(), area.getY(), area.getRight(), area.getBottom() }; | |||||
InvalidateRect (hwnd, &r, FALSE); | InvalidateRect (hwnd, &r, FALSE); | ||||
} | } | ||||
@@ -1055,9 +1055,7 @@ static int indexOfMatch (const juce_wchar* const wildcard, | |||||
else | else | ||||
{ | { | ||||
if (wc == '*' && (wildcard [i + 1] == 0 | if (wc == '*' && (wildcard [i + 1] == 0 | ||||
|| indexOfMatch (wildcard + i + 1, | |||||
test + start + i, | |||||
ignoreCase) >= 0)) | |||||
|| indexOfMatch (wildcard + i + 1, test + start + i, ignoreCase) >= 0)) | |||||
{ | { | ||||
return start; | return start; | ||||
} | } | ||||
@@ -1093,9 +1091,7 @@ bool String::matchesWildcard (const String& wildcard, const bool ignoreCase) con | |||||
else | else | ||||
{ | { | ||||
return wc == '*' && (wildcard [i + 1] == 0 | return wc == '*' && (wildcard [i + 1] == 0 | ||||
|| indexOfMatch (wildcard.text + i + 1, | |||||
text + i, | |||||
ignoreCase) >= 0); | |||||
|| indexOfMatch (wildcard.text + i + 1, text + i, ignoreCase) >= 0); | |||||
} | } | ||||
} | } | ||||
} | } | ||||