Browse Source

Major changes to the way Drawables are converted to ValueTrees (with more changes still to come in this area). Important fix to DirectoryIterator. Minor fix for ASIO. Jucer development.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
8ff6737261
75 changed files with 4686 additions and 2229 deletions
  1. +297
    -297
      Builds/Linux/Makefile
  2. +34
    -40
      extras/Jucer (experimental)/Builds/Linux/Makefile
  3. +3
    -7
      extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj
  4. +1
    -2
      extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
  5. +1
    -2
      extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
  6. +2
    -4
      extras/Jucer (experimental)/Jucer.jucer
  7. +5
    -5
      extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp
  8. +4
    -3
      extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h
  9. +4
    -4
      extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp
  10. +0
    -1
      extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h
  11. +78
    -45
      extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp
  12. +8
    -8
      extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h
  13. +103
    -0
      extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h
  14. +1
    -1
      extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h
  15. +4
    -4
      extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h
  16. +1
    -1
      extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.cpp
  17. +1
    -1
      extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.h
  18. +3
    -10
      extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp
  19. +16
    -5
      extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h
  20. +15
    -14
      extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h
  21. +3
    -3
      extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
  22. +1
    -1
      extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h
  23. +0
    -167
      extras/Jucer (experimental)/Source/utility/jucer_Coordinate.cpp
  24. +0
    -102
      extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h
  25. +2
    -2
      extras/Jucer (experimental)/Source/utility/jucer_CoordinatePropertyComponent.h
  26. +2
    -2
      extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h
  27. +140
    -0
      extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp
  28. +69
    -0
      extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h
  29. +2
    -2
      extras/amalgamator/Builds/Linux/Makefile
  30. +9
    -9
      extras/audio plugin host/Builds/Linux/Makefile
  31. +2
    -2
      extras/binarybuilder/Builds/Linux/Makefile
  32. +6
    -6
      extras/example projects/Builds/Linux/Makefile
  33. +26
    -26
      extras/juce demo/Builds/Linux/Makefile
  34. +1346
    -495
      juce_amalgamated.cpp
  35. +717
    -392
      juce_amalgamated.h
  36. +1
    -1
      src/containers/juce_Array.h
  37. +15
    -0
      src/containers/juce_NamedValueSet.cpp
  38. +4
    -0
      src/containers/juce_NamedValueSet.h
  39. +25
    -3
      src/containers/juce_ValueTree.cpp
  40. +12
    -3
      src/containers/juce_ValueTree.h
  41. +1
    -1
      src/core/juce_StandardHeader.h
  42. +1
    -2
      src/gui/components/controls/juce_ListBox.cpp
  43. +3
    -2
      src/gui/components/controls/juce_TreeView.cpp
  44. +6
    -1
      src/gui/components/juce_Component.cpp
  45. +15
    -0
      src/gui/components/juce_Component.h
  46. +5
    -5
      src/gui/components/special/juce_MagnifierComponent.cpp
  47. +1
    -1
      src/gui/components/windows/juce_ComponentPeer.h
  48. +1
    -3
      src/gui/components/windows/juce_DocumentWindow.cpp
  49. +2
    -1
      src/gui/graphics/contexts/juce_EdgeTable.h
  50. +16
    -0
      src/gui/graphics/contexts/juce_FillType.cpp
  51. +6
    -0
      src/gui/graphics/contexts/juce_FillType.h
  52. +26
    -29
      src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
  53. +129
    -3
      src/gui/graphics/drawables/juce_Drawable.cpp
  54. +26
    -1
      src/gui/graphics/drawables/juce_Drawable.h
  55. +321
    -63
      src/gui/graphics/drawables/juce_DrawableComposite.cpp
  56. +73
    -16
      src/gui/graphics/drawables/juce_DrawableComposite.h
  57. +162
    -112
      src/gui/graphics/drawables/juce_DrawableImage.cpp
  58. +41
    -13
      src/gui/graphics/drawables/juce_DrawableImage.h
  59. +172
    -136
      src/gui/graphics/drawables/juce_DrawablePath.cpp
  60. +40
    -8
      src/gui/graphics/drawables/juce_DrawablePath.h
  61. +25
    -11
      src/gui/graphics/drawables/juce_DrawableText.cpp
  62. +16
    -1
      src/gui/graphics/drawables/juce_DrawableText.h
  63. +5
    -7
      src/gui/graphics/geometry/juce_Path.cpp
  64. +429
    -86
      src/gui/graphics/geometry/juce_RelativeCoordinate.cpp
  65. +167
    -19
      src/gui/graphics/geometry/juce_RelativeCoordinate.h
  66. +3
    -0
      src/gui/graphics/imaging/juce_ImageCache.cpp
  67. +1
    -1
      src/io/files/juce_DirectoryIterator.cpp
  68. +8
    -14
      src/native/linux/juce_linux_Windowing.cpp
  69. +6
    -5
      src/native/mac/juce_iphone_UIViewComponentPeer.mm
  70. +6
    -6
      src/native/mac/juce_mac_NSViewComponentPeer.mm
  71. +4
    -1
      src/native/windows/juce_win32_ASIO.cpp
  72. +1
    -2
      src/native/windows/juce_win32_OpenGLComponent.cpp
  73. +1
    -1
      src/native/windows/juce_win32_WASAPI.cpp
  74. +2
    -2
      src/native/windows/juce_win32_Windowing.cpp
  75. +2
    -6
      src/text/juce_String.cpp

+ 297
- 297
Builds/Linux/Makefile
File diff suppressed because it is too large
View File


+ 34
- 40
extras/Jucer (experimental)/Builds/Linux/Makefile View File

@@ -68,7 +68,6 @@ OBJECTS := \
$(OBJDIR)/jucer_ProjectTreeViewBase.o \
$(OBJDIR)/jucer_TreeViewTypes.o \
$(OBJDIR)/jucer_CodeHelpers.o \
$(OBJDIR)/jucer_Coordinate.o \
$(OBJDIR)/jucer_FileHelpers.o \
$(OBJDIR)/jucer_StoredSettings.o \
$(OBJDIR)/jucer_MiscUtilities.o \
@@ -96,177 +95,172 @@ clean:
$(OBJDIR)/jucer_CodeGenerator.o: ../../Source/model/Component/jucer_CodeGenerator.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_CodeGenerator.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ComponentDocument.o: ../../Source/model/Component/jucer_ComponentDocument.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ComponentDocument.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ComponentTypeManager.o: ../../Source/model/Component/Types/jucer_ComponentTypeManager.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ComponentTypeManager.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_DrawableDocument.o: ../../Source/model/Drawable/jucer_DrawableDocument.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_DrawableDocument.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_NewFileWizard.o: ../../Source/model/Project/jucer_NewFileWizard.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_NewFileWizard.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_Project.o: ../../Source/model/Project/jucer_Project.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_Project.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ProjectExporter.o: ../../Source/model/Project/jucer_ProjectExporter.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ProjectExporter.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ProjectWizard.o: ../../Source/model/Project/jucer_ProjectWizard.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ProjectWizard.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ResourceFile.o: ../../Source/model/Project/jucer_ResourceFile.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ResourceFile.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_SourceCodeEditor.o: ../../Source/ui/Code\ Editor/jucer_SourceCodeEditor.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_SourceCodeEditor.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ComponentEditor.o: ../../Source/ui/Component\ Editor/jucer_ComponentEditor.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ComponentEditor.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ComponentViewer.o: ../../Source/ui/Component\ Editor/jucer_ComponentViewer.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ComponentViewer.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_DrawableEditor.o: ../../Source/ui/Drawable\ Editor/jucer_DrawableEditor.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_DrawableEditor.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_EditorCanvas.o: ../../Source/ui/Editor\ Base/jucer_EditorCanvas.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_EditorCanvas.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_DocumentEditorComponent.o: ../../Source/ui/jucer_DocumentEditorComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_DocumentEditorComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_JucerTreeViewBase.o: ../../Source/ui/jucer_JucerTreeViewBase.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_JucerTreeViewBase.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_MainWindow.o: ../../Source/ui/jucer_MainWindow.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_MainWindow.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_OpenDocumentManager.o: ../../Source/ui/jucer_OpenDocumentManager.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_OpenDocumentManager.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_GroupInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_GroupInformationComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_GroupInformationComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ItemPreviewComponent.o: ../../Source/ui/Project\ Editor/jucer_ItemPreviewComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ItemPreviewComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ProjectContentComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectContentComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ProjectContentComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ProjectInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectInformationComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ProjectInformationComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_ProjectTreeViewBase.o: ../../Source/ui/Project\ Editor/jucer_ProjectTreeViewBase.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_ProjectTreeViewBase.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_TreeViewTypes.o: ../../Source/ui/Project\ Editor/jucer_TreeViewTypes.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_TreeViewTypes.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_CodeHelpers.o: ../../Source/utility/jucer_CodeHelpers.cpp
-@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 "$<"
$(OBJDIR)/jucer_FileHelpers.o: ../../Source/utility/jucer_FileHelpers.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_FileHelpers.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_StoredSettings.o: ../../Source/utility/jucer_StoredSettings.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_StoredSettings.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_MiscUtilities.o: ../../Source/utility/jucer_MiscUtilities.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_MiscUtilities.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_Main.o: ../../Source/jucer_Main.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling jucer_Main.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling BinaryData.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode1.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode2.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode3.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode4.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-include $(OBJECTS:%.o=%.d)

+ 3
- 7
extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj View File

@@ -42,7 +42,6 @@
984444E3B2947675DC7D65DA = { isa = PBXBuildFile; fileRef = 1FDE55685608689765ADC578; };
58BF60E87F9A8EDCACC5D1AE = { isa = PBXBuildFile; fileRef = 939E2A7946081DB4D21B89B6; };
28B94C4BB7B572E6F5419E5D = { isa = PBXBuildFile; fileRef = 78E0309CB6D5E7E80B5BED7D; };
5BF87265418D736250283182 = { isa = PBXBuildFile; fileRef = C7ADB43F83A83FFC08921A12; };
12C1D006503C664FF07F476F = { isa = PBXBuildFile; fileRef = 5533704F0D30A9C62058FEC7; };
DDAB225ABE572196882C3524 = { isa = PBXBuildFile; fileRef = 7A1CD936BD306A6E0BEFB046; };
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; };
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; };
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; };
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; };
@@ -143,8 +143,6 @@
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; };
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; };
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; };
@@ -204,7 +202,8 @@
7C95A5CDB1B24D227D92749E ); name = Component; sourceTree = "<group>"; };
E70E3BE796E91EA86CFE10FE = { isa = PBXGroup; children = (
B1471E8698D193FBCF0DD13D,
739F94CA6213B43D867AB0FD ); name = Drawable; sourceTree = "<group>"; };
739F94CA6213B43D867AB0FD,
BDE8CD9273E1B0D0E500D283 ); name = Drawable; sourceTree = "<group>"; };
ADA17383E5554BCDF567AACC = { isa = PBXGroup; children = (
9DCB32BBD7053ACCB598CE79,
201DF0B7B4AA3E03B1AA5144,
@@ -280,8 +279,6 @@
9C58E022906C193862372BC1,
AAF3C58696944A256CA61730,
9736236B5C4D6A16FC7E03AC,
C7ADB43F83A83FFC08921A12,
EFA0636FB8ABA3377AB6C6F4,
CC9A3046B8B9FCDFE2092F51,
5533704F0D30A9C62058FEC7,
27E71DE11448E4D6721D5508,
@@ -438,7 +435,6 @@
984444E3B2947675DC7D65DA,
58BF60E87F9A8EDCACC5D1AE,
28B94C4BB7B572E6F5419E5D,
5BF87265418D736250283182,
12C1D006503C664FF07F476F,
DDAB225ABE572196882C3524,
92612DD3884793248F1EC45A,


+ 1
- 2
extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj View File

@@ -154,6 +154,7 @@
<Filter Name="Drawable">
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.cpp"/>
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.h"/>
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableTypeHandler.h"/>
</Filter>
<Filter Name="Project">
<File RelativePath="..\..\Source\model\Project\jucer_NewFileWizard.cpp"/>
@@ -229,8 +230,6 @@
<File RelativePath="..\..\Source\utility\jucer_CodeHelpers.h"/>
<File RelativePath="..\..\Source\utility\jucer_ColourEditorComponent.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_FileHelpers.cpp"/>
<File RelativePath="..\..\Source\utility\jucer_FileHelpers.h"/>


+ 1
- 2
extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj View File

@@ -154,6 +154,7 @@
<Filter Name="Drawable">
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.cpp"/>
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableDocument.h"/>
<File RelativePath="..\..\Source\model\Drawable\jucer_DrawableTypeHandler.h"/>
</Filter>
<Filter Name="Project">
<File RelativePath="..\..\Source\model\Project\jucer_NewFileWizard.cpp"/>
@@ -229,8 +230,6 @@
<File RelativePath="..\..\Source\utility\jucer_CodeHelpers.h"/>
<File RelativePath="..\..\Source\utility\jucer_ColourEditorComponent.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_FileHelpers.cpp"/>
<File RelativePath="..\..\Source\utility\jucer_FileHelpers.h"/>


+ 2
- 4
extras/Jucer (experimental)/Jucer.jucer View File

@@ -72,6 +72,8 @@
file="Source/model/Drawable/jucer_DrawableDocument.cpp"/>
<FILE id="qMcrWuCal" name="jucer_DrawableDocument.h" compile="0" resource="0"
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 id="na25KSPIj" name="Project">
<FILE id="jqL1mb9xp" name="jucer_NewFileWizard.cpp" compile="1" resource="0"
@@ -205,10 +207,6 @@
resource="0" file="Source/utility/jucer_ColourEditorComponent.h"/>
<FILE id="bjibbvm3S" name="jucer_Colours.h" compile="0" resource="0"
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"
resource="0" file="Source/utility/jucer_CoordinatePropertyComponent.h"/>
<FILE id="WlEYep7NN" name="jucer_FileHelpers.cpp" compile="1" resource="0"


+ 5
- 5
extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp View File

@@ -40,7 +40,7 @@ public:
//==============================================================================
ComponentBoundsEditor (ComponentDocument& document_, const String& name, Type type_,
const ValueTree& compState_, const Value& coordValue_)
: CoordinatePropertyComponent (document_, name,
: CoordinatePropertyComponent (&document_, name,
Value (new CoordExtractor (coordValue_, type_)),
type_ == left || type_ == right),
document (document_),
@@ -184,7 +184,7 @@ Component* ComponentTypeManager::createFromStoredType (ComponentDocument& docume
ComponentTypeHandler* ComponentTypeManager::getHandlerFor (const Identifier& type)
{
for (int i = handlers.size(); --i >= 0;)
if (handlers.getUnchecked(i)->getXmlTag() == type)
if (handlers.getUnchecked(i)->getValueTreeType() == type)
return handlers.getUnchecked(i);
return 0;
@@ -205,8 +205,8 @@ juce_ImplementSingleton_SingleThreaded (ComponentTypeManager);
//==============================================================================
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_)
{
}
@@ -315,7 +315,7 @@ void ComponentTypeInstance::initialiseNewItemBasics()
void ComponentTypeInstance::updateComponentBasics (Component* comp)
{
RelativeRectangle pos (state [ComponentDocument::compBoundsProperty].toString());
comp->setBounds (pos.resolve (document).getSmallestIntegerContainer());
comp->setBounds (pos.resolve (&document).getSmallestIntegerContainer());
//comp->setName (state [ComponentDocument::compNameProperty]);


+ 4
- 3
extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h View File

@@ -86,11 +86,12 @@ class ComponentTypeHandler
{
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();
const String& getDisplayName() const { return displayName; }
const Identifier& getXmlTag() const { return xmlTag; }
const Identifier& getValueTreeType() const { return valueTreeType; }
const String& getMemberNameRoot() const { return memberNameRoot; }
virtual Component* createComponent() = 0;
@@ -106,7 +107,7 @@ public:
protected:
//==============================================================================
const String displayName, className, memberNameRoot;
const Identifier xmlTag;
const Identifier valueTreeType;
private:
ComponentTypeHandler (const ComponentTypeHandler&);


+ 4
- 4
extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp View File

@@ -359,7 +359,7 @@ const ValueTree ComponentDocument::performNewComponentMenuItem (int menuResultCo
if (handler != 0)
{
ValueTree state (handler->getXmlTag());
ValueTree state (handler->getValueTreeType());
state.setProperty (idProperty, createAlphaNumericUID(), 0);
ComponentTypeInstance comp (*this, state);
@@ -532,7 +532,7 @@ void ComponentDocument::renameAnchor (const String& oldName, const String& newNa
{
ValueTree v (getComponent(i));
RelativeRectangle coords (getCoordsFor (v));
coords.renameAnchorIfUsed (oldName, newName, *this);
coords.renameAnchorIfUsed (oldName, newName, this);
setCoordsFor (v, coords);
}
@@ -551,7 +551,7 @@ void ComponentDocument::addMarkerMenuItem (int i, const RelativeCoordinate& coor
name << '.' << edge;
menu.addItem (i, name,
! (name == fullCoordName || requestedCoord.references (fullCoordName, *this)),
! (name == fullCoordName || requestedCoord.references (fullCoordName, this)),
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))),
"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())));
return true;
}


+ 0
- 1
extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h View File

@@ -28,7 +28,6 @@
#include "../../jucer_Headers.h"
#include "../Project/jucer_Project.h"
#include "../../utility/jucer_Coordinate.h"
#include "../../utility/jucer_MarkerListBase.h"
#include "jucer_CodeGenerator.h"


+ 78
- 45
extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp View File

@@ -24,6 +24,54 @@
*/
#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);
}
ValueTree DrawableDocument::getRootDrawableNode() const
DrawableComposite::ValueTreeWrapper DrawableDocument::getRootDrawableNode() const
{
return root.getChild (0);
return DrawableComposite::ValueTreeWrapper (root.getChild (0));
}
void DrawableDocument::checkRootObject()
@@ -75,11 +123,6 @@ void DrawableDocument::checkRootObject()
getCanvasHeight() = 500;
}
const String DrawableDocument::getIdFor (const ValueTree& object)
{
return object [Ids::id_];
}
//==============================================================================
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
}
//==============================================================================


+ 8
- 8
extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h View File

@@ -28,13 +28,13 @@
#include "../../jucer_Headers.h"
#include "../Project/jucer_Project.h"
#include "../../utility/jucer_Coordinate.h"
#include "../../utility/jucer_MarkerListBase.h"
//==============================================================================
class DrawableDocument : public ValueTree::Listener,
public ChangeBroadcaster
public ChangeBroadcaster,
public Drawable::ImageProvider
{
public:
//==============================================================================
@@ -51,16 +51,13 @@ public:
void changed();
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 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
@@ -91,6 +88,9 @@ public:
const String getNonexistentMarkerName (const String& name);
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 valueTreeChildrenChanged (ValueTree& tree);


+ 103
- 0
extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h View File

@@ -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__

+ 1
- 1
extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h View File

@@ -298,7 +298,7 @@ private:
out << "$(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i)))
<< ": " << escapeSpaces (files.getReference(i).toUnixStyle()) << 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 \"$<\""
: "\t@$(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"")
<< newLine << newLine;


+ 4
- 4
extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h View File

@@ -120,7 +120,7 @@ public:
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)
@@ -176,14 +176,14 @@ public:
const Rectangle<float> getObjectPosition (const ValueTree& state)
{
ComponentDocument& doc = getDocument();
return doc.getCoordsFor (state).resolve (doc);
return doc.getCoordsFor (state).resolve (&doc);
}
bool setObjectPosition (ValueTree& state, const Rectangle<float>& newBounds)
{
ComponentDocument& doc = getDocument();
RelativeRectangle pr (doc.getCoordsFor (state));
pr.moveToAbsolute (newBounds, doc);
pr.moveToAbsolute (newBounds, &doc);
return doc.setCoordsFor (state, pr);
}
@@ -191,7 +191,7 @@ public:
float getMarkerPosition (const ValueTree& marker, bool isX)
{
ComponentDocument& doc = getDocument();
return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (doc);
return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (&doc);
}
};


+ 1
- 1
extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.cpp View File

@@ -80,7 +80,7 @@ void ComponentViewer::handleAsyncUpdate()
background = Colour::fromString (componentDocument->getBackgroundColour().toString());
if (layoutManager == 0)
layoutManager = new ComponentAutoLayoutManager (this);
layoutManager = new RelativeRectangleLayoutManager (this);
int i;
for (i = getNumChildComponents(); --i >= 0;)


+ 1
- 1
extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.h View File

@@ -62,7 +62,7 @@ private:
ComponentDocument* componentDocument;
ValueTree documentRoot;
ScopedPointer<ComponentAutoLayoutManager> layoutManager;
ScopedPointer<RelativeRectangleLayoutManager> layoutManager;
Colour background;
ComponentViewer (const ComponentViewer&);


+ 3
- 10
extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp View File

@@ -53,7 +53,7 @@ public:
void createCanvas()
{
initialise (new DrawableEditorCanvas (editor), toolbarFactory,
new DrawableTreeViewItem (editor, editor.getDocument().getRootDrawableNode()));
new DrawableTreeViewItem (editor, editor.getDocument().getRootDrawableNode().getState()));
}
SelectedItemSet<String>& getSelection()
@@ -117,17 +117,10 @@ void DrawableEditor::selectionToBack()
void DrawableEditor::showNewShapeMenu (Component* componentToAttachTo)
{
/*
PopupMenu m;
getDocument().addNewComponentMenuItems (m);
getDocument().addNewItemMenuItems (m);
const int r = m.showAt (componentToAttachTo);
const ValueTree newComp (getDocument().performNewComponentMenuItem (r));
if (newComp.isValid())
getSelection().selectOnly (newComp [ComponentDocument::idProperty]);
*/
getDocument().performNewItemMenuItem (r);
}
//==============================================================================


+ 16
- 5
extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h View File

@@ -54,8 +54,19 @@ public:
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);
}
@@ -89,9 +100,9 @@ public:
}
else
{
// getDocument().addNewComponentMenuItems (m);
// const int r = m.show();
// getDocument().performNewComponentMenuItem (r);
getDocument().addNewItemMenuItems (m);
const int r = m.show();
getDocument().performNewItemMenuItem (r);
}
}


+ 15
- 14
extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h View File

@@ -38,14 +38,14 @@ public:
DrawableTreeViewItem (DrawableEditor& editor_, const ValueTree& drawableRoot)
: editor (editor_), node (drawableRoot), typeName (drawableRoot.getType().toString())
{
node.addListener (this);
node.getState().addListener (this);
editor.getSelection().addChangeListener (this);
}
~DrawableTreeViewItem()
{
editor.getSelection().removeChangeListener (this);
node.removeListener (this);
node.getState().removeListener (this);
}
//==============================================================================
@@ -55,7 +55,7 @@ public:
void valueTreeChildrenChanged (ValueTree& tree)
{
if (tree == node)
if (tree == node.getState())
refreshSubItems();
}
@@ -67,14 +67,13 @@ public:
// TreeViewItem stuff..
bool mightContainSubItems()
{
return node.getType() == DrawableComposite::valueTreeType
&& node.getNumChildren() > 0;
return node.getState().getType() == DrawableComposite::valueTreeType;
}
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)
@@ -85,15 +84,17 @@ public:
void refreshSubItems()
{
if (node.getType() == DrawableComposite::valueTreeType)
if (node.getState().getType() == DrawableComposite::valueTreeType)
{
ScopedPointer <XmlElement> oldOpenness (getOpennessState());
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);
addSubItem (item);
}
@@ -114,7 +115,7 @@ public:
const String getRenamingName() const
{
return node ["name"];
return node.getID();
}
void setName (const String& newName)
@@ -138,7 +139,7 @@ public:
void itemSelectionChanged (bool isNowSelected)
{
const String objectId (DrawableDocument::getIdFor (node));
const String objectId (node.getID());
if (isNowSelected)
editor.getSelection().addToSelection (objectId);
@@ -148,7 +149,7 @@ public:
void changeListenerCallback (void*)
{
setSelected (editor.getSelection().isSelected (DrawableDocument::getIdFor (node)), false);
setSelected (editor.getSelection().isSelected (node.getID()), false);
}
const String getTooltip()
@@ -194,7 +195,7 @@ public:
//==============================================================================
DrawableEditor& editor;
ValueTree node;
Drawable::ValueTreeWrapperBase node;
private:
String typeName;


+ 3
- 3
extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp View File

@@ -243,7 +243,7 @@ public:
void updatePosition()
{
RelativeCoordinate coord (getMarkerList().getCoordinate (marker));
const int pos = roundToInt (coord.resolve (getMarkerList()));
const int pos = roundToInt (coord.resolve (&getMarkerList()));
const int width = 8;
if (isX)
@@ -309,7 +309,7 @@ public:
canvas->getUndoManager().beginNewTransaction();
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)
coord.moveToAbsolute (jmax (0, roundToInt (dragStartPos + (isX ? e2.x - mouseDownPos.getX()
: e2.y - mouseDownPos.getY()))),
getMarkerList());
&getMarkerList());
getMarkerList().setCoordinate (marker, coord);
}
else


+ 1
- 1
extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h View File

@@ -26,10 +26,10 @@
#ifndef __JUCER_EDITORCANVAS_H_EF886D17__
#define __JUCER_EDITORCANVAS_H_EF886D17__
#include "../../utility/jucer_Coordinate.h"
#include "../../utility/jucer_MarkerListBase.h"
class EditorPanelBase;
//==============================================================================
class EditorCanvasBase : public Component,
public ValueTree::Listener,


+ 0
- 167
extras/Jucer (experimental)/Source/utility/jucer_Coordinate.cpp View File

@@ -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_)
{
}

+ 0
- 102
extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h View File

@@ -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__

+ 2
- 2
extras/Jucer (experimental)/Source/utility/jucer_CoordinatePropertyComponent.h View File

@@ -34,7 +34,7 @@ class CoordinatePropertyComponent : public PropertyComponent,
{
public:
//==============================================================================
CoordinatePropertyComponent (RelativeCoordinate::NamedCoordinateFinder& nameSource_, const String& name,
CoordinatePropertyComponent (RelativeCoordinate::NamedCoordinateFinder* nameSource_, const String& name,
const Value& coordValue_, bool isHorizontal_)
: PropertyComponent (name, 40), nameSource (nameSource_),
coordValue (coordValue_),
@@ -142,7 +142,7 @@ public:
virtual const String pickMarker (TextButton* button, const String& currentMarker, bool isAnchor1) = 0;
protected:
RelativeCoordinate::NamedCoordinateFinder& nameSource;
RelativeCoordinate::NamedCoordinateFinder* nameSource;
Value coordValue, textValue;
Label* label;
TextButton* proportionButton;


+ 2
- 2
extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h View File

@@ -56,7 +56,7 @@ public:
{
ValueTree v (getMarker (i));
RelativeCoordinate coord (getCoordinate (v));
coord.renameAnchorIfUsed (oldName, newName, *this);
coord.renameAnchorIfUsed (oldName, newName, this);
setCoordinate (v, coord);
}
}
@@ -133,7 +133,7 @@ public:
{
public:
//==============================================================================
PositionPropertyComponent (NamedCoordinateFinder& nameSource_, MarkerListBase& markerList_,
PositionPropertyComponent (NamedCoordinateFinder* nameSource_, MarkerListBase& markerList_,
const String& name, const ValueTree& markerState_,
const Value& coordValue_)
: CoordinatePropertyComponent (nameSource_, name, coordValue_, markerList_.isHorizontal()),


+ 140
- 0
extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp View File

@@ -266,3 +266,143 @@ void FloatingLabelComponent::paint (Graphics& g)
g.setColour (colour);
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_)
{
}

+ 69
- 0
extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h View File

@@ -136,3 +136,72 @@ private:
JucerToolbarButton (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&);
};

+ 2
- 2
extras/amalgamator/Builds/Linux/Makefile View File

@@ -63,12 +63,12 @@ clean:
$(OBJDIR)/Main.o: ../../Source/Main.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling Main.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-include $(OBJECTS:%.o=%.d)

+ 9
- 9
extras/audio plugin host/Builds/Linux/Makefile View File

@@ -70,47 +70,47 @@ clean:
$(OBJDIR)/FilterGraph.o: ../../Source/FilterGraph.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling FilterGraph.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/GraphEditorPanel.o: ../../Source/GraphEditorPanel.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling GraphEditorPanel.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/HostStartup.o: ../../Source/HostStartup.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling HostStartup.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/InternalFilters.o: ../../Source/InternalFilters.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling InternalFilters.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/MainHostWindow.o: ../../Source/MainHostWindow.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling MainHostWindow.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode1.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode2.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode3.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode4.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-include $(OBJECTS:%.o=%.d)

+ 2
- 2
extras/binarybuilder/Builds/Linux/Makefile View File

@@ -63,12 +63,12 @@ clean:
$(OBJDIR)/Main.o: ../../Source/Main.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling Main.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-include $(OBJECTS:%.o=%.d)

+ 6
- 6
extras/example projects/Builds/Linux/Makefile View File

@@ -67,32 +67,32 @@ clean:
$(OBJDIR)/Main.o: ../../Source/Main.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling Main.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/MainComponent.o: ../../Source/MainComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling MainComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode1.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode2.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode3.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode4.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-include $(OBJECTS:%.o=%.d)

+ 26
- 26
extras/juce demo/Builds/Linux/Makefile View File

@@ -87,132 +87,132 @@ clean:
$(OBJDIR)/ApplicationStartup.o: ../../Source/ApplicationStartup.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling ApplicationStartup.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/MainDemoWindow.o: ../../Source/MainDemoWindow.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling MainDemoWindow.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/AudioDemoLatencyPage.o: ../../Source/demos/AudioDemoLatencyPage.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling AudioDemoLatencyPage.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/AudioDemoPlaybackPage.o: ../../Source/demos/AudioDemoPlaybackPage.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling AudioDemoPlaybackPage.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/AudioDemoRecordPage.o: ../../Source/demos/AudioDemoRecordPage.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling AudioDemoRecordPage.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/AudioDemoSetupPage.o: ../../Source/demos/AudioDemoSetupPage.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling AudioDemoSetupPage.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/AudioDemoSynthPage.o: ../../Source/demos/AudioDemoSynthPage.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling AudioDemoSynthPage.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/AudioDemoTabComponent.o: ../../Source/demos/AudioDemoTabComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling AudioDemoTabComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/CameraDemo.o: ../../Source/demos/CameraDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling CameraDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/CodeEditorDemo.o: ../../Source/demos/CodeEditorDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling CodeEditorDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/DragAndDropDemo.o: ../../Source/demos/DragAndDropDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling DragAndDropDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/FontsAndTextDemo.o: ../../Source/demos/FontsAndTextDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling FontsAndTextDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/InterprocessCommsDemo.o: ../../Source/demos/InterprocessCommsDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling InterprocessCommsDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/OpenGLDemo.o: ../../Source/demos/OpenGLDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling OpenGLDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/QuickTimeDemo.o: ../../Source/demos/QuickTimeDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling QuickTimeDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/RenderingTestComponent.o: ../../Source/demos/RenderingTestComponent.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling RenderingTestComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/TableDemo.o: ../../Source/demos/TableDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling TableDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/ThreadingDemo.o: ../../Source/demos/ThreadingDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling ThreadingDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/TreeViewDemo.o: ../../Source/demos/TreeViewDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling TreeViewDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/WebBrowserDemo.o: ../../Source/demos/WebBrowserDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling WebBrowserDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/WidgetsDemo.o: ../../Source/demos/WidgetsDemo.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling WidgetsDemo.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling BinaryData.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode1.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode2.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode3.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@echo "Compiling JuceLibraryCode4.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-include $(OBJECTS:%.o=%.d)

+ 1346
- 495
juce_amalgamated.cpp
File diff suppressed because it is too large
View File


+ 717
- 392
juce_amalgamated.h
File diff suppressed because it is too large
View File


+ 1
- 1
src/containers/juce_Array.h View File

@@ -150,7 +150,7 @@ public:
return false;
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 true;


+ 15
- 0
src/containers/juce_NamedValueSet.cpp View File

@@ -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()
{
@@ -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()
{
return values.size();


+ 4
- 0
src/containers/juce_NamedValueSet.h View File

@@ -51,6 +51,9 @@ public:
/** Destructor. */
~NamedValueSet();
bool operator== (const NamedValueSet& other) const;
bool operator!= (const NamedValueSet& other) const;
//==============================================================================
/** Returns the total number of values that the set contains. */
int size() const throw();
@@ -108,6 +111,7 @@ private:
{
NamedValue() throw();
NamedValue (const Identifier& name, const var& value);
bool operator== (const NamedValue& other) const throw();
Identifier name;
var value;


+ 25
- 3
src/containers/juce_ValueTree.cpp View File

@@ -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()
: object (0)
@@ -546,16 +562,22 @@ ValueTree::~ValueTree()
object->valueTreesWithListeners.removeValue (this);
}
bool ValueTree::operator== (const ValueTree& other) const
bool ValueTree::operator== (const ValueTree& other) const throw()
{
return object == other.object;
}
bool ValueTree::operator!= (const ValueTree& other) const
bool ValueTree::operator!= (const ValueTree& other) const throw()
{
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
{
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;
}
void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager)
void ValueTree::addChild (const ValueTree& child, int index, UndoManager* const undoManager)
{
if (object != 0)
object->addChild (child.object, index, undoManager);


+ 12
- 3
src/containers/juce_ValueTree.h View File

@@ -102,13 +102,21 @@ public:
Note that this isn't a value comparison - two independently-created trees which
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.
Note that this isn't a value comparison - two independently-created trees which
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.
@@ -233,7 +241,7 @@ public:
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
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.
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 removeAllChildren (UndoManager*);
void moveChild (int currentIndex, int newIndex, UndoManager*);
bool isEquivalentTo (const SharedObject& other) const;
XmlElement* createXml() const;
juce_UseDebuggingNewOperator


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 5
#define JUCE_BUILDNUMBER 6
/** Current Juce version number.


+ 1
- 2
src/gui/components/controls/juce_ListBox.cpp View File

@@ -877,8 +877,7 @@ void ListBox::setHeaderComponent (Component* const newHeaderComponent)
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)


+ 3
- 2
src/gui/components/controls/juce_TreeView.cpp View File

@@ -1338,8 +1338,9 @@ void TreeViewItem::repaintItem() const
{
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);
}
}


+ 6
- 1
src/gui/components/juce_Component.cpp View File

@@ -1555,6 +1555,11 @@ void Component::repaint (const int x, const int y,
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)
{
// 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();
if (peer != 0)
peer->repaint (x, y, w, h);
peer->repaint (Rectangle<int> (x, y, w, h));
}
}
}


+ 15
- 0
src/gui/components/juce_Component.h View File

@@ -819,6 +819,21 @@ public:
*/
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.


+ 5
- 5
src/gui/components/special/juce_MagnifierComponent.cpp View File

@@ -117,14 +117,14 @@ public:
&& ((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();
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()


+ 1
- 1
src/gui/components/windows/juce_ComponentPeer.h View File

@@ -281,7 +281,7 @@ public:
//==============================================================================
/** 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
of any areas of this window that need repainting.


+ 1
- 3
src/gui/components/windows/juce_DocumentWindow.cpp View File

@@ -95,9 +95,7 @@ DocumentWindow::~DocumentWindow()
//==============================================================================
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)


+ 2
- 1
src/gui/graphics/contexts/juce_EdgeTable.h View File

@@ -177,12 +177,13 @@ public:
x = endX;
}
levelAccumulator >>= 8;
if (levelAccumulator > 0)
{
x >>= 8;
jassert (x >= bounds.getX() && x < bounds.getRight());
levelAccumulator >>= 8;
if (levelAccumulator >> 8)
iterationCallback.handleEdgeTablePixelFull (x);
else


+ 16
- 0
src/gui/graphics/contexts/juce_FillType.cpp View File

@@ -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()
{
gradient = 0;
@@ -110,4 +120,10 @@ void FillType::setOpacity (const float newOpacity) throw()
colour = colour.withAlpha (newOpacity);
}
bool FillType::isInvisible() const throw()
{
return colour.isTransparent() || (gradient != 0 && gradient->isInvisible());
}
END_JUCE_NAMESPACE

+ 6
- 0
src/gui/graphics/contexts/juce_FillType.h View File

@@ -103,6 +103,12 @@ public:
*/
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.
If the fill type is not a solid colour, the alpha channel of this colour indicates


+ 26
- 29
src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp View File

@@ -1899,41 +1899,38 @@ public:
shapeToFill = clip->applyClipTo (shapeToFill);
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);
}
}


+ 129
- 3
src/gui/graphics/drawables/juce_Drawable.cpp View File

@@ -36,7 +36,6 @@ BEGIN_JUCE_NAMESPACE
#include "../../../text/juce_XmlDocument.h"
#include "../../../io/files/juce_FileInputStream.h"
const Identifier Drawable::idProperty ("id");
//==============================================================================
Drawable::RenderingContext::RenderingContext (Graphics& g_,
@@ -50,6 +49,7 @@ Drawable::RenderingContext::RenderingContext (Graphics& g_,
//==============================================================================
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));
}
@@ -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

+ 26
- 1
src/gui/graphics/drawables/juce_Drawable.h View File

@@ -27,8 +27,10 @@
#define __JUCE_DRAWABLE_JUCEHEADER__
#include "../contexts/juce_Graphics.h"
#include "../geometry/juce_RelativeCoordinate.h"
#include "../../../text/juce_XmlElement.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. */
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
protected:
static const Identifier idProperty;
friend class DrawableComposite;
DrawableComposite* parent;
virtual void invalidatePoints() = 0;
private:
String name;


+ 321
- 63
src/gui/graphics/drawables/juce_DrawableComposite.cpp View File

@@ -37,8 +37,21 @@ BEGIN_JUCE_NAMESPACE
//==============================================================================
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()
@@ -51,7 +64,9 @@ void DrawableComposite::insertDrawable (Drawable* drawable, const int index)
if (drawable != 0)
{
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);
drawable->parent = this;
}
}
@@ -71,9 +86,9 @@ void DrawableComposite::bringToFront (const int index)
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[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
@@ -95,7 +169,7 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const
if (context.opacity >= 1.0f || drawables.size() == 1)
{
Drawable::RenderingContext contextCopy (context);
contextCopy.transform = getTransform().followedBy (context.transform);
contextCopy.transform = calculateTransform().followedBy (context.transform);
for (int i = 0; i < drawables.size(); ++i)
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
{
Rectangle<float> bounds;
@@ -133,12 +234,12 @@ const Rectangle<float> DrawableComposite::getUntransformedBounds() const
const Rectangle<float> DrawableComposite::getBounds() const
{
return getUntransformedBounds().transformed (getTransform());
return getUntransformedBounds().transformed (calculateTransform());
}
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)
if (drawables.getUnchecked(i)->hitTest (x, y))
@@ -149,125 +250,282 @@ bool DrawableComposite::hitTest (float x, float y) 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)
dc->drawables.add (drawables.getUnchecked(i)->createCopy());
return dc;
drawables.getUnchecked(i)->invalidatePoints();
}
//==============================================================================
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;
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]
|| controlPoints[1] != newControlPoint[1]
|| controlPoints[2] != newControlPoint[2])
{
controlPointsChanged = true;
redrawAll = true;
damageRect = getUntransformedBounds();
controlPoints[0] = newControlPoint[0];
controlPoints[1] = newControlPoint[1];
controlPoints[2] = newControlPoint[2];
}
// Remove deleted markers...
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);
}
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];
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
{
damageRect = damageRect.getUnion (d->getBounds());
d = createFromValueTree (childTree, imageProvider);
d = createFromValueTree (newDrawable, imageProvider);
d->parent = this;
drawables.set (i, d);
damageRect = damageRect.getUnion (d->getBounds());
}
}
else
{
d = createFromValueTree (childTree, imageProvider);
d = createFromValueTree (newDrawable, imageProvider);
d->parent = this;
drawables.set (i, d);
damageRect = damageRect.getUnion (d->getBounds());
}
}
if (controlPointsChanged)
if (redrawAll)
damageRect = damageRect.getUnion (getUntransformedBounds());
return damageRect.transformed (getTransform());
return damageRect.transformed (calculateTransform());
}
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;
}


+ 73
- 16
src/gui/graphics/drawables/juce_DrawableComposite.h View File

@@ -35,14 +35,17 @@
@see Drawable
*/
class JUCE_API DrawableComposite : public Drawable
class JUCE_API DrawableComposite : public Drawable,
public RelativeCoordinate::NamedCoordinateFinder
{
public:
//==============================================================================
/** Creates a composite Drawable.
*/
/** Creates a composite Drawable. */
DrawableComposite();
/** Creates a copy of a DrawableComposite. */
DrawableComposite (const DrawableComposite& other);
/** Destructor. */
virtual ~DrawableComposite();
@@ -122,27 +125,44 @@ public:
@param targetPositionForX0Y1 the position that the local coordinate (0, 1) should be
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
coordinate space when rendering this object.
@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
coordinate space when rendering this object.
@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
coordinate space when rendering this object.
@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 */
@@ -152,12 +172,10 @@ public:
/** @internal */
bool hitTest (float x, float y) const;
/** @internal */
int getNumControlPoints() const;
/** @internal */
const Point<float> getControlPoint (int index) const;
/** @internal */
Drawable* createCopy() const;
/** @internal */
void invalidatePoints();
/** @internal */
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
/** @internal */
const ValueTree createValueTree (ImageProvider* imageProvider) const;
@@ -165,18 +183,57 @@ public:
static const Identifier valueTreeType;
/** @internal */
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
private:
OwnedArray <Drawable> drawables;
Point<float> controlPoints[3];
RelativePoint controlPoints[3];
OwnedArray <Marker> markers;
const Rectangle<float> getUntransformedBounds() const;
const AffineTransform getTransform() const;
const AffineTransform calculateTransform() const;
DrawableComposite (const DrawableComposite&);
DrawableComposite& operator= (const DrawableComposite&);
};


+ 162
- 112
src/gui/graphics/drawables/juce_DrawableImage.cpp View File

@@ -27,8 +27,8 @@
BEGIN_JUCE_NAMESPACE
#include "juce_DrawableImage.h"
#include "juce_DrawableComposite.h"
#include "../imaging/juce_ImageCache.h"
@@ -39,47 +39,58 @@ DrawableImage::DrawableImage()
opacity (1.0f),
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)
{
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,
const bool releaseWhenNotNeeded)
{
clearImage();
if (canDeleteImage)
ImageCache::releaseOrDelete (image);
image = imageToUse;
canDeleteImage = releaseWhenNotNeeded;
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;
}
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[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)
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(),
bl.getX(), bl.getY());
}
@@ -120,7 +135,7 @@ void DrawableImage::render (const Drawable::RenderingContext& context) const
{
if (image != 0)
{
const AffineTransform t (getTransform().followedBy (context.transform));
const AffineTransform t (calculateTransform().followedBy (context.transform));
if (opacity > 0.0f && ! overlayColour.isOpaque())
{
@@ -141,7 +156,11 @@ const Rectangle<float> DrawableImage::getBounds() const
if (image == 0)
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 maxX = minX;
float minY = bottomRight.getY();
@@ -149,10 +168,10 @@ const Rectangle<float> DrawableImage::getBounds() const
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);
@@ -163,7 +182,7 @@ bool DrawableImage::hitTest (float x, float y) const
if (image == 0)
return false;
getTransform().inverted().transformPoint (x, y);
calculateTransform().inverted().transformPoint (x, y);
const int ix = roundToInt (x);
const int iy = roundToInt (y);
@@ -177,81 +196,117 @@ bool DrawableImage::hitTest (float x, float y) 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;
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
|| controlPoints[0] != newControlPoint[0]
@@ -266,7 +321,10 @@ const Rectangle<float> DrawableImage::refreshFromValueTree (const ValueTree& tre
if (image != newImage)
{
ImageCache::release (image);
if (canDeleteImage)
ImageCache::releaseOrDelete (image);
canDeleteImage = true;
image = newImage;
}
@@ -279,33 +337,25 @@ const Rectangle<float> DrawableImage::refreshFromValueTree (const ValueTree& tre
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)
{
jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them!
if (imageProvider != 0)
v.setProperty (DrawableImageHelpers::image, imageProvider->getIdentifierForImage (image), 0);
v.setImageIdentifier (imageProvider->getIdentifierForImage (image), 0);
}
return v;
return tree;
}


+ 41
- 13
src/gui/graphics/drawables/juce_DrawableImage.h View File

@@ -40,6 +40,7 @@ class JUCE_API DrawableImage : public Drawable
public:
//==============================================================================
DrawableImage();
DrawableImage (const DrawableImage& other);
/** Destructor. */
virtual ~DrawableImage();
@@ -59,7 +60,7 @@ public:
with ImageCache and pass it in here with releaseWhenNotNeeded = true, then
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,
then the image will be deleted when this object no longer
needs it - unless the image was created by the ImageCache,
@@ -70,9 +71,6 @@ public:
/** Returns the current 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. */
void setOpacity (float newOpacity);
@@ -103,27 +101,27 @@ public:
@param imageBottomLeftPosition the position that the image's bottom-left corner should be mapped to
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
coordinate space when rendering this object.
@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
coordinate space when rendering this object.
@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
coordinate space when rendering this object.
@see setTransform
*/
const Point<float>& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; }
const RelativePoint& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; }
//==============================================================================
/** @internal */
@@ -135,6 +133,8 @@ public:
/** @internal */
Drawable* createCopy() const;
/** @internal */
void invalidatePoints();
/** @internal */
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
/** @internal */
const ValueTree createValueTree (ImageProvider* imageProvider) const;
@@ -143,6 +143,35 @@ public:
/** @internal */
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
@@ -151,11 +180,10 @@ private:
bool canDeleteImage;
float opacity;
Colour overlayColour;
Point<float> controlPoints[3];
RelativePoint controlPoints[3];
const AffineTransform getTransform() const;
const AffineTransform calculateTransform() const;
DrawableImage (const DrawableImage&);
DrawableImage& operator= (const DrawableImage&);
};


+ 172
- 136
src/gui/graphics/drawables/juce_DrawablePath.cpp View File

@@ -28,6 +28,7 @@
BEGIN_JUCE_NAMESPACE
#include "juce_DrawablePath.h"
#include "juce_DrawableComposite.h"
#include "../../../io/streams/juce_MemoryOutputStream.h"
@@ -35,10 +36,25 @@ BEGIN_JUCE_NAMESPACE
DrawablePath::DrawablePath()
: mainFill (Colours::black),
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()
{
}
@@ -47,7 +63,7 @@ DrawablePath::~DrawablePath()
void DrawablePath::setPath (const Path& newPath)
{
path = newPath;
updateOutline();
strokeNeedsUpdating = true;
}
void DrawablePath::setFill (const FillType& newFill)
@@ -63,7 +79,7 @@ void DrawablePath::setStrokeFill (const FillType& newFill)
void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType)
{
strokeType = newStrokeType;
updateOutline();
strokeNeedsUpdating = true;
}
void DrawablePath::setStrokeThickness (const float newThickness)
@@ -71,6 +87,55 @@ void DrawablePath::setStrokeThickness (const float newThickness)
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
{
@@ -81,10 +146,10 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const
f.transform = f.transform.followedBy (context.transform);
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);
if (f.isGradient())
@@ -92,162 +157,133 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const
f.transform = f.transform.followedBy (context.transform);
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
{
if (strokeType.getStrokeThickness() > 0.0f)
return stroke.getBounds();
if (isStrokeVisible())
return getStrokePath().getBounds();
else
return path.getBounds();
return getPath().getBounds();
}
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
{
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");
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)
{
jassert (tree.hasType (valueTreeType));
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;
newPath.restoreFromString (tree [DrawablePathHelpers::path]);
newRelativePath->createPath (newPath, parent);
if (! newRelativePath->containsAnyDynamicPoints())
newRelativePath = 0;
if (strokeType != newStroke || path != newPath)
{
@@ -257,6 +293,8 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree
needsRedraw = true;
}
relativePath = newRelativePath.release();
if (needsRedraw)
damageRect = damageRect.getUnion (getBounds());
@@ -265,22 +303,20 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree
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
- 8
src/gui/graphics/drawables/juce_DrawablePath.h View File

@@ -40,9 +40,9 @@ class JUCE_API DrawablePath : public Drawable
{
public:
//==============================================================================
/** Creates a DrawablePath.
*/
/** Creates a DrawablePath. */
DrawablePath();
DrawablePath (const DrawablePath& other);
/** Destructor. */
virtual ~DrawablePath();
@@ -54,9 +54,6 @@ public:
*/
void setPath (const Path& newPath);
/** Returns the current path. */
const Path& getPath() const throw() { return 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
@@ -97,6 +94,13 @@ public:
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 */
void render (const Drawable::RenderingContext& context) const;
@@ -107,6 +111,8 @@ public:
/** @internal */
Drawable* createCopy() const;
/** @internal */
void invalidatePoints();
/** @internal */
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
/** @internal */
const ValueTree createValueTree (ImageProvider* imageProvider) const;
@@ -115,17 +121,43 @@ public:
/** @internal */
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
private:
Path path, stroke;
FillType mainFill, strokeFill;
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&);
};


+ 25
- 11
src/gui/graphics/drawables/juce_DrawableText.cpp View File

@@ -36,6 +36,12 @@ DrawableText::DrawableText()
{
}
DrawableText::DrawableText (const DrawableText& other)
: text (other.text),
colour (other.colour)
{
}
DrawableText::~DrawableText()
{
}
@@ -76,21 +82,28 @@ bool DrawableText::hitTest (float x, float y) 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::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)
{
jassert (tree.hasType (valueTreeType));
setName (tree [idProperty]);
ValueTreeWrapper v (tree);
setName (v.getID());
jassertfalse; // xxx not finished!
@@ -99,13 +112,14 @@ const Rectangle<float> DrawableText::refreshFromValueTree (const ValueTree& tree
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!
return v;
return tree;
}


+ 16
- 1
src/gui/graphics/drawables/juce_DrawableText.h View File

@@ -42,6 +42,7 @@ public:
//==============================================================================
/** Creates a DrawableText object. */
DrawableText();
DrawableText (const DrawableText& other);
/** Destructor. */
virtual ~DrawableText();
@@ -78,6 +79,8 @@ public:
/** @internal */
Drawable* createCopy() const;
/** @internal */
void invalidatePoints();
/** @internal */
const Rectangle<float> refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider);
/** @internal */
const ValueTree createValueTree (ImageProvider* imageProvider) const;
@@ -86,6 +89,19 @@ public:
/** @internal */
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
@@ -93,7 +109,6 @@ private:
GlyphArrangement text;
Colour colour;
DrawableText (const DrawableText&);
DrawableText& operator= (const DrawableText&);
};


+ 5
- 7
src/gui/graphics/geometry/juce_Path.cpp View File

@@ -74,12 +74,7 @@ namespace PathHelpers
while (*t != 0 && ! CharacterFunctions::isWhitespace (*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;
float values [6];
while (*t != 0)
for (;;)
{
const String token (PathHelpers::nextToken (t));
const juce_wchar firstChar = token[0];
int startNum = 0;
if (firstChar == 0)
break;
if (firstChar == 'm' || firstChar == 'l')
{
marker = firstChar;


+ 429
- 86
src/gui/graphics/geometry/juce_RelativeCoordinate.cpp View File

@@ -28,6 +28,8 @@
BEGIN_JUCE_NAMESPACE
#include "juce_RelativeCoordinate.h"
#include "../../../io/streams/juce_MemoryOutputStream.h"
//==============================================================================
namespace RelativeCoordinateHelpers
@@ -61,9 +63,10 @@ namespace RelativeCoordinateHelpers
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;
}
static void skipComma (const String& s, int& i)
{
skipWhitespace (s, i);
if (s[i] == ',')
++i;
}
static const String readAnchorName (const String& s, int& i)
{
skipWhitespace (s, i);
@@ -126,10 +136,89 @@ namespace RelativeCoordinateHelpers
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)
{
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());
}
RelativeCoordinate::RelativeCoordinate (const String& s, const bool isHorizontal)
: value (0)
{
int i = 0;
*this = RelativeCoordinateHelpers::readNextCoordinate (s, i, isHorizontal);
}
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
{
@@ -186,7 +292,7 @@ const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate2() const
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))
return 0.0;
@@ -194,7 +300,7 @@ double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedC
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)
{
@@ -208,7 +314,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder, int
: pos1 + value;
}
double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) const
double RelativeCoordinate::resolve (const NamedCoordinateFinder* nameFinder) const
{
try
{
@@ -220,7 +326,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) con
return 0.0;
}
bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) const
bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder* nameFinder) const
{
try
{
@@ -234,7 +340,7 @@ bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) c
return false;
}
void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder& nameFinder)
void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder* nameFinder)
{
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);
@@ -267,8 +373,7 @@ void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder& nam
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;
@@ -281,65 +386,12 @@ bool RelativeCoordinate::references (const String& coordName, const NamedCoordin
|| (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
{
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_."));
@@ -392,7 +444,7 @@ void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const Named
moveToAbsolute (oldValue, nameFinder);
}
void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder& nameFinder)
void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder* nameFinder)
{
jassert (isProportional());
jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_."));
@@ -402,7 +454,7 @@ void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const Named
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;
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),
(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);
y.moveToAbsolute (newPos.getY(), nameFinder);
@@ -464,12 +531,17 @@ const String RelativePoint::toString() const
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);
y.renameAnchorIfUsed (oldName, newName, nameFinder);
}
bool RelativePoint::isDynamic() const
{
return x.isDynamic() || y.isDynamic();
}
//==============================================================================
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 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));
}
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);
right.moveToAbsolute (newPos.getRight(), nameFinder);
@@ -519,7 +602,7 @@ const String RelativeRectangle::toString() const
}
void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& newName,
const RelativeCoordinate::NamedCoordinateFinder& nameFinder)
const RelativeCoordinate::NamedCoordinateFinder* nameFinder)
{
left.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

+ 167
- 19
src/gui/graphics/geometry/juce_RelativeCoordinate.h View File

@@ -26,7 +26,9 @@
#ifndef __JUCE_RELATIVECOORDINATE_JUCEHEADER__
#define __JUCE_RELATIVECOORDINATE_JUCEHEADER__
#include "juce_Path.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
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
"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 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. */
~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.
@@ -145,15 +150,18 @@ public:
You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may
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.
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. */
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.
@@ -162,7 +170,7 @@ public:
or relative position to whatever value is necessary to make its resultant position
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.
@see toggleProportionality
@@ -173,7 +181,7 @@ public:
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.
*/
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.
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
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
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.
@@ -227,7 +235,7 @@ public:
instead.
*/
void renameAnchorIfUsed (const String& oldName, const String& newName,
const NamedCoordinateFinder& nameFinder);
const NamedCoordinateFinder* nameFinder);
//==============================================================================
/** Returns a string which represents this coordinate.
@@ -261,8 +269,8 @@ private:
String anchor1, anchor2;
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. */
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.
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.
@see toString
*/
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.
You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may
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.
@@ -301,7 +315,7 @@ public:
or relative positions to whatever values are necessary to make the resultant position
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.
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.
*/
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...
RelativeCoordinate x, y;
@@ -347,13 +364,16 @@ public:
*/
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.
You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may
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.
@@ -361,7 +381,7 @@ public:
or relative positions to whatever values are necessary to make the resultant position
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.
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.
*/
void renameAnchorIfUsed (const String& oldName, const String& newName,
const RelativeCoordinate::NamedCoordinateFinder& nameFinder);
const RelativeCoordinate::NamedCoordinateFinder* nameFinder);
// The actual rectangle coords...
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__

+ 3
- 0
src/gui/graphics/imaging/juce_ImageCache.cpp View File

@@ -131,6 +131,9 @@ void ImageCache::releaseOrDelete (Image* const imageToRelease)
bool ImageCache::isImageInCache (Image* const imageToLookFor)
{
if (imageToLookFor == 0)
return false;
if (instance != 0)
{
const ScopedLock sl (instance->lock);


+ 1
- 1
src/io/files/juce_DirectoryIterator.cpp View File

@@ -35,7 +35,7 @@ DirectoryIterator::DirectoryIterator (const File& directory,
bool isRecursive_,
const String& wildCard_,
const int whatToLookFor_)
: fileFinder (directory, isRecursive ? "*" : wildCard_),
: fileFinder (directory, isRecursive_ ? "*" : wildCard_),
wildCard (wildCard_),
path (File::addTrailingSeparator (directory.getFullPathName())),
index (-1),


+ 8
- 14
src/native/linux/juce_linux_Windowing.cpp View File

@@ -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()
@@ -1526,8 +1520,8 @@ public:
&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)
{
@@ -1537,8 +1531,8 @@ public:
XNextEvent (display, (XEvent*) &nextEvent);
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;
@@ -1838,12 +1832,12 @@ private:
}
}
void repaint (int x, int y, int w, int h)
void repaint (const Rectangle<int>& area)
{
if (! isTimerRunning())
startTimer (repaintTimerPeriod);
regionsNeedingRepaint.add (x, y, w, h);
regionsNeedingRepaint.add (area);
}
void performAnyPendingRepaintsNow()


+ 6
- 5
src/native/mac/juce_iphone_UIViewComponentPeer.mm View File

@@ -138,7 +138,7 @@ public:
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();
//==============================================================================
@@ -849,19 +849,20 @@ public:
void messageCallback()
{
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())
{
(new AsyncRepaintMessage (this, Rectangle<int> (x, y, w, h)))->post();
(new AsyncRepaintMessage (this, area))->post();
}
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())];
}
}


+ 6
- 6
src/native/mac/juce_mac_NSViewComponentPeer.mm View File

@@ -253,7 +253,7 @@ public:
void textInputRequired (const Point<int>& position);
//==============================================================================
void repaint (int x, int y, int w, int h);
void repaint (const Rectangle<int>& area);
void performAnyPendingRepaintsNow();
//==============================================================================
@@ -1631,20 +1631,20 @@ public:
void messageCallback()
{
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)
{
(new AsyncRepaintMessage (this, Rectangle<int> (x, y, w, h)))->post();
(new AsyncRepaintMessage (this, area))->post();
}
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())];
}
}


+ 4
- 1
src/native/windows/juce_win32_ASIO.cpp View File

@@ -597,7 +597,10 @@ public:
Thread::sleep (20);
isStarted = false;
isOpen_ = false;
close();
const String errorCopy (error);
close(); // (this resets the error string)
error = errorCopy;
}
needToReset = false;


+ 1
- 2
src/native/windows/juce_win32_OpenGLComponent.cpp View File

@@ -288,8 +288,7 @@ public:
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()


+ 1
- 1
src/native/windows/juce_win32_WASAPI.cpp View File

@@ -685,7 +685,7 @@ public:
int getInputLatencyInSamples() { return latencyIn; }
const BigInteger getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->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,


+ 2
- 2
src/native/windows/juce_win32_Windowing.cpp View File

@@ -705,9 +705,9 @@ public:
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);
}


+ 2
- 6
src/text/juce_String.cpp View File

@@ -1055,9 +1055,7 @@ static int indexOfMatch (const juce_wchar* const wildcard,
else
{
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;
}
@@ -1093,9 +1091,7 @@ bool String::matchesWildcard (const String& wildcard, const bool ignoreCase) con
else
{
return wc == '*' && (wildcard [i + 1] == 0
|| indexOfMatch (wildcard.text + i + 1,
text + i,
ignoreCase) >= 0);
|| indexOfMatch (wildcard.text + i + 1, text + i, ignoreCase) >= 0);
}
}
}


Loading…
Cancel
Save