From 1b6eb960e3c003f8bc7344e6432084084f9a4204 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Tue, 25 May 2010 14:31:50 +0100 Subject: [PATCH] Added HTTP header retrieval functionality to the URL class. More drawable and Jucer development. --- .../Builds/Linux/Makefile | 12 +- .../The Jucer.xcodeproj/project.pbxproj | 18 +- .../Builds/VisualStudio2005/The Jucer.vcproj | 7 +- .../Builds/VisualStudio2008/The Jucer.vcproj | 7 +- extras/Jucer (experimental)/Jucer.jucer | 14 +- .../Types/jucer_ComponentTypeManager.cpp | 2 +- .../Types/jucer_ComponentTypeManager.h | 4 +- .../Component/jucer_ComponentDocument.cpp | 31 +- .../model/Component/jucer_ComponentDocument.h | 11 +- .../model/Drawable/jucer_DrawableDocument.cpp | 64 ++- .../model/Drawable/jucer_DrawableDocument.h | 12 +- .../Drawable/jucer_DrawableTypeHandler.h | 97 +++-- .../jucer_ComponentEditorCanvas.h | 43 +- .../jucer_ComponentEditorToolbar.h | 2 +- .../jucer_ComponentEditorTreeView.h | 2 +- .../jucer_DrawableEditorCanvas.h | 65 ++- .../ui/Editor Base/jucer_EditorCanvas.cpp | 43 +- .../ui/Editor Base/jucer_EditorCanvas.h | 4 +- .../Editor Base/jucer_EditorDragOperation.h | 82 ++-- ...nent.h => jucer_ColourPropertyComponent.h} | 24 +- .../utility/jucer_FillTypePropertyComponent.h | 207 ++++++++++ .../Source/utility/jucer_MarkerListBase.h | 35 +- .../Source/utility/jucer_StoredSettings.h | 14 +- juce_amalgamated.cpp | 385 +++++++++++++----- juce_amalgamated.h | 125 +++++- src/containers/juce_Array.h | 5 +- src/containers/juce_OwnedArray.h | 47 ++- src/gui/components/menus/juce_PopupMenu.cpp | 10 +- .../juce_ChoicePropertyComponent.cpp | 2 +- src/gui/graphics/drawables/juce_Drawable.cpp | 23 +- src/gui/graphics/drawables/juce_Drawable.h | 4 +- .../drawables/juce_DrawableComposite.cpp | 234 ++++++++--- .../drawables/juce_DrawableComposite.h | 30 +- .../graphics/drawables/juce_DrawablePath.cpp | 4 +- .../graphics/drawables/juce_DrawablePath.h | 1 - .../graphics/drawables/juce_DrawableText.cpp | 4 +- .../graphics/fonts/juce_GlyphArrangement.cpp | 4 +- .../graphics/fonts/juce_GlyphArrangement.h | 3 +- src/gui/graphics/fonts/juce_TextLayout.cpp | 4 +- .../geometry/juce_RelativeCoordinate.h | 24 ++ src/io/network/juce_URL.cpp | 14 +- src/io/network/juce_URL.h | 11 +- src/native/linux/juce_linux_Network.cpp | 11 + src/native/linux/juce_linux_Windowing.cpp | 3 + src/native/mac/juce_mac_Network.mm | 29 ++ src/native/windows/juce_win32_Network.cpp | 41 +- src/text/juce_CharacterFunctions.cpp | 4 +- 47 files changed, 1383 insertions(+), 439 deletions(-) rename extras/Jucer (experimental)/Source/utility/{jucer_ColourEditorComponent.h => jucer_ColourPropertyComponent.h} (84%) create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_FillTypePropertyComponent.h diff --git a/extras/Jucer (experimental)/Builds/Linux/Makefile b/extras/Jucer (experimental)/Builds/Linux/Makefile index 41ec312d9f..80c31c32da 100644 --- a/extras/Jucer (experimental)/Builds/Linux/Makefile +++ b/extras/Jucer (experimental)/Builds/Linux/Makefile @@ -69,8 +69,8 @@ OBJECTS := \ $(OBJDIR)/jucer_TreeViewTypes.o \ $(OBJDIR)/jucer_CodeHelpers.o \ $(OBJDIR)/jucer_FileHelpers.o \ - $(OBJDIR)/jucer_StoredSettings.o \ $(OBJDIR)/jucer_MiscUtilities.o \ + $(OBJDIR)/jucer_StoredSettings.o \ $(OBJDIR)/jucer_Main.o \ $(OBJDIR)/BinaryData.o \ $(OBJDIR)/JuceLibraryCode1.o \ @@ -223,16 +223,16 @@ $(OBJDIR)/jucer_FileHelpers.o: ../../Source/utility/jucer_FileHelpers.cpp @echo "Compiling jucer_FileHelpers.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/jucer_StoredSettings.o: ../../Source/utility/jucer_StoredSettings.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling jucer_StoredSettings.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/jucer_MiscUtilities.o: ../../Source/utility/jucer_MiscUtilities.cpp -@mkdir -p $(OBJDIR) @echo "Compiling jucer_MiscUtilities.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/jucer_StoredSettings.o: ../../Source/utility/jucer_StoredSettings.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling jucer_StoredSettings.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/jucer_Main.o: ../../Source/jucer_Main.cpp -@mkdir -p $(OBJDIR) @echo "Compiling jucer_Main.cpp" diff --git a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj index f737d37c7f..5a93e5cc50 100644 --- a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj +++ b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj @@ -43,8 +43,8 @@ 58BF60E87F9A8EDCACC5D1AE = { isa = PBXBuildFile; fileRef = 939E2A7946081DB4D21B89B6; }; 28B94C4BB7B572E6F5419E5D = { isa = PBXBuildFile; fileRef = 78E0309CB6D5E7E80B5BED7D; }; 12C1D006503C664FF07F476F = { isa = PBXBuildFile; fileRef = 5533704F0D30A9C62058FEC7; }; - DDAB225ABE572196882C3524 = { isa = PBXBuildFile; fileRef = 7A1CD936BD306A6E0BEFB046; }; 92612DD3884793248F1EC45A = { isa = PBXBuildFile; fileRef = 49A1C43070A68985C25F34C7; }; + DDAB225ABE572196882C3524 = { isa = PBXBuildFile; fileRef = 7A1CD936BD306A6E0BEFB046; }; 6B6B0EBBE899B0ACDCAD92F5 = { isa = PBXBuildFile; fileRef = 0DC331A7B856F30AD266A3E6; }; 69CA42E334E4BA09E4FE8B65 = { isa = PBXBuildFile; fileRef = D02830A908A07FD46F7387DA; }; 0C3A85F58C34FA91D16664EB = { isa = PBXBuildFile; fileRef = 933DADF4F3906510EA714CC0; }; @@ -141,18 +141,19 @@ 119004FCF601190AC8929BBD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TreeViewTypes.h; path = "../../Source/ui/Project Editor/jucer_TreeViewTypes.h"; sourceTree = SOURCE_ROOT; }; 78E0309CB6D5E7E80B5BED7D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_CodeHelpers.cpp; path = ../../Source/utility/jucer_CodeHelpers.cpp; sourceTree = SOURCE_ROOT; }; 9C58E022906C193862372BC1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CodeHelpers.h; path = ../../Source/utility/jucer_CodeHelpers.h; sourceTree = SOURCE_ROOT; }; - AAF3C58696944A256CA61730 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ColourEditorComponent.h; path = ../../Source/utility/jucer_ColourEditorComponent.h; sourceTree = SOURCE_ROOT; }; + F09B64E34443A4030EA1DA30 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ColourPropertyComponent.h; path = ../../Source/utility/jucer_ColourPropertyComponent.h; sourceTree = SOURCE_ROOT; }; 9736236B5C4D6A16FC7E03AC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Colours.h; path = ../../Source/utility/jucer_Colours.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; }; + BE9E52ADB12C9D4F783AFE42 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_FillTypePropertyComponent.h; path = ../../Source/utility/jucer_FillTypePropertyComponent.h; sourceTree = SOURCE_ROOT; }; 848F9EFCBB691000A4B32346 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_MarkerListBase.h; path = ../../Source/utility/jucer_MarkerListBase.h; sourceTree = SOURCE_ROOT; }; + 49A1C43070A68985C25F34C7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_MiscUtilities.cpp; path = ../../Source/utility/jucer_MiscUtilities.cpp; sourceTree = SOURCE_ROOT; }; + 2B2A6FCA85F56682698864EC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_MiscUtilities.h; path = ../../Source/utility/jucer_MiscUtilities.h; sourceTree = SOURCE_ROOT; }; F99858EE1CD3B23057B8BEBD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_RelativePath.h; path = ../../Source/utility/jucer_RelativePath.h; sourceTree = SOURCE_ROOT; }; 7A1CD936BD306A6E0BEFB046 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_StoredSettings.cpp; path = ../../Source/utility/jucer_StoredSettings.cpp; sourceTree = SOURCE_ROOT; }; E99413C9561A66310DAD5EEB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_StoredSettings.h; path = ../../Source/utility/jucer_StoredSettings.h; sourceTree = SOURCE_ROOT; }; 7530E3F9877E4F322CD81801 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TickIterator.h; path = ../../Source/utility/jucer_TickIterator.h; sourceTree = SOURCE_ROOT; }; - 49A1C43070A68985C25F34C7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_MiscUtilities.cpp; path = ../../Source/utility/jucer_MiscUtilities.cpp; sourceTree = SOURCE_ROOT; }; - 2B2A6FCA85F56682698864EC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_MiscUtilities.h; path = ../../Source/utility/jucer_MiscUtilities.h; sourceTree = SOURCE_ROOT; }; C693F6EF4381328D5F5891CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ValueSourceHelpers.h; path = ../../Source/utility/jucer_ValueSourceHelpers.h; sourceTree = SOURCE_ROOT; }; 0CA0CCCEBFA0AC8C577FC915 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Headers.h; path = ../../Source/jucer_Headers.h; sourceTree = SOURCE_ROOT; }; 0DC331A7B856F30AD266A3E6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Main.cpp; path = ../../Source/jucer_Main.cpp; sourceTree = SOURCE_ROOT; }; @@ -277,18 +278,19 @@ 14B5B6D3D07644058F0F526F = { isa = PBXGroup; children = ( 78E0309CB6D5E7E80B5BED7D, 9C58E022906C193862372BC1, - AAF3C58696944A256CA61730, + F09B64E34443A4030EA1DA30, 9736236B5C4D6A16FC7E03AC, CC9A3046B8B9FCDFE2092F51, 5533704F0D30A9C62058FEC7, 27E71DE11448E4D6721D5508, + BE9E52ADB12C9D4F783AFE42, 848F9EFCBB691000A4B32346, + 49A1C43070A68985C25F34C7, + 2B2A6FCA85F56682698864EC, F99858EE1CD3B23057B8BEBD, 7A1CD936BD306A6E0BEFB046, E99413C9561A66310DAD5EEB, 7530E3F9877E4F322CD81801, - 49A1C43070A68985C25F34C7, - 2B2A6FCA85F56682698864EC, C693F6EF4381328D5F5891CF ); name = Utility; sourceTree = ""; }; FAFBE12D4C5798FC1BB3A4BA = { isa = PBXGroup; children = ( 0CA0CCCEBFA0AC8C577FC915, @@ -436,8 +438,8 @@ 58BF60E87F9A8EDCACC5D1AE, 28B94C4BB7B572E6F5419E5D, 12C1D006503C664FF07F476F, - DDAB225ABE572196882C3524, 92612DD3884793248F1EC45A, + DDAB225ABE572196882C3524, 6B6B0EBBE899B0ACDCAD92F5, 69CA42E334E4BA09E4FE8B65, 0C3A85F58C34FA91D16664EB, diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj index 1448d21fc2..042d820686 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj @@ -228,18 +228,19 @@ - + + + + - - diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj index 6117d47c36..286e77a0f2 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj @@ -228,18 +228,19 @@ - + + + + - - diff --git a/extras/Jucer (experimental)/Jucer.jucer b/extras/Jucer (experimental)/Jucer.jucer index 27e09c6714..6e4713feb0 100644 --- a/extras/Jucer (experimental)/Jucer.jucer +++ b/extras/Jucer (experimental)/Jucer.jucer @@ -203,8 +203,8 @@ file="Source/utility/jucer_CodeHelpers.cpp"/> - + + + + - - diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp index 13ce6e876d..32840489c6 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp @@ -355,7 +355,7 @@ void ComponentTypeInstance::addFocusOrderProperty (Array & p void ComponentTypeInstance::addColourProperty (Array & props, int colourId, const String& name, const Identifier& propertyName) { - props.add (new ColourPropertyComponent (document, name, getValue (propertyName), + props.add (new ColourPropertyComponent (document.getUndoManager(), name, getValue (propertyName), LookAndFeel::getDefaultLookAndFeel().findColour (colourId), true)); } diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h index 4f9f58e52f..5a9cefd8fc 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h @@ -28,7 +28,7 @@ #include "../../../jucer_Headers.h" #include "../jucer_ComponentDocument.h" -#include "../../../utility/jucer_ColourEditorComponent.h" +#include "../../../utility/jucer_ColourPropertyComponent.h" class ComponentTypeHandler; @@ -78,6 +78,8 @@ private: //============================================================================== ComponentDocument& document; ValueTree state; + + ComponentTypeInstance& operator= (const ComponentTypeInstance&); }; diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp index ba024a4c28..5af7a16211 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp @@ -502,15 +502,12 @@ const RelativeRectangle ComponentDocument::getCoordsFor (const ValueTree& state) return RelativeRectangle (state [compBoundsProperty]); } -bool ComponentDocument::setCoordsFor (ValueTree& state, const RelativeRectangle& pr) +void ComponentDocument::setCoordsFor (ValueTree& state, const RelativeRectangle& pr) { const String newBoundsString (pr.toString()); - if (state[compBoundsProperty] == newBoundsString) - return false; - - state.setProperty (compBoundsProperty, newBoundsString, getUndoManager()); - return true; + if (state[compBoundsProperty] != newBoundsString) + state.setProperty (compBoundsProperty, newBoundsString, getUndoManager()); } const String ComponentDocument::getNonexistentMemberName (String name) @@ -695,8 +692,9 @@ void ComponentDocument::removeComponent (const ValueTree& state) //============================================================================== ComponentDocument::MarkerList::MarkerList (ComponentDocument& document_, const bool isX_) - : MarkerListBase (document_.getRoot().getChildWithName (isX_ ? markersGroupXTag : markersGroupYTag), isX_), - document (document_) + : MarkerListBase (isX_), + document (document_), + group (document_.getRoot().getChildWithName (isX_ ? markersGroupXTag : markersGroupYTag)) { jassert (group.isValid()); jassert (group.isAChildOf (document_.getRoot())); @@ -717,6 +715,21 @@ void ComponentDocument::MarkerList::renameAnchor (const String& oldName, const S document.renameAnchor (oldName, newName); } +void ComponentDocument::MarkerList::createMarker (const String& name, int position) +{ + ValueTree marker (getMarkerTag()); + marker.setProperty (getMarkerNameProperty(), name, 0); + marker.setProperty (getMarkerPosProperty(), RelativeCoordinate (position, isX).toString(), 0); + marker.setProperty (Ids::id_, createAlphaNumericUID(), 0); + group.addChild (marker, -1, getUndoManager()); +} + +void ComponentDocument::MarkerList::deleteMarker (ValueTree& markerState) +{ + renameAnchor (getName (markerState), String::empty); + group.removeChild (markerState, getUndoManager()); +} + const RelativeCoordinate ComponentDocument::MarkerList::findNamedCoordinate (const String& objectName, const String& edge) const { if (objectName == RelativeCoordinate::Strings::parent) @@ -780,7 +793,7 @@ bool ComponentDocument::MarkerList::createProperties (Array 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 (*this, "Position", marker, marker.getPropertyAsValue (getMarkerPosProperty(), document.getUndoManager()))); return true; } diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h index 4e1f3e452d..a63a7fcb4f 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h @@ -80,7 +80,7 @@ public: bool isStateForComponent (const ValueTree& storedState, Component* comp) const; void removeComponent (const ValueTree& state); const RelativeRectangle getCoordsFor (const ValueTree& componentState) const; - bool setCoordsFor (ValueTree& componentState, const RelativeRectangle& newSize); + void setCoordsFor (ValueTree& componentState, const RelativeRectangle& newSize); void renameAnchor (const String& oldName, const String& newName); // for RelativeCoordinate::Resolver: @@ -111,11 +111,20 @@ public: UndoManager* getUndoManager() const; void renameAnchor (const String& oldName, const String& newName); const String getNonexistentMarkerName (const String& name); + const String getId (const ValueTree& markerState) { return markerState [Ids::id_]; } + int size() const { return group.getNumChildren(); } + ValueTree getMarker (int index) const { return group.getChild (index); } + ValueTree getMarkerNamed (const String& name) const { return group.getChildWithProperty (getMarkerNameProperty(), name); } + bool contains (const ValueTree& markerState) const { return markerState.isAChildOf (group); } + void createMarker (const String& name, int position); + void deleteMarker (ValueTree& markerState); ComponentDocument& getDocument() throw() { return document; } + ValueTree& getGroup() { return group; } private: ComponentDocument& document; + ValueTree group; MarkerList (const MarkerList&); MarkerList& operator= (const MarkerList&); diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp index 5f38028e28..64216fce73 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp @@ -90,11 +90,16 @@ DrawableTypeHandler* DrawableTypeInstance::getHandler() const return h; } -bool DrawableTypeInstance::setBounds (Drawable* drawable, const Rectangle& newBounds) +void DrawableTypeInstance::setBounds (Drawable* drawable, const Rectangle& newBounds) { return getHandler()->setBounds (*this, drawable, newBounds); } +void DrawableTypeInstance::getAllControlPoints (Array & points) +{ + return getHandler()->getAllControlPoints (*this, points); +} + //============================================================================== namespace Tags @@ -227,7 +232,7 @@ void DrawableDocument::save (OutputStream& output) bool DrawableDocument::load (InputStream& input) { int64 originalPos = input.getPosition(); - ValueTree loadedTree ("dummy"); + ValueTree loadedTree; XmlDocument xmlDoc (input.readEntireStreamAsString()); ScopedPointer xml (xmlDoc.getDocumentElement()); @@ -247,6 +252,8 @@ bool DrawableDocument::load (InputStream& input) root.removeListener (this); root = loadedTree; root.addListener (this); + markersX = 0; + markersY = 0; valueTreeParentChanged (loadedTree); @@ -262,7 +269,6 @@ bool DrawableDocument::load (InputStream& input) void DrawableDocument::changed() { needsSaving = true; - sendChangeMessage (this); } DrawableComposite::ValueTreeWrapper DrawableDocument::getRootDrawableNode() const @@ -421,11 +427,48 @@ const RelativeCoordinate DrawableDocument::findNamedCoordinate (const String& ob //============================================================================== DrawableDocument::MarkerList::MarkerList (DrawableDocument& document_, bool isX_) - : MarkerListBase (document_.getRoot().getChildWithName (isX_ ? Tags::markersGroupXTag : Tags::markersGroupYTag), isX_), - document (document_) + : MarkerListBase (isX_), + document (document_), + object (document_.getRootDrawableNode()) { } +const String DrawableDocument::MarkerList::getId (const ValueTree& markerState) +{ + return markerState [DrawableComposite::ValueTreeWrapper::nameProperty]; +} + +int DrawableDocument::MarkerList::size() const +{ + return object.getNumMarkers (isX); +} + +ValueTree DrawableDocument::MarkerList::getMarker (int index) const +{ + return object.getMarkerState (isX, index); +} + +ValueTree DrawableDocument::MarkerList::getMarkerNamed (const String& name) const +{ + return object.getMarkerState (isX, name); +} + +bool DrawableDocument::MarkerList::contains (const ValueTree& markerState) const +{ + return object.containsMarker (isX, markerState); +} + +void DrawableDocument::MarkerList::createMarker (const String& name, int position) +{ + object.setMarker (isX, DrawableComposite::Marker (name, RelativeCoordinate ((double) position, isX)), + getUndoManager()); +} + +void DrawableDocument::MarkerList::deleteMarker (ValueTree& markerState) +{ + object.removeMarker (isX, markerState, getUndoManager()); +} + const RelativeCoordinate DrawableDocument::MarkerList::findNamedCoordinate (const String& objectName, const String& edge) const { if (objectName == "parent") @@ -443,14 +486,15 @@ const RelativeCoordinate DrawableDocument::MarkerList::findNamedCoordinate (cons bool DrawableDocument::MarkerList::createProperties (Array & props, const String& itemId) { - ValueTree marker (group.getChildWithProperty (getIdProperty(), itemId)); + ValueTree marker (getMarkerNamed (itemId)); if (marker.isValid()) { - props.add (new TextPropertyComponent (getNameAsValue (marker), "Marker Name", 256, false)); -// props.add (new MarkerPositionComponent (document, "Position", marker, - // marker.getPropertyAsValue (markerPosProperty, document.getUndoManager()), - // contains (marker))); + props.add (new TextPropertyComponent (marker.getPropertyAsValue (DrawableComposite::ValueTreeWrapper::nameProperty, getUndoManager()), + "Marker Name", 256, false)); + + props.add (new MarkerListBase::PositionPropertyComponent (*this, "Position", marker, + marker.getPropertyAsValue (DrawableComposite::ValueTreeWrapper::posProperty, getUndoManager()))); return true; } diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h index e97716104c..7fbd6e75bc 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h @@ -33,7 +33,6 @@ //============================================================================== class DrawableDocument : public ValueTree::Listener, - public ChangeBroadcaster, public Drawable::ImageProvider { public: @@ -53,9 +52,6 @@ public: ValueTree& getRoot() { return root; } DrawableComposite::ValueTreeWrapper getRootDrawableNode() const; -// Value getCanvasWidth() const { return getRootValueNonUndoable (Ids::width); } - // Value getCanvasHeight() const { return getRootValueNonUndoable (Ids::height); } - ValueTree findDrawableState (const String& objectId, bool recursive) const; const String createUniqueID (const String& suggestion) const; @@ -78,9 +74,17 @@ public: UndoManager* getUndoManager() const; const String getNonexistentMarkerName (const String& name); void renameAnchor (const String& oldName, const String& newName); + const String getId (const ValueTree& markerState); + int size() const; + ValueTree getMarker (int index) const; + ValueTree getMarkerNamed (const String& name) const; + bool contains (const ValueTree& markerState) const; + void createMarker (const String& name, int position); + void deleteMarker (ValueTree& markerState); private: DrawableDocument& document; + DrawableComposite::ValueTreeWrapper object; MarkerList (const MarkerList&); MarkerList& operator= (const MarkerList&); diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h index cc7afab1ea..f8c5411cb9 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h @@ -27,6 +27,7 @@ #define __JUCER_DRAWABLETYPEHANDLER_H_7FB02E2F__ #include "jucer_DrawableDocument.h" +#include "../../utility/jucer_FillTypePropertyComponent.h" class DrawableTypeHandler; @@ -42,7 +43,8 @@ public: Value getValue (const Identifier& name) const; void createProperties (Array & props); - bool setBounds (Drawable* drawable, const Rectangle& newBounds); + void setBounds (Drawable* drawable, const Rectangle& newBounds); + void getAllControlPoints (Array & points); //============================================================================== DrawableTypeHandler* getHandler() const; @@ -51,6 +53,8 @@ private: //============================================================================== DrawableDocument& document; ValueTree state; + + DrawableTypeInstance& operator= (const DrawableTypeInstance&); }; //============================================================================== @@ -67,7 +71,8 @@ public: virtual const ValueTree createNewInstance (DrawableDocument& document, const Point& approxPosition) = 0; virtual void createPropertyEditors (DrawableTypeInstance& item, Array & props) = 0; virtual void itemDoubleClicked (const MouseEvent& e, DrawableTypeInstance& item) = 0; - virtual bool setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) = 0; + virtual void setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) = 0; + virtual void getAllControlPoints (DrawableTypeInstance& item, Array & points) = 0; const String& getDisplayName() const { return displayName; } const Identifier& getValueTreeType() const { return valueTreeType; } @@ -85,7 +90,7 @@ protected: newBounds.setSize (jmax (1.0f, newBounds.getWidth()), jmax (1.0f, newBounds.getHeight())); - const double tolerance = 0.1; + const double tolerance = 0.001; double xScale = newBounds.getWidth() / (double) oldBounds.getWidth(); double yScale = newBounds.getHeight() / (double) oldBounds.getHeight(); @@ -115,6 +120,8 @@ protected: private: const String displayName; const Identifier valueTreeType; + + DrawableTypeHandler& operator= (const DrawableTypeHandler&); }; //============================================================================== @@ -145,7 +152,7 @@ public: { } - bool setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) + void setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) { DrawablePath::ValueTreeWrapper wrapper (item.getState()); @@ -163,22 +170,38 @@ public: points.add (elementPoints[j]); } - if (! rescalePoints (points.getRawDataPointer(), points.size(), - drawable->getBounds(), newBounds, drawable->getParent())) - return false; + if (rescalePoints (points.getRawDataPointer(), points.size(), + drawable->getBounds(), newBounds, drawable->getParent())) + { + int n = 0; + for (i = 0; i < path.elements.size(); ++i) + { + int numPoints; + RelativePoint* elementPoints = path.elements.getUnchecked(i)->getControlPoints (numPoints); - int n = 0; - for (i = 0; i < path.elements.size(); ++i) + for (int j = 0; j < numPoints; ++j) + elementPoints[j] = points [n++]; + } + + wrapper.setPath (path.toString(), item.getDocument().getUndoManager()); + } + } + + void getAllControlPoints (DrawableTypeInstance& item, Array & points) + { + DrawablePath::ValueTreeWrapper wrapper (item.getState()); + + RelativePointPath path; + wrapper.getPath (path); + + for (int i = 0; i < path.elements.size(); ++i) { int numPoints; RelativePoint* elementPoints = path.elements.getUnchecked(i)->getControlPoints (numPoints); for (int j = 0; j < numPoints; ++j) - elementPoints[j] = points [n++]; + points.add (elementPoints[j]); } - - wrapper.setPath (path.toString(), item.getDocument().getUndoManager()); - return true; } }; @@ -216,7 +239,7 @@ public: { } - bool setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) + void setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) { DrawableImage::ValueTreeWrapper wrapper (item.getState()); @@ -224,14 +247,22 @@ public: wrapper.getTargetPositionForTopRight(), wrapper.getTargetPositionForBottomLeft() }; - if (! rescalePoints (points, 3, drawable->getBounds(), newBounds, drawable->getParent())) - return false; + if (rescalePoints (points, 3, drawable->getBounds(), newBounds, drawable->getParent())) + { + UndoManager* undoManager = item.getDocument().getUndoManager(); + wrapper.setTargetPositionForTopLeft (points[0], undoManager); + wrapper.setTargetPositionForTopRight (points[1], undoManager); + wrapper.setTargetPositionForBottomLeft (points[2], undoManager); + } + } - UndoManager* undoManager = item.getDocument().getUndoManager(); - wrapper.setTargetPositionForTopLeft (points[0], undoManager); - wrapper.setTargetPositionForTopRight (points[1], undoManager); - wrapper.setTargetPositionForBottomLeft (points[2], undoManager); - return true; + void getAllControlPoints (DrawableTypeInstance& item, Array & points) + { + DrawableImage::ValueTreeWrapper wrapper (item.getState()); + + points.add (wrapper.getTargetPositionForTopLeft()); + points.add (wrapper.getTargetPositionForTopRight()); + points.add (wrapper.getTargetPositionForBottomLeft()); } }; @@ -255,7 +286,7 @@ public: { } - bool setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) + void setBounds (DrawableTypeInstance& item, Drawable* drawable, const Rectangle& newBounds) { DrawableComposite::ValueTreeWrapper wrapper (item.getState()); @@ -263,14 +294,22 @@ public: wrapper.getTargetPositionForX1Y0(), wrapper.getTargetPositionForX0Y1() }; - if (! rescalePoints (points, 3, drawable->getBounds(), newBounds, drawable->getParent())) - return false; + if (rescalePoints (points, 3, drawable->getBounds(), newBounds, drawable->getParent())) + { + UndoManager* undoManager = item.getDocument().getUndoManager(); + wrapper.setTargetPositionForOrigin (points[0], undoManager); + wrapper.setTargetPositionForX1Y0 (points[1], undoManager); + wrapper.setTargetPositionForX0Y1 (points[2], undoManager); + } + } - UndoManager* undoManager = item.getDocument().getUndoManager(); - wrapper.setTargetPositionForOrigin (points[0], undoManager); - wrapper.setTargetPositionForX1Y0 (points[1], undoManager); - wrapper.setTargetPositionForX0Y1 (points[2], undoManager); - return true; + void getAllControlPoints (DrawableTypeInstance& item, Array & points) + { + DrawableComposite::ValueTreeWrapper wrapper (item.getState()); + + points.add (wrapper.getTargetPositionForOrigin()); + points.add (wrapper.getTargetPositionForX1Y0()); + points.add (wrapper.getTargetPositionForX0Y1()); } }; diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h index 8257118a85..49094ffdb3 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h @@ -89,6 +89,11 @@ public: return getDocument().getMarkerList (isX); } + double limitMarkerPosition (double pos) + { + return jmax (0.0, pos); + } + const SelectedItems::ItemType findObjectIdAt (const Point& position) { for (int i = getComponentHolder()->getNumChildComponents(); --i >= 0;) @@ -166,10 +171,10 @@ public: { public: DragOperation (ComponentEditorCanvas* canvas_, - const MouseEvent& e, + const MouseEvent& e, const Point& mousePos, Component* snapGuideParentComp_, const ResizableBorderComponent::Zone& zone_) - : EditorDragOperation (canvas_, e, snapGuideParentComp_, zone_) + : EditorDragOperation (canvas_, e, mousePos, snapGuideParentComp_, zone_) { } @@ -206,19 +211,47 @@ public: UndoManager& getUndoManager() { return *getDocument().getUndoManager(); } + void getObjectDependencies (const ValueTree& state, Array& deps) + { + ComponentDocument& doc = getDocument(); + RelativeRectangle pr (doc.getCoordsFor (state)); + + StringArray anchors; + anchors.addIfNotAlreadyThere (pr.left.getAnchorName1()); + anchors.addIfNotAlreadyThere (pr.left.getAnchorName2()); + anchors.addIfNotAlreadyThere (pr.top.getAnchorName1()); + anchors.addIfNotAlreadyThere (pr.top.getAnchorName2()); + anchors.addIfNotAlreadyThere (pr.right.getAnchorName1()); + anchors.addIfNotAlreadyThere (pr.right.getAnchorName2()); + anchors.addIfNotAlreadyThere (pr.bottom.getAnchorName1()); + anchors.addIfNotAlreadyThere (pr.bottom.getAnchorName2()); + + for (int i = 0; i < anchors.size(); ++i) + { + const String anchor (anchors[i]); + if (anchor.isNotEmpty() && ! anchor.startsWith ("parent.")) + { + const ValueTree v (doc.getComponentWithMemberName (anchor.upToFirstOccurrenceOf (".", false, false))); + + if (v.isValid()) + deps.add (v); + } + } + } + const Rectangle getObjectPosition (const ValueTree& state) { ComponentDocument& doc = getDocument(); return doc.getCoordsFor (state).resolve (&doc); } - bool setObjectPosition (ValueTree& state, const Rectangle& newBounds) + void setObjectPosition (ValueTree& state, const Rectangle& newBounds) { ComponentDocument& doc = getDocument(); RelativeRectangle pr (doc.getCoordsFor (state)); pr.moveToAbsolute (newBounds, &doc); - return doc.setCoordsFor (state, pr); + doc.setCoordsFor (state, pr); } float getMarkerPosition (const ValueTree& marker, bool isX) @@ -231,7 +264,7 @@ public: DragOperation* createDragOperation (const MouseEvent& e, Component* snapGuideParentComponent, const ResizableBorderComponent::Zone& zone) { - DragOperation* d = new DragOperation (this, e, snapGuideParentComponent, zone); + DragOperation* d = new DragOperation (this, e, e.getPosition() - origin, snapGuideParentComponent, zone); Array selected, unselected; diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h index 5b90cc611a..7d87cc3b6c 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h @@ -26,7 +26,7 @@ #ifndef __JUCER_COMPONENTEDITORTOOLBAR_H_6B5CA931__ #define __JUCER_COMPONENTEDITORTOOLBAR_H_6B5CA931__ -#include "../../utility/jucer_ColourEditorComponent.h" +#include "../../utility/jucer_ColourPropertyComponent.h" //============================================================================== diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h index b349746dde..3602e97015 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h @@ -291,7 +291,7 @@ namespace ComponentEditorTreeView } //============================================================================== - const String getItemId() const { return MarkerListBase::getId (markerState); } + const String getItemId() const { return markerState [Ids::id_]; } bool mightContainSubItems() { return false; } void refreshSubItems() {} diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h index 9ed79b51a1..8f55c03d56 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h @@ -86,6 +86,11 @@ public: return getDocument().getMarkerList (isX); } + double limitMarkerPosition (double pos) + { + return pos; + } + const SelectedItems::ItemType findObjectIdAt (const Point& position) { if (drawable != 0) @@ -134,6 +139,36 @@ public: return getDocument().findDrawableState (objectId, false); } + void getObjectPositionDependencies (const ValueTree& state, Array& deps) + { + DrawableDocument& doc = getDocument(); + DrawableTypeInstance item (doc, state); + + Array points; + item.getAllControlPoints (points); + + StringArray anchors; + for (int i = 0; i < points.size(); ++i) + { + anchors.addIfNotAlreadyThere (points.getReference(i).x.getAnchorName1()); + anchors.addIfNotAlreadyThere (points.getReference(i).x.getAnchorName2()); + anchors.addIfNotAlreadyThere (points.getReference(i).y.getAnchorName1()); + anchors.addIfNotAlreadyThere (points.getReference(i).y.getAnchorName2()); + } + + for (int i = 0; i < anchors.size(); ++i) + { + const String anchor (anchors[i]); + if (anchor.isNotEmpty() && ! anchor.startsWith ("parent.")) + { + const ValueTree v (doc.findDrawableState (anchor.upToFirstOccurrenceOf (".", false, false), false)); + + if (v.isValid()) + deps.add (v); + } + } + } + const Rectangle getObjectPositionFloat (const ValueTree& state) { if (drawable != 0) @@ -147,7 +182,7 @@ public: return Rectangle(); } - bool setObjectPositionFloat (const ValueTree& state, const Rectangle& newPos) + void setObjectPositionFloat (const ValueTree& state, const Rectangle& newPos) { if (drawable != 0) { @@ -157,11 +192,9 @@ public: { d->refreshFromValueTree (state, &getDocument()); DrawableTypeInstance di (getDocument(), state); - return di.setBounds (d, newPos); + di.setBounds (d, newPos); } } - - return false; } const Rectangle getObjectPosition (const ValueTree& state) @@ -204,10 +237,10 @@ public: { public: DragOperation (DrawableEditorCanvas* canvas_, - const MouseEvent& e, + const MouseEvent& e, const Point& mousePos, Component* snapGuideParentComp_, const ResizableBorderComponent::Zone& zone_) - : EditorDragOperation (canvas_, e, snapGuideParentComp_, zone_) + : EditorDragOperation (canvas_, e, mousePos, snapGuideParentComp_, zone_) { } @@ -224,14 +257,19 @@ public: UndoManager& getUndoManager() { return *getDocument().getUndoManager(); } + void getObjectDependencies (const ValueTree& state, Array& deps) + { + static_cast (canvas)->getObjectPositionDependencies (state, deps); + } + const Rectangle getObjectPosition (const ValueTree& state) { return static_cast (canvas)->getObjectPositionFloat (state); } - bool setObjectPosition (ValueTree& state, const Rectangle& newBounds) + void setObjectPosition (ValueTree& state, const Rectangle& newBounds) { - return static_cast (canvas)->setObjectPositionFloat (state, newBounds); + static_cast (canvas)->setObjectPositionFloat (state, newBounds); } float getMarkerPosition (const ValueTree& marker, bool isX) @@ -243,7 +281,7 @@ public: DragOperation* createDragOperation (const MouseEvent& e, Component* snapGuideParentComponent, const ResizableBorderComponent::Zone& zone) { - DragOperation* d = new DragOperation (this, e, snapGuideParentComponent, zone); + DragOperation* d = new DragOperation (this, e, e.getPosition() - origin, snapGuideParentComponent, zone); Array selected, unselected; @@ -300,6 +338,7 @@ public: void paint (Graphics& g) { + canvas->handleUpdateNowIfNeeded(); g.fillAll (Colours::white); const Point origin (canvas->getOrigin()); @@ -307,14 +346,14 @@ public: if (origin.getX() > 0) { - g.setColour (Colour::greyLevel (0.8f)); - g.drawVerticalLine (0, 0, 10000.0f); + g.setColour (Colour::greyLevel (0.87f)); + g.drawVerticalLine (0, -10000.0f, 10000.0f); } if (origin.getY() > 0) { - g.setColour (Colour::greyLevel (0.8f)); - g.drawHorizontalLine (0, 0, 10000.0f); + g.setColour (Colour::greyLevel (0.87f)); + g.drawHorizontalLine (0, -10000.0f, 10000.0f); } canvas->drawable->draw (g, 1.0f); diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp index 9b5a743f5a..a7a0df4f8c 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp @@ -236,7 +236,7 @@ public: void paint (Graphics& g) { - g.setColour (Colours::lightgreen.withAlpha (isMouseOverOrDragging() ? 0.8f : 0.4f)); + g.setColour (Colours::lightblue.withAlpha (isMouseOverOrDragging() ? 0.9f : 0.5f)); g.fillPath (path); } @@ -247,9 +247,11 @@ public: const int width = 8; if (isX) - setBoundsInTargetSpace (Rectangle (pos - width, -headSize, width * 2, getParentHeight())); + setBoundsInTargetSpace (Rectangle (pos - width, -canvas->getOrigin().getY() - headSize, + width * 2, getParentHeight())); else - setBoundsInTargetSpace (Rectangle (-headSize, pos - width, getParentWidth(), width * 2)); + setBoundsInTargetSpace (Rectangle (-canvas->getOrigin().getX() - headSize, pos - width, + getParentWidth(), width * 2)); labelText = "name: " + getMarkerList().getName (marker) + "\nposition: " + coord.toString(); updateLabel(); @@ -297,7 +299,7 @@ public: toFront (false); updateLabel(); - canvas->getSelection().selectOnly (MarkerListBase::getId (marker)); + canvas->getSelection().selectOnly (getMarkerList().getId (marker)); if (e.mods.isPopupMenu()) { @@ -328,13 +330,13 @@ public: else axis.setBounds (0, 0, headSize, getParentHeight()); - if (axis.expanded (30, 30).contains (e.x, e.y)) + if (axis.expanded (isX ? 500 : 30, isX ? 30 : 500).contains (e.x, e.y)) { RelativeCoordinate coord (getMarkerList().getCoordinate (marker)); // (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()))), + coord.moveToAbsolute (canvas->limitMarkerPosition (dragStartPos + (isX ? e2.x - mouseDownPos.getX() + : e2.y - mouseDownPos.getY())), &getMarkerList()); getMarkerList().setCoordinate (marker, coord); } @@ -489,11 +491,13 @@ public: if (xAxis.contains (e.x, e.y)) { - canvas->getMarkerList (true).createMarker ("Marker", e.x - xAxis.getX()); + canvas->getMarkerList (true).createMarker (canvas->getMarkerList (true).getNonexistentMarkerName ("Marker"), + e.x - xAxis.getX()); } else if (yAxis.contains (e.x, e.y)) { - canvas->getMarkerList (false).createMarker ("Marker", e.y - yAxis.getY()); + canvas->getMarkerList (false).createMarker (canvas->getMarkerList (false).getNonexistentMarkerName ("Marker"), + e.y - yAxis.getY()); } else { @@ -879,11 +883,20 @@ void EditorCanvasBase::handleAsyncUpdate() if (origin != newOrigin) { repaint(); - origin = newOrigin; - } - setSize (jmax (canvasBounds.getWidth(), canvasBounds.getRight()) + border.getLeftAndRight(), - jmax (canvasBounds.getHeight(), canvasBounds.getBottom()) + border.getTopAndBottom()); + const Point oldOrigin (origin); + origin = newOrigin; + + setBounds (jmin (0, getX() + oldOrigin.getX() - origin.getX()), + jmin (0, getY() + oldOrigin.getY() - origin.getY()), + jmax (canvasBounds.getWidth(), canvasBounds.getRight()) + border.getLeftAndRight(), + jmax (canvasBounds.getHeight(), canvasBounds.getBottom()) + border.getTopAndBottom()); + } + else + { + setSize (jmax (canvasBounds.getWidth(), canvasBounds.getRight()) + border.getLeftAndRight(), + jmax (canvasBounds.getHeight(), canvasBounds.getBottom()) + border.getTopAndBottom()); + } overlay->update(); } @@ -910,14 +923,14 @@ void EditorCanvasBase::beginDrag (const MouseEvent& e, const ResizableBorderComp void EditorCanvasBase::continueDrag (const MouseEvent& e) { if (dragger != 0) - dragger->drag (e); + dragger->drag (e, e.getPosition() - origin); } void EditorCanvasBase::endDrag (const MouseEvent& e) { if (dragger != 0) { - dragger->drag (e); + dragger->drag (e, e.getPosition() - origin); dragger = 0; } } diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h index a4a6ed9dba..4004255f9d 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h @@ -69,6 +69,7 @@ public: virtual void setCanvasBounds (const Rectangle& newBounds) = 0; virtual bool canResizeCanvas() const = 0; virtual MarkerListBase& getMarkerList (bool isX) = 0; + virtual double limitMarkerPosition (double pos) = 0; virtual const SelectedItems::ItemType findObjectIdAt (const Point& position) = 0; virtual void showPopupMenu (bool isClickOnSelectedObject) = 0; @@ -91,8 +92,7 @@ public: DragOperation() {} virtual ~DragOperation() {} - virtual void drag (const MouseEvent& e) = 0; - virtual bool dragItem (ValueTree& v, const Point& distance, const Rectangle& originalPos) = 0; + virtual void drag (const MouseEvent& e, const Point& newPos) = 0; }; virtual DragOperation* createDragOperation (const MouseEvent& e, diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h index e0e7534545..ab9adf3a73 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h @@ -33,13 +33,13 @@ class EditorDragOperation : public EditorCanvasBase::DragOperation { public: - EditorDragOperation (EditorCanvasBase* canvas_, const MouseEvent& e, + EditorDragOperation (EditorCanvasBase* canvas_, const MouseEvent& e, const Point& mousePos, Component* snapGuideParentComp_, const ResizableBorderComponent::Zone& zone_) : canvas (canvas_), snapGuideParentComp (snapGuideParentComp_), zone (zone_), - mouseDownPos (e.getPosition()) + mouseDownPos (mousePos) { } @@ -50,12 +50,13 @@ public: void initialise (const Array& objects, const Array& objectsToSnapTo) { - draggedObjects = objects; - int i; for (i = 0; i < objects.size(); ++i) + addObjectToList (objects.getReference(i), objects); + + for (i = 0; i < updateList.size(); ++i) { - const Rectangle floatPos (getObjectPosition (objects.getReference(i))); + const Rectangle floatPos (getObjectPosition (updateList.getReference(i))); originalPositions.add (floatPos); if (zone.isDraggingWholeObject() || zone.isDraggingLeftEdge()) @@ -185,12 +186,12 @@ public: }; //============================================================================== - void drag (const MouseEvent& e) + void drag (const MouseEvent& e, const Point& newPos) { getUndoManager().undoCurrentTransactionOnly(); // (can't use getOffsetFromDragStart() because of auto-scrolling) - Point distance (e.getPosition() - mouseDownPos); + Point distance (newPos - mouseDownPos); if (! isDraggingLeftRight()) distance = distance.withX (0); @@ -205,32 +206,15 @@ public: performSnap (horizontalSnapTargets, getHorizontalSnapPositions (distance), false, distance); } - for (int n = 50;;) - { - // Need to repeatedly apply the new positions until they all settle down, in case some of - // the coords are relative to each other.. - bool anyUpdated = false; - - for (int i = 0; i < draggedObjects.size(); ++i) - if (dragItem (draggedObjects.getReference(i), distance, originalPositions.getReference(i))) - anyUpdated = true; - - if (! anyUpdated) - break; - - if (--n == 0) - { - jassertfalse; - break; - } - } + for (int i = 0; i < updateList.size(); ++i) + dragItem (updateList.getReference(i), distance, originalPositions.getReference(i)); } - bool dragItem (ValueTree& v, const Point& distance, const Rectangle& originalPos) + void dragItem (ValueTree& v, const Point& distance, const Rectangle& originalPos) { const Rectangle newBounds (zone.resizeRectangleBy (originalPos, Point ((float) distance.getX(), (float) distance.getY()))); - return setObjectPosition (v, newBounds); + setObjectPosition (v, newBounds); } protected: @@ -239,8 +223,9 @@ protected: virtual void getSnapPointsY (Array& points, bool includeCentre) = 0; virtual float getMarkerPosition (const ValueTree& marker, bool isX) = 0; + virtual void getObjectDependencies (const ValueTree& state, Array& deps) = 0; virtual const Rectangle getObjectPosition (const ValueTree& state) = 0; - virtual bool setObjectPosition (ValueTree& state, const Rectangle& newBounds) = 0; + virtual void setObjectPosition (ValueTree& state, const Rectangle& newBounds) = 0; virtual UndoManager& getUndoManager() = 0; @@ -248,7 +233,7 @@ protected: private: //============================================================================== - Array draggedObjects; + Array updateList; Array > originalPositions; Array verticalSnapPositions, horizontalSnapPositions; Array verticalSnapTargets, horizontalSnapTargets; @@ -257,6 +242,43 @@ private: Component* snapGuideParentComp; Point mouseDownPos; + void getCompleteDependencyList (const ValueTree& object, Array & deps, const Array& activeObjects) + { + Array d; + getObjectDependencies (object, d); + + for (int i = 0; i < d.size(); ++i) + { + const ValueTree& dep = d.getReference(i); + if (activeObjects.contains (dep) && ! deps.contains (dep)) + { + deps.add (dep); + getCompleteDependencyList (dep, deps, activeObjects); + } + } + } + + void addObjectToList (const ValueTree& object, const Array& activeObjects) + { + Array deps; + getCompleteDependencyList (object, deps, activeObjects); + + int lastIndexInList = updateList.indexOf (object); + + int i; + for (i = lastIndexInList; --i >= 0;) + deps.removeValue (updateList.getReference(i)); + + if (deps.size() > 0 || lastIndexInList < 0) + { + for (i = 0; i < deps.size(); ++i) + if (! updateList.contains (deps.getReference(i))) + updateList.add (deps.getReference(i)); + + updateList.add (object); + } + } + static void mergeSnapLines (Array & lines) { for (int i = lines.size(); --i > 0;) diff --git a/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h b/extras/Jucer (experimental)/Source/utility/jucer_ColourPropertyComponent.h similarity index 84% rename from extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h rename to extras/Jucer (experimental)/Source/utility/jucer_ColourPropertyComponent.h index d388b26a01..1757d13b19 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_ColourPropertyComponent.h @@ -120,17 +120,7 @@ public: } private: - class ColourSelectorWithSwatches : public ColourSelector - { - public: - ColourSelectorWithSwatches() {} - - int getNumSwatches() const { return StoredSettings::getInstance()->swatchColours.size(); } - const Colour getSwatchColour (int index) const { return StoredSettings::getInstance()->swatchColours [index]; } - void setSwatchColour (int index, const Colour& newColour) const { StoredSettings::getInstance()->swatchColours.set (index, newColour); } - }; - - ColourSelectorWithSwatches selector; + StoredSettings::ColourSelectorWithSwatches selector; TextButton defaultButton; Value colourValue; Colour defaultColour; @@ -145,9 +135,9 @@ class ColourEditorComponent : public Component, public Value::Listener { public: - ColourEditorComponent (ComponentDocument& document_, const Value& colourValue_, + ColourEditorComponent (UndoManager* undoManager_, const Value& colourValue_, const Colour& defaultColour_, const bool canResetToDefault_) - : document (document_), colourValue (colourValue_), defaultColour (defaultColour_), + : undoManager (undoManager_), colourValue (colourValue_), defaultColour (defaultColour_), canResetToDefault (canResetToDefault_) { colourValue.addListener (this); @@ -211,7 +201,7 @@ public: void mouseDown (const MouseEvent& e) { - document.getUndoManager()->beginNewTransaction(); + undoManager->beginNewTransaction(); PopupColourSelector::showAt (this, colourValue, defaultColour, canResetToDefault); } @@ -223,7 +213,7 @@ public: juce_UseDebuggingNewOperator private: - ComponentDocument& document; + UndoManager* undoManager; Value colourValue; Colour lastColour; const Colour defaultColour; @@ -235,10 +225,10 @@ class ColourPropertyComponent : public PropertyComponent { public: //============================================================================== - ColourPropertyComponent (ComponentDocument& document, const String& name, const Value& colour, + ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour, const Colour& defaultColour, bool canResetToDefault) : PropertyComponent (name), - colourEditor (document, colour, defaultColour, canResetToDefault) + colourEditor (undoManager, colour, defaultColour, canResetToDefault) { addAndMakeVisible (&colourEditor); } diff --git a/extras/Jucer (experimental)/Source/utility/jucer_FillTypePropertyComponent.h b/extras/Jucer (experimental)/Source/utility/jucer_FillTypePropertyComponent.h new file mode 100644 index 0000000000..4e215baefd --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_FillTypePropertyComponent.h @@ -0,0 +1,207 @@ +/* + ============================================================================== + + 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_FILLTYPEPROPERTYCOMPONENT_H_88CF1300__ +#define __JUCER_FILLTYPEPROPERTYCOMPONENT_H_88CF1300__ + +//============================================================================== +class PopupFillSelector : public Component, + public ChangeListener, + public ValueTree::Listener, + public ButtonListener +{ +public: + PopupFillSelector (const ValueTree& fillState_, UndoManager* undoManager_) + : fillState (fillState_), + undoManager (undoManager_) + { + addAndMakeVisible (&colourPicker); + colourPicker.setName ("Colour"); + colourPicker.addChangeListener (this); + + fillState.addListener (this); + } + + ~PopupFillSelector() + { + } + + static void showAt (Component* comp, const ValueTree& fill, UndoManager* undoManager) + { + PopupFillSelector popup (fill, undoManager); + + PopupMenu m; + m.addCustomItem (1234, &popup, 300, 400, false); + m.showAt (comp); + } + + void resized() + { + colourPicker.setBounds (0, 0, getWidth(), getHeight()); + } + + void buttonClicked (Button*) + { + } + + void changeListenerCallback (void* source) + { + const FillType currentFill (Drawable::ValueTreeWrapperBase::readFillType (fillState)); + + if (currentFill.isColour()) + { + const FillType newFill (colourPicker.getCurrentColour()); + + if (currentFill != newFill) + Drawable::ValueTreeWrapperBase::writeFillType (fillState, newFill, undoManager); + } + } + + void refresh() + { + const FillType newFill (Drawable::ValueTreeWrapperBase::readFillType (fillState)); + + if (newFill.isColour()) + colourPicker.setCurrentColour (newFill.colour); + } + + void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property) { refresh(); } + void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) { refresh(); } + void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} + +private: + StoredSettings::ColourSelectorWithSwatches colourPicker; + ValueTree fillState; + UndoManager* undoManager; +}; + + +//============================================================================== +/** + A component that shows a fill type swatch, and pops up a editor panel + when you click it. +*/ +class FillTypeEditorComponent : public Component, + public ValueTree::Listener +{ +public: + FillTypeEditorComponent (const ValueTree& fillState_, UndoManager* undoManager_) + : fillState (fillState_), undoManager (undoManager_) + { + fillState.addListener (this); + refresh(); + } + + ~FillTypeEditorComponent() + { + } + + void paint (Graphics& g) + { + g.setColour (Colours::grey); + g.drawRect (0, 0, getWidth(), getHeight(), 2); + + g.fillCheckerBoard (2, 2, getWidth() - 4, getHeight() - 4, 10, 10, + Colour (0xffdddddd), Colour (0xffffffff)); + + FillType f (fillType); + + if (f.gradient != 0) + { + f.gradient->point1.setXY (2.0f, getHeight() / 2.0f); + f.gradient->point2.setXY (getWidth() - 2.0f, getHeight() / 2.0f); + } + + g.setFillType (f); + g.fillRect (2, 2, getWidth() - 4, getHeight() - 4); + + if (fillType.isColour()) + { + g.setColour (Colours::white.overlaidWith (fillType.colour).contrasting()); + g.setFont (getHeight() * 0.6f, Font::bold); + g.drawFittedText (fillType.colour.toDisplayString (true), + 2, 1, getWidth() - 4, getHeight() - 1, + Justification::centred, 1); + } + } + + void refresh() + { + const FillType newFill (Drawable::ValueTreeWrapperBase::readFillType (fillState)); + + if (newFill != fillType) + { + fillType = newFill; + repaint(); + } + } + + void mouseDown (const MouseEvent& e) + { + undoManager->beginNewTransaction(); + PopupFillSelector::showAt (this, fillState, undoManager); + } + + void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property) { refresh(); } + void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) { refresh(); } + void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} + + juce_UseDebuggingNewOperator + +private: + ValueTree fillState; + UndoManager* undoManager; + FillType fillType; +}; + +//============================================================================== +class FillTypePropertyComponent : public PropertyComponent +{ +public: + //============================================================================== + FillTypePropertyComponent (UndoManager* undoManager, const String& name, const ValueTree& fill) + : PropertyComponent (name), + editor (fill, undoManager) + { + addAndMakeVisible (&editor); + } + + ~FillTypePropertyComponent() + { + } + + void resized() + { + editor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this)); + } + + void refresh() {} + +protected: + FillTypeEditorComponent editor; +}; + + +#endif // __JUCER_FILLTYPEPROPERTYCOMPONENT_H_88CF1300__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h index 4017175234..57fedeee3d 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h @@ -33,16 +33,15 @@ class MarkerListBase : public RelativeCoordinate::NamedCoordinateFinder { public: - MarkerListBase (const ValueTree& group_, bool isX_) : group (group_), isX (isX_) {} + MarkerListBase (bool isX_) : isX (isX_) {} virtual ~MarkerListBase() {} bool isHorizontal() const { return isX; } - static const String getId (const ValueTree& markerState) { return markerState [getIdProperty()]; } - ValueTree& getGroup() { return group; } - int size() const { return group.getNumChildren(); } - ValueTree getMarker (int index) const { return group.getChild (index); } - ValueTree getMarkerNamed (const String& name) const { return group.getChildWithProperty (getMarkerNameProperty(), name); } - bool contains (const ValueTree& markerState) const { return markerState.isAChildOf (group); } + virtual const String getId (const ValueTree& markerState) = 0; + virtual int size() const = 0; + virtual ValueTree getMarker (int index) const = 0; + virtual ValueTree getMarkerNamed (const String& name) const = 0; + virtual bool contains (const ValueTree& markerState) const = 0; const String getName (const ValueTree& markerState) const { return markerState [getMarkerNameProperty()].toString(); } Value getNameAsValue (const ValueTree& markerState) const { return markerState.getPropertyAsValue (getMarkerNameProperty(), getUndoManager()); } @@ -61,20 +60,8 @@ public: } } - void createMarker (const String& name, int position) - { - ValueTree marker (getMarkerTag()); - marker.setProperty (getMarkerNameProperty(), getNonexistentMarkerName (name), 0); - marker.setProperty (getMarkerPosProperty(), RelativeCoordinate (position, isX).toString(), 0); - marker.setProperty (getIdProperty(), createAlphaNumericUID(), 0); - group.addChild (marker, -1, getUndoManager()); - } - - void deleteMarker (ValueTree& markerState) - { - renameAnchor (getName (markerState), String::empty); - group.removeChild (markerState, getUndoManager()); - } + virtual void createMarker (const String& name, int position) = 0; + virtual void deleteMarker (ValueTree& markerState) = 0; //============================================================================== virtual UndoManager* getUndoManager() const = 0; @@ -85,7 +72,6 @@ public: //============================================================================== static const Identifier getMarkerTag() { static Identifier i ("MARKER"); return i; } - static const Identifier getIdProperty() { return Ids::id_; } static const Identifier getMarkerNameProperty() { return Ids::name; } static const Identifier getMarkerPosProperty() { return Ids::position; } @@ -133,10 +119,10 @@ public: { public: //============================================================================== - PositionPropertyComponent (NamedCoordinateFinder* nameSource_, MarkerListBase& markerList_, + PositionPropertyComponent (MarkerListBase& markerList_, const String& name, const ValueTree& markerState_, const Value& coordValue_) - : CoordinatePropertyComponent (nameSource_, name, coordValue_, markerList_.isHorizontal()), + : CoordinatePropertyComponent (&markerList_, name, coordValue_, markerList_.isHorizontal()), markerList (markerList_), markerState (markerState_) { @@ -168,7 +154,6 @@ public: //============================================================================== protected: - ValueTree group; const bool isX; private: diff --git a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h index 0b88f5276e..0d76cd696c 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h @@ -53,10 +53,22 @@ public: const File getLastKnownJuceFolder() const; void setLastKnownJuceFolder (const File& file); - Array swatchColours; const StringArray& getFontNames(); + //============================================================================== + Array swatchColours; + + class ColourSelectorWithSwatches : public ColourSelector + { + public: + ColourSelectorWithSwatches() {} + + int getNumSwatches() const { return StoredSettings::getInstance()->swatchColours.size(); } + const Colour getSwatchColour (int index) const { return StoredSettings::getInstance()->swatchColours [index]; } + void setSwatchColour (int index, const Colour& newColour) const { StoredSettings::getInstance()->swatchColours.set (index, newColour); } + }; + //============================================================================== juce_UseDebuggingNewOperator diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 1a92b4c3b4..50506660a5 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -8122,6 +8122,7 @@ void juce_closeInternetFile (void* handle); int juce_readFromInternetFile (void* handle, void* dest, int bytesToRead); int juce_seekInInternetFile (void* handle, int newPosition); int64 juce_getInternetFileContentLength (void* handle); +void juce_getInternetFileHeaders (void* handle, StringPairArray& headers); class WebInputStream : public InputStream { @@ -8132,7 +8133,8 @@ public: URL::OpenStreamProgressCallback* const progressCallback_, void* const progressCallbackContext_, const String& extraHeaders, - int timeOutMs_) + const int timeOutMs_, + StringPairArray* const responseHeaders) : position (0), finished (false), isPost (isPost_), @@ -8153,6 +8155,9 @@ public: handle = juce_openInternetFile (server, headers, postData, isPost, progressCallback_, progressCallbackContext_, timeOutMs); + + if (responseHeaders != 0) + juce_getInternetFileHeaders (handle, *responseHeaders); } ~WebInputStream() @@ -8293,12 +8298,12 @@ InputStream* URL::createInputStream (const bool usePostCommand, OpenStreamProgressCallback* const progressCallback, void* const progressCallbackContext, const String& extraHeaders, - const int timeOutMs) const + const int timeOutMs, + StringPairArray* const responseHeaders) const { ScopedPointer wi (new WebInputStream (*this, usePostCommand, progressCallback, progressCallbackContext, - extraHeaders, - timeOutMs)); + extraHeaders, timeOutMs, responseHeaders)); return wi->isError() ? 0 : wi.release(); } @@ -10160,11 +10165,11 @@ int CharacterFunctions::getHexDigitValue (const juce_wchar digit) throw() if (d < (unsigned int) 10) return (int) d; - d += '0' - 'a'; + d += (unsigned int) ('0' - 'a'); if (d < (unsigned int) 6) return (int) d + 10; - d += 'a' - 'A'; + d += (unsigned int) ('a' - 'A'); if (d < (unsigned int) 6) return (int) d + 10; @@ -68838,10 +68843,7 @@ PopupMenu::PopupMenu (const PopupMenu& other) : lookAndFeel (other.lookAndFeel), separatorPending (false) { - items.ensureStorageAllocated (other.items.size()); - - for (int i = 0; i < other.items.size(); ++i) - items.add (new Item (*other.items.getUnchecked(i))); + items.addCopiesOf (other.items); } PopupMenu& PopupMenu::operator= (const PopupMenu& other) @@ -68851,10 +68853,7 @@ PopupMenu& PopupMenu::operator= (const PopupMenu& other) lookAndFeel = other.lookAndFeel; clear(); - items.ensureStorageAllocated (other.items.size()); - - for (int i = 0; i < other.items.size(); ++i) - items.add (new Item (*other.items.getUnchecked(i))); + items.addCopiesOf (other.items); } return *this; @@ -70974,7 +70973,7 @@ void ChoicePropertyComponent::createComboBox() comboBox->setEditableText (false); } -void ChoicePropertyComponent::setIndex (const int newIndex) +void ChoicePropertyComponent::setIndex (const int /*newIndex*/) { jassertfalse; // you need to override this method in your subclass! } @@ -83920,16 +83919,8 @@ const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v) return FillType(); } -void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager) +void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType, UndoManager* const 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); @@ -83978,6 +83969,19 @@ void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, con } } +void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* const undoManager) +{ + ValueTree v (state.getChildWithName (tag)); + + if (! v.isValid()) + { + state.addChild (ValueTree (tag), -1, undoManager); + v = state.getChildWithName (tag); + } + + writeFillType (v, fillType, undoManager); +} + END_JUCE_NAMESPACE /*** End of inlined file: juce_Drawable.cpp ***/ @@ -84000,8 +84004,8 @@ DrawableComposite::DrawableComposite (const DrawableComposite& other) 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))); + markersX.addCopiesOf (other.markersX); + markersY.addCopiesOf (other.markersY); } DrawableComposite::~DrawableComposite() @@ -84054,39 +84058,39 @@ void DrawableComposite::setTransform (const RelativePoint& targetPositionForOrig } DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other) - : name (other.name), position (other.position), isOnXAxis (other.isOnXAxis) + : name (other.name), position (other.position) { } -DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_, const bool isOnXAxis_) - : name (name_), position (position_), isOnXAxis (isOnXAxis_) +DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_) + : name (name_), position (position_) { } bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw() { - return name != other.name || position != other.position || isOnXAxis != other.isOnXAxis; + return name != other.name || position != other.position; } -int DrawableComposite::getNumMarkers (bool xAxis) const throw() +int DrawableComposite::getNumMarkers (const bool xAxis) const throw() { - return markers.size(); + return (xAxis ? markersX : markersY).size(); } -const DrawableComposite::Marker* DrawableComposite::getMarker (int index) const throw() +const DrawableComposite::Marker* DrawableComposite::getMarker (const bool xAxis, const int index) const throw() { - return markers [index]; + return (xAxis ? markersX : markersY) [index]; } -void DrawableComposite::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position) +void DrawableComposite::setMarker (const String& name, const bool xAxis, const RelativeCoordinate& position) { + OwnedArray & markers = (xAxis ? markersX : markersY); + 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; @@ -84097,13 +84101,13 @@ void DrawableComposite::setMarker (const String& name, bool xAxis, const Relativ } } - markers.add (new Marker (name, position, xAxis)); + (xAxis ? markersX : markersY).add (new Marker (name, position)); invalidatePoints(); } -void DrawableComposite::removeMarker (int index) +void DrawableComposite::removeMarker (const bool xAxis, const int index) { - markers.remove (index); + (xAxis ? markersX : markersY).remove (index); } const AffineTransform DrawableComposite::calculateTransform() const @@ -84167,9 +84171,17 @@ const RelativeCoordinate DrawableComposite::findNamedCoordinate (const String& o } } - for (int i = 0; i < markers.size(); ++i) + int i; + for (i = 0; i < markersX.size(); ++i) { - Marker* const m = markers.getUnchecked(i); + Marker* const m = markersX.getUnchecked(i); + if (m->name == objectName) + return m->position; + } + + for (i = 0; i < markersY.size(); ++i) + { + Marker* const m = markersY.getUnchecked(i); if (m->name == objectName) return m->position; } @@ -84181,9 +84193,66 @@ const Rectangle DrawableComposite::getUntransformedBounds() const { Rectangle bounds; - for (int i = 0; i < drawables.size(); ++i) + int i; + for (i = 0; i < drawables.size(); ++i) bounds = bounds.getUnion (drawables.getUnchecked(i)->getBounds()); + if (markersX.size() > 0) + { + float minX = std::numeric_limits::max(); + float maxX = std::numeric_limits::min(); + + for (i = markersX.size(); --i >= 0;) + { + const Marker* m = markersX.getUnchecked(i); + const float pos = (float) m->position.resolve (parent); + minX = jmin (minX, pos); + maxX = jmax (maxX, pos); + } + + if (minX <= maxX) + { + if (bounds.getWidth() == 0) + { + bounds.setLeft (minX); + bounds.setWidth (maxX - minX); + } + else + { + bounds.setLeft (jmin (bounds.getX(), minX)); + bounds.setRight (jmax (bounds.getRight(), maxX)); + } + } + } + + if (markersY.size() > 0) + { + float minY = std::numeric_limits::max(); + float maxY = std::numeric_limits::min(); + + for (i = markersY.size(); --i >= 0;) + { + const Marker* m = markersY.getUnchecked(i); + const float pos = (float) m->position.resolve (parent); + minY = jmin (minY, pos); + maxY = jmax (maxY, pos); + } + + if (minY <= maxY) + { + if (bounds.getHeight() == 0) + { + bounds.setTop (minY); + bounds.setHeight (maxY - minY); + } + else + { + bounds.setTop (jmin (bounds.getY(), minY)); + bounds.setBottom (jmax (bounds.getBottom(), maxY)); + } + } + } + return bounds; } @@ -84220,10 +84289,10 @@ 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::markerGroupTagX ("MarkersX"); +const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagY ("MarkersY"); 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_) @@ -84247,21 +84316,6 @@ ValueTree DrawableComposite::ValueTreeWrapper::getChildListCreating (UndoManager return getChildList(); } -ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList() const -{ - 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(); @@ -84353,44 +84407,69 @@ void DrawableComposite::ValueTreeWrapper::setTargetPositionForX0Y1 (const Relati state.setProperty (bottomLeft, newPoint.toString(), undoManager); } -int DrawableComposite::ValueTreeWrapper::getNumMarkers() const +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const { - return getMarkerList().getNumChildren(); + return state.getChildWithName (xAxis ? markerGroupTagX : markerGroupTagY); } -const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (int index) const +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager) { - const ValueTree marker (getMarkerList().getChild (index)); - const bool isXAxis = marker [xAxisProperty]; + const ValueTree markerList (getMarkerList (xAxis)); + if (markerList.isValid()) + return markerList; - return Marker (marker [nameProperty], - RelativeCoordinate (marker [posProperty].toString(), isXAxis), - isXAxis); + state.addChild (ValueTree (xAxis ? markerGroupTagX : markerGroupTagY), -1, undoManager); + return getMarkerList (xAxis); } -void DrawableComposite::ValueTreeWrapper::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager) +int DrawableComposite::ValueTreeWrapper::getNumMarkers (bool xAxis) const { - ValueTree markerList (getMarkerListCreating (undoManager)); - ValueTree marker (markerList.getChildWithProperty (nameProperty, name)); + return getMarkerList (xAxis).getNumChildren(); +} + +const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, int index) const +{ + return getMarkerList (xAxis).getChild (index); +} + +const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, const String& name) const +{ + return getMarkerList (xAxis).getChildWithProperty (nameProperty, name); +} + +bool DrawableComposite::ValueTreeWrapper::containsMarker (bool xAxis, const ValueTree& state) const +{ + return state.isAChildOf (getMarkerList (xAxis)); +} + +const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (bool xAxis, const ValueTree& state) const +{ + jassert (containsMarker (xAxis, state)); + + return Marker (state [nameProperty], RelativeCoordinate (state [posProperty].toString(), xAxis)); +} + +void DrawableComposite::ValueTreeWrapper::setMarker (bool xAxis, const Marker& m, UndoManager* undoManager) +{ + ValueTree markerList (getMarkerListCreating (xAxis, undoManager)); + ValueTree marker (markerList.getChildWithProperty (nameProperty, m.name)); if (marker.isValid()) { - jassert ((bool) marker [xAxisProperty] == xAxis); // shouldn't change the axis of a marker after it has been created! - marker.setProperty (posProperty, position.toString(), undoManager); + marker.setProperty (posProperty, m.position.toString(), undoManager); } else { marker = ValueTree (markerTag); - marker.setProperty (nameProperty, name, 0); - marker.setProperty (xAxisProperty, xAxis, 0); - marker.setProperty (posProperty, position.toString(), 0); + marker.setProperty (nameProperty, m.name, 0); + marker.setProperty (posProperty, m.position.toString(), 0); markerList.addChild (marker, -1, undoManager); } } -void DrawableComposite::ValueTreeWrapper::removeMarker (int index, UndoManager* undoManager) +void DrawableComposite::ValueTreeWrapper::removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager) { - return getMarkerList().removeChild (index, undoManager); + return getMarkerList (xAxis).removeChild (state, undoManager); } const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) @@ -84416,21 +84495,32 @@ const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& controlPoints[2] = newControlPoint[2]; } + const int numMarkersX = controller.getNumMarkers (true); + const int numMarkersY = controller.getNumMarkers (false); + // Remove deleted markers... int i; - for (i = markers.size(); --i >= controller.getNumMarkers();) + for (i = markersX.size(); --i >= numMarkersX;) { if (damageRect.isEmpty()) damageRect = getUntransformedBounds(); - removeMarker (i); + markersX.remove (i); + } + + for (i = markersY.size(); --i >= numMarkersY;) + { + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + markersY.remove (i); } // Update markers and add new ones.. - for (i = 0; i < controller.getNumMarkers(); ++i) + for (i = 0; i < numMarkersX; ++i) { - const Marker newMarker (controller.getMarker (i)); - Marker* m = markers[i]; + const Marker newMarker (controller.getMarker (true, controller.getMarkerState (true, i))); + Marker* m = markersX[i]; if (m == 0 || newMarker != *m) { @@ -84439,7 +84529,25 @@ const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& damageRect = getUntransformedBounds(); if (m == 0) - markers.add (new Marker (newMarker)); + markersX.add (new Marker (newMarker)); + else + *m = newMarker; + } + } + + for (i = 0; i < numMarkersY; ++i) + { + const Marker newMarker (controller.getMarker (false, controller.getMarkerState (false, i))); + Marker* m = markersY[i]; + + if (m == 0 || newMarker != *m) + { + redrawAll = true; + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + if (m == 0) + markersY.add (new Marker (newMarker)); else *m = newMarker; } @@ -84504,11 +84612,11 @@ const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider for (i = 0; i < drawables.size(); ++i) v.addDrawable (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); - for (i = 0; i < markers.size(); ++i) - { - const Marker* m = markers.getUnchecked(i); - v.setMarker (m->name, m->isOnXAxis, m->position, 0); - } + for (i = 0; i < markersX.size(); ++i) + v.setMarker (true, *markersX.getUnchecked(i), 0); + + for (i = 0; i < markersY.size(); ++i) + v.setMarker (false, *markersY.getUnchecked(i), 0); return tree; } @@ -85060,7 +85168,7 @@ void DrawablePath::ValueTreeWrapper::setPath (const String& newPath, UndoManager state.setProperty (path, newPath, undoManager); } -const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider*) { Rectangle damageRect; ValueTreeWrapper v (tree); @@ -85110,7 +85218,7 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree return damageRect; } -const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) const +const ValueTree DrawablePath::createValueTree (ImageProvider*) const { ValueTree tree (valueTreeType); ValueTreeWrapper v (tree); @@ -85201,7 +85309,7 @@ DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) jassert (state.hasType (valueTreeType)); } -const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider*) { ValueTreeWrapper v (tree); setName (v.getID()); @@ -85211,7 +85319,7 @@ const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree return Rectangle(); } -const ValueTree DrawableText::createValueTree (ImageProvider* imageProvider) const +const ValueTree DrawableText::createValueTree (ImageProvider*) const { ValueTree tree (valueTreeType); ValueTreeWrapper v (tree); @@ -87217,9 +87325,7 @@ PositionedGlyph& GlyphArrangement::getGlyph (const int index) const void GlyphArrangement::addGlyphArrangement (const GlyphArrangement& other) { glyphs.ensureStorageAllocated (glyphs.size() + other.glyphs.size()); - - for (int i = 0; i < other.glyphs.size(); ++i) - glyphs.add (new PositionedGlyph (*other.glyphs.getUnchecked (i))); + glyphs.addCopiesOf (other.glyphs); } void GlyphArrangement::removeRangeOfGlyphs (int startIndex, const int num) @@ -87935,9 +88041,7 @@ TextLayout& TextLayout::operator= (const TextLayout& other) clear(); totalLines = other.totalLines; - - for (int i = 0; i < other.tokens.size(); ++i) - tokens.add (new Token (*other.tokens.getUnchecked(i))); + tokens.addCopiesOf (other.tokens); } return *this; @@ -237356,16 +237460,49 @@ int64 juce_getInternetFileContentLength (void* handle) { DWORD index = 0, result = 0, size = sizeof (result); - if (HttpQueryInfo (crs->request, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, - &result, &size, &index)) - { + if (HttpQueryInfo (crs->request, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &result, &size, &index)) return (int64) result; - } } return -1; } +void juce_getInternetFileHeaders (void* handle, StringPairArray& headers) +{ + const ConnectionAndRequestStruct* const crs = static_cast (handle); + + if (crs != 0) + { + DWORD bufferSizeBytes = 4096; + + for (;;) + { + HeapBlock buffer ((size_t) bufferSizeBytes); + + if (HttpQueryInfo (crs->request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer.getData(), &bufferSizeBytes, 0)) + { + StringArray headersArray; + headersArray.addLines (reinterpret_cast (buffer.getData())); + + for (int i = 0; i < headersArray.size(); ++i) + { + const String& header = headersArray[i]; + const String key (header.upToFirstOccurrenceOf (": ", false, false)); + const String value (header.fromFirstOccurrenceOf (": ", false, false)); + const String previousValue (headers [key]); + + headers.set (key, previousValue.isEmpty() ? value : (previousValue + ";" + value)); + } + + break; + } + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + break; + } + } +} + void juce_closeInternetFile (void* handle) { if (handle != 0) @@ -253151,6 +253288,17 @@ int64 juce_getInternetFileContentLength (void* handle) return -1; } +void juce_getInternetFileHeaders (void* handle, StringPairArray& headers) +{ + JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle; + + if (s != 0) + { + // xxx todo + jassertfalse; + } +} + int juce_seekInInternetFile (void* handle, int newPosition) { JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle; @@ -257511,6 +257659,9 @@ void juce_updateMultiMonitorInfo (Array >& monitorCoords, const { void* h = dlopen ("libXinerama.so", RTLD_GLOBAL | RTLD_NOW); + if (h == 0) + h = dlopen ("libXinerama.so.1", RTLD_GLOBAL | RTLD_NOW); + if (h != 0) { xXineramaIsActive = (tXineramaIsActive) dlsym (h, "XineramaIsActive"); @@ -260951,6 +261102,7 @@ using namespace JUCE_NAMESPACE; bool initialised, hasFailed, hasFinished; int position; int64 contentLength; + NSDictionary* headers; NSLock* dataLock; } @@ -261013,6 +261165,7 @@ public: hasFailed = false; hasFinished = false; contentLength = -1; + headers = 0; runLoopThread = new JuceURLConnectionMessageThread (self); runLoopThread->startThread(); @@ -261037,6 +261190,7 @@ public: [data release]; [dataLock release]; [request release]; + [headers release]; [super dealloc]; } @@ -261057,6 +261211,12 @@ public: [dataLock unlock]; initialised = true; contentLength = [response expectedContentLength]; + + [headers release]; + headers = 0; + + if ([response isKindOfClass: [NSHTTPURLResponse class]]) + headers = [[((NSHTTPURLResponse*) response) allHeaderFields] retain]; } - (void) connection: (NSURLConnection*) conn didFailWithError: (NSError*) error @@ -261228,6 +261388,25 @@ int64 juce_getInternetFileContentLength (void* handle) return -1; } +bool juce_getInternetFileHeaders (void* handle, StringPairArray& headers) +{ + JuceURLConnection* const s = (JuceURLConnection*) handle; + + if (s != 0 && s->headers != 0) + { + NSEnumerator* enumerator = [s->headers keyEnumerator]; + NSString* key; + + while ((key = [enumerator nextObject]) != nil) + headers.set (nsStringToJuce (key), + nsStringToJuce ((NSString*) [s->headers objectForKey: key])); + + return true; + } + + return false; +} + int juce_seekInInternetFile (void* handle, int /*newPosition*/) { JuceURLConnection* const s = (JuceURLConnection*) handle; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 6cb5cb4e03..659dd92f00 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -3921,7 +3921,10 @@ public: data.ensureAllocatedSize (numUsed + numElementsToAdd); while (--numElementsToAdd >= 0) - new (data.elements + numUsed++) ElementType (*elementsToAdd++); + { + new (data.elements + numUsed) ElementType (*elementsToAdd++); + ++numUsed; + } } } @@ -6763,8 +6766,53 @@ public: if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) numElementsToAdd = arrayToAddFrom.size() - startIndex; + data.ensureAllocatedSize (numUsed + numElementsToAdd); + while (--numElementsToAdd >= 0) - add (arrayToAddFrom.getUnchecked (startIndex++)); + { + data.elements [numUsed] = arrayToAddFrom.getUnchecked (startIndex++); + ++numUsed; + } + } + + /** Adds copies of the elements in another array to the end of this array. + + The other array must be either an OwnedArray of a compatible type of object, or an Array + containing pointers to the same kind of object. The objects involved must provide + a copy constructor, and this will be used to create new copies of each element, and + add them to this array. + + @param arrayToAddFrom the array from which to copy the elements + @param startIndex the first element of the other array to start copying from + @param numElementsToAdd how many elements to add from the other array. If this + value is negative or greater than the number of available elements, + all available elements will be copied. + @see add + */ + template + void addCopiesOf (const OtherArrayType& arrayToAddFrom, + int startIndex = 0, + int numElementsToAdd = -1) + { + const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock()); + const ScopedLockType lock2 (getLock()); + + if (startIndex < 0) + { + jassertfalse; + startIndex = 0; + } + + if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) + numElementsToAdd = arrayToAddFrom.size() - startIndex; + + data.ensureAllocatedSize (numUsed + numElementsToAdd); + + while (--numElementsToAdd >= 0) + { + data.elements [numUsed] = new ObjectClass (*arrayToAddFrom.getUnchecked (startIndex++)); + ++numUsed; + } } /** Inserts a new object into the array assuming that the array is sorted. @@ -15993,7 +16041,7 @@ public: */ const URL withNewSubPath (const String& newPath) const; - /** Returns a copy of this URL, with a GET parameter added to the end. + /** Returns a copy of this URL, with a GET or POST parameter added to the end. Any control characters in the value will be encoded. @@ -16097,12 +16145,17 @@ public: @param connectionTimeOutMs if 0, this will use whatever default setting the OS chooses. If a negative number, it will be infinite. Otherwise it specifies a time in milliseconds. - */ + @param responseHeaders if this is non-zero, all the (key, value) pairs received as headers + in the response will be stored in this array + @returns an input stream that the caller must delete, or a null pointer if there was an + error trying to open it. + */ InputStream* createInputStream (bool usePostCommand, OpenStreamProgressCallback* progressCallback = 0, void* progressCallbackContext = 0, const String& extraHeaders = String::empty, - int connectionTimeOutMs = 0) const; + int connectionTimeOutMs = 0, + StringPairArray* responseHeaders = 0) const; /** Tries to download the entire contents of this URL into a binary data block. @@ -42228,6 +42281,10 @@ public: virtual RelativePoint* getControlPoints (int& numPoints) = 0; const ElementType type; + + private: + ElementBase (const ElementBase&); + ElementBase& operator= (const ElementBase&); }; class JUCE_API StartSubPath : public ElementBase @@ -42240,6 +42297,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint startPos; + + private: + StartSubPath (const StartSubPath&); + StartSubPath& operator= (const StartSubPath&); }; class JUCE_API CloseSubPath : public ElementBase @@ -42250,6 +42311,10 @@ public: void write (OutputStream& out, ElementType lastTypeWritten) const; void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; RelativePoint* getControlPoints (int& numPoints); + + private: + CloseSubPath (const CloseSubPath&); + CloseSubPath& operator= (const CloseSubPath&); }; class JUCE_API LineTo : public ElementBase @@ -42262,6 +42327,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint endPoint; + + private: + LineTo (const LineTo&); + LineTo& operator= (const LineTo&); }; class JUCE_API QuadraticTo : public ElementBase @@ -42274,6 +42343,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint controlPoints[2]; + + private: + QuadraticTo (const QuadraticTo&); + QuadraticTo& operator= (const QuadraticTo&); }; class JUCE_API CubicTo : public ElementBase @@ -42286,6 +42359,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint controlPoints[3]; + + private: + CubicTo (const CubicTo&); + CubicTo& operator= (const CubicTo&); }; OwnedArray elements; @@ -42509,11 +42586,13 @@ public: void setID (const String& newID, UndoManager* undoManager); static const Identifier idProperty; + static const FillType readFillType (const ValueTree& v); + static void writeFillType (ValueTree& v, const FillType& fillType, UndoManager* undoManager); + protected: ValueTree state; static const Identifier 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); }; @@ -49362,6 +49441,8 @@ class JUCE_API PositionedGlyph { public: + PositionedGlyph (const PositionedGlyph& other); + /** Returns the character the glyph represents. */ juce_wchar getCharacter() const { return character; } /** Checks whether the glyph is actually empty. */ @@ -49409,7 +49490,6 @@ private: int glyph; PositionedGlyph (float x, float y, float w, const Font& font, juce_wchar character, int glyph); - PositionedGlyph (const PositionedGlyph& other); }; /** @@ -58158,18 +58238,17 @@ public: struct Marker { Marker (const Marker&); - Marker (const String& name, const RelativeCoordinate& position, bool isOnXAxis); + Marker (const String& name, const RelativeCoordinate& position); 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(); + const Marker* getMarker (bool xAxis, int index) const throw(); void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position); - void removeMarker (int index); + void removeMarker (bool xAxis, int index); /** @internal */ void render (const Drawable::RenderingContext& context) const; @@ -58214,19 +58293,24 @@ public: 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); + int getNumMarkers (bool xAxis) const; + const ValueTree getMarkerState (bool xAxis, int index) const; + const ValueTree getMarkerState (bool xAxis, const String& name) const; + bool containsMarker (bool xAxis, const ValueTree& state) const; + const Marker getMarker (bool xAxis, const ValueTree& state) const; + void setMarker (bool xAxis, const Marker& marker, UndoManager* undoManager); + void removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager); + + static const Identifier nameProperty, posProperty; private: - static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTag, - markerTag, nameProperty, xAxisProperty, posProperty; + static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTagX, + markerGroupTagY, markerTag; ValueTree getChildList() const; ValueTree getChildListCreating (UndoManager* undoManager); - ValueTree getMarkerList() const; - ValueTree getMarkerListCreating (UndoManager* undoManager); + ValueTree getMarkerList (bool xAxis) const; + ValueTree getMarkerListCreating (bool xAxis, UndoManager* undoManager); }; juce_UseDebuggingNewOperator @@ -58234,7 +58318,7 @@ public: private: OwnedArray drawables; RelativePoint controlPoints[3]; - OwnedArray markers; + OwnedArray markersX, markersY; const Rectangle getUntransformedBounds() const; const AffineTransform calculateTransform() const; @@ -58521,7 +58605,6 @@ public: void getPath (RelativePointPath& path) const; void setPath (const String& newPath, UndoManager* undoManager); - private: static const Identifier fill, stroke, jointStyle, capStyle, strokeWidth, path; }; diff --git a/src/containers/juce_Array.h b/src/containers/juce_Array.h index fe7ff9e3ea..634a369c6e 100644 --- a/src/containers/juce_Array.h +++ b/src/containers/juce_Array.h @@ -534,7 +534,10 @@ public: data.ensureAllocatedSize (numUsed + numElementsToAdd); while (--numElementsToAdd >= 0) - new (data.elements + numUsed++) ElementType (*elementsToAdd++); + { + new (data.elements + numUsed) ElementType (*elementsToAdd++); + ++numUsed; + } } } diff --git a/src/containers/juce_OwnedArray.h b/src/containers/juce_OwnedArray.h index 9b76d6d3a3..44fbcb8c84 100644 --- a/src/containers/juce_OwnedArray.h +++ b/src/containers/juce_OwnedArray.h @@ -350,8 +350,53 @@ public: if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) numElementsToAdd = arrayToAddFrom.size() - startIndex; + data.ensureAllocatedSize (numUsed + numElementsToAdd); + while (--numElementsToAdd >= 0) - add (arrayToAddFrom.getUnchecked (startIndex++)); + { + data.elements [numUsed] = arrayToAddFrom.getUnchecked (startIndex++); + ++numUsed; + } + } + + /** Adds copies of the elements in another array to the end of this array. + + The other array must be either an OwnedArray of a compatible type of object, or an Array + containing pointers to the same kind of object. The objects involved must provide + a copy constructor, and this will be used to create new copies of each element, and + add them to this array. + + @param arrayToAddFrom the array from which to copy the elements + @param startIndex the first element of the other array to start copying from + @param numElementsToAdd how many elements to add from the other array. If this + value is negative or greater than the number of available elements, + all available elements will be copied. + @see add + */ + template + void addCopiesOf (const OtherArrayType& arrayToAddFrom, + int startIndex = 0, + int numElementsToAdd = -1) + { + const typename OtherArrayType::ScopedLockType lock1 (arrayToAddFrom.getLock()); + const ScopedLockType lock2 (getLock()); + + if (startIndex < 0) + { + jassertfalse; + startIndex = 0; + } + + if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) + numElementsToAdd = arrayToAddFrom.size() - startIndex; + + data.ensureAllocatedSize (numUsed + numElementsToAdd); + + while (--numElementsToAdd >= 0) + { + data.elements [numUsed] = new ObjectClass (*arrayToAddFrom.getUnchecked (startIndex++)); + ++numUsed; + } } /** Inserts a new object into the array assuming that the array is sorted. diff --git a/src/gui/components/menus/juce_PopupMenu.cpp b/src/gui/components/menus/juce_PopupMenu.cpp index 691b8a1b1e..0da3a89b4a 100644 --- a/src/gui/components/menus/juce_PopupMenu.cpp +++ b/src/gui/components/menus/juce_PopupMenu.cpp @@ -1275,10 +1275,7 @@ PopupMenu::PopupMenu (const PopupMenu& other) : lookAndFeel (other.lookAndFeel), separatorPending (false) { - items.ensureStorageAllocated (other.items.size()); - - for (int i = 0; i < other.items.size(); ++i) - items.add (new Item (*other.items.getUnchecked(i))); + items.addCopiesOf (other.items); } PopupMenu& PopupMenu::operator= (const PopupMenu& other) @@ -1288,10 +1285,7 @@ PopupMenu& PopupMenu::operator= (const PopupMenu& other) lookAndFeel = other.lookAndFeel; clear(); - items.ensureStorageAllocated (other.items.size()); - - for (int i = 0; i < other.items.size(); ++i) - items.add (new Item (*other.items.getUnchecked(i))); + items.addCopiesOf (other.items); } return *this; diff --git a/src/gui/components/properties/juce_ChoicePropertyComponent.cpp b/src/gui/components/properties/juce_ChoicePropertyComponent.cpp index 01742125fc..9c8a5249bc 100644 --- a/src/gui/components/properties/juce_ChoicePropertyComponent.cpp +++ b/src/gui/components/properties/juce_ChoicePropertyComponent.cpp @@ -121,7 +121,7 @@ void ChoicePropertyComponent::createComboBox() comboBox->setEditableText (false); } -void ChoicePropertyComponent::setIndex (const int newIndex) +void ChoicePropertyComponent::setIndex (const int /*newIndex*/) { jassertfalse; // you need to override this method in your subclass! } diff --git a/src/gui/graphics/drawables/juce_Drawable.cpp b/src/gui/graphics/drawables/juce_Drawable.cpp index 3f5f0a089e..510a584b4e 100644 --- a/src/gui/graphics/drawables/juce_Drawable.cpp +++ b/src/gui/graphics/drawables/juce_Drawable.cpp @@ -223,16 +223,8 @@ const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v) return FillType(); } -void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager) +void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType, UndoManager* const 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); @@ -281,5 +273,18 @@ void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, con } } +void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* const undoManager) +{ + ValueTree v (state.getChildWithName (tag)); + + if (! v.isValid()) + { + state.addChild (ValueTree (tag), -1, undoManager); + v = state.getChildWithName (tag); + } + + writeFillType (v, fillType, undoManager); +} + END_JUCE_NAMESPACE diff --git a/src/gui/graphics/drawables/juce_Drawable.h b/src/gui/graphics/drawables/juce_Drawable.h index 88d43e8b9b..f2cdc2e437 100644 --- a/src/gui/graphics/drawables/juce_Drawable.h +++ b/src/gui/graphics/drawables/juce_Drawable.h @@ -248,11 +248,13 @@ public: void setID (const String& newID, UndoManager* undoManager); static const Identifier idProperty; + static const FillType readFillType (const ValueTree& v); + static void writeFillType (ValueTree& v, const FillType& fillType, UndoManager* undoManager); + protected: ValueTree state; static const Identifier 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); }; diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.cpp b/src/gui/graphics/drawables/juce_DrawableComposite.cpp index abe8ddc472..9c837100d1 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.cpp +++ b/src/gui/graphics/drawables/juce_DrawableComposite.cpp @@ -50,8 +50,8 @@ DrawableComposite::DrawableComposite (const DrawableComposite& other) 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))); + markersX.addCopiesOf (other.markersX); + markersY.addCopiesOf (other.markersY); } DrawableComposite::~DrawableComposite() @@ -106,40 +106,40 @@ void DrawableComposite::setTransform (const RelativePoint& targetPositionForOrig //============================================================================== DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other) - : name (other.name), position (other.position), isOnXAxis (other.isOnXAxis) + : name (other.name), position (other.position) { } -DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_, const bool isOnXAxis_) - : name (name_), position (position_), isOnXAxis (isOnXAxis_) +DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_) + : name (name_), position (position_) { } bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw() { - return name != other.name || position != other.position || isOnXAxis != other.isOnXAxis; + return name != other.name || position != other.position; } //============================================================================== -int DrawableComposite::getNumMarkers (bool xAxis) const throw() +int DrawableComposite::getNumMarkers (const bool xAxis) const throw() { - return markers.size(); + return (xAxis ? markersX : markersY).size(); } -const DrawableComposite::Marker* DrawableComposite::getMarker (int index) const throw() +const DrawableComposite::Marker* DrawableComposite::getMarker (const bool xAxis, const int index) const throw() { - return markers [index]; + return (xAxis ? markersX : markersY) [index]; } -void DrawableComposite::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position) +void DrawableComposite::setMarker (const String& name, const bool xAxis, const RelativeCoordinate& position) { + OwnedArray & markers = (xAxis ? markersX : markersY); + 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; @@ -150,13 +150,13 @@ void DrawableComposite::setMarker (const String& name, bool xAxis, const Relativ } } - markers.add (new Marker (name, position, xAxis)); + (xAxis ? markersX : markersY).add (new Marker (name, position)); invalidatePoints(); } -void DrawableComposite::removeMarker (int index) +void DrawableComposite::removeMarker (const bool xAxis, const int index) { - markers.remove (index); + (xAxis ? markersX : markersY).remove (index); } //============================================================================== @@ -221,9 +221,17 @@ const RelativeCoordinate DrawableComposite::findNamedCoordinate (const String& o } } - for (int i = 0; i < markers.size(); ++i) + int i; + for (i = 0; i < markersX.size(); ++i) { - Marker* const m = markers.getUnchecked(i); + Marker* const m = markersX.getUnchecked(i); + if (m->name == objectName) + return m->position; + } + + for (i = 0; i < markersY.size(); ++i) + { + Marker* const m = markersY.getUnchecked(i); if (m->name == objectName) return m->position; } @@ -235,9 +243,66 @@ const Rectangle DrawableComposite::getUntransformedBounds() const { Rectangle bounds; - for (int i = 0; i < drawables.size(); ++i) + int i; + for (i = 0; i < drawables.size(); ++i) bounds = bounds.getUnion (drawables.getUnchecked(i)->getBounds()); + if (markersX.size() > 0) + { + float minX = std::numeric_limits::max(); + float maxX = std::numeric_limits::min(); + + for (i = markersX.size(); --i >= 0;) + { + const Marker* m = markersX.getUnchecked(i); + const float pos = (float) m->position.resolve (parent); + minX = jmin (minX, pos); + maxX = jmax (maxX, pos); + } + + if (minX <= maxX) + { + if (bounds.getWidth() == 0) + { + bounds.setLeft (minX); + bounds.setWidth (maxX - minX); + } + else + { + bounds.setLeft (jmin (bounds.getX(), minX)); + bounds.setRight (jmax (bounds.getRight(), maxX)); + } + } + } + + if (markersY.size() > 0) + { + float minY = std::numeric_limits::max(); + float maxY = std::numeric_limits::min(); + + for (i = markersY.size(); --i >= 0;) + { + const Marker* m = markersY.getUnchecked(i); + const float pos = (float) m->position.resolve (parent); + minY = jmin (minY, pos); + maxY = jmax (maxY, pos); + } + + if (minY <= maxY) + { + if (bounds.getHeight() == 0) + { + bounds.setTop (minY); + bounds.setHeight (maxY - minY); + } + else + { + bounds.setTop (jmin (bounds.getY(), minY)); + bounds.setBottom (jmax (bounds.getBottom(), maxY)); + } + } + } + return bounds; } @@ -275,10 +340,10 @@ 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::markerGroupTagX ("MarkersX"); +const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagY ("MarkersY"); const Identifier DrawableComposite::ValueTreeWrapper::markerTag ("Marker"); const Identifier DrawableComposite::ValueTreeWrapper::nameProperty ("name"); -const Identifier DrawableComposite::ValueTreeWrapper::xAxisProperty ("xAxis"); const Identifier DrawableComposite::ValueTreeWrapper::posProperty ("position"); //============================================================================== @@ -303,21 +368,6 @@ ValueTree DrawableComposite::ValueTreeWrapper::getChildListCreating (UndoManager return getChildList(); } -ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList() const -{ - 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(); @@ -409,44 +459,69 @@ void DrawableComposite::ValueTreeWrapper::setTargetPositionForX0Y1 (const Relati state.setProperty (bottomLeft, newPoint.toString(), undoManager); } -int DrawableComposite::ValueTreeWrapper::getNumMarkers() const +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const { - return getMarkerList().getNumChildren(); + return state.getChildWithName (xAxis ? markerGroupTagX : markerGroupTagY); } -const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (int index) const +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager) { - const ValueTree marker (getMarkerList().getChild (index)); - const bool isXAxis = marker [xAxisProperty]; + const ValueTree markerList (getMarkerList (xAxis)); + if (markerList.isValid()) + return markerList; - return Marker (marker [nameProperty], - RelativeCoordinate (marker [posProperty].toString(), isXAxis), - isXAxis); + state.addChild (ValueTree (xAxis ? markerGroupTagX : markerGroupTagY), -1, undoManager); + return getMarkerList (xAxis); } -void DrawableComposite::ValueTreeWrapper::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager) +int DrawableComposite::ValueTreeWrapper::getNumMarkers (bool xAxis) const { - ValueTree markerList (getMarkerListCreating (undoManager)); - ValueTree marker (markerList.getChildWithProperty (nameProperty, name)); + return getMarkerList (xAxis).getNumChildren(); +} + +const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, int index) const +{ + return getMarkerList (xAxis).getChild (index); +} + +const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, const String& name) const +{ + return getMarkerList (xAxis).getChildWithProperty (nameProperty, name); +} + +bool DrawableComposite::ValueTreeWrapper::containsMarker (bool xAxis, const ValueTree& state) const +{ + return state.isAChildOf (getMarkerList (xAxis)); +} + +const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (bool xAxis, const ValueTree& state) const +{ + jassert (containsMarker (xAxis, state)); + + return Marker (state [nameProperty], RelativeCoordinate (state [posProperty].toString(), xAxis)); +} + +void DrawableComposite::ValueTreeWrapper::setMarker (bool xAxis, const Marker& m, UndoManager* undoManager) +{ + ValueTree markerList (getMarkerListCreating (xAxis, undoManager)); + ValueTree marker (markerList.getChildWithProperty (nameProperty, m.name)); if (marker.isValid()) { - jassert ((bool) marker [xAxisProperty] == xAxis); // shouldn't change the axis of a marker after it has been created! - marker.setProperty (posProperty, position.toString(), undoManager); + marker.setProperty (posProperty, m.position.toString(), undoManager); } else { marker = ValueTree (markerTag); - marker.setProperty (nameProperty, name, 0); - marker.setProperty (xAxisProperty, xAxis, 0); - marker.setProperty (posProperty, position.toString(), 0); + marker.setProperty (nameProperty, m.name, 0); + marker.setProperty (posProperty, m.position.toString(), 0); markerList.addChild (marker, -1, undoManager); } } -void DrawableComposite::ValueTreeWrapper::removeMarker (int index, UndoManager* undoManager) +void DrawableComposite::ValueTreeWrapper::removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager) { - return getMarkerList().removeChild (index, undoManager); + return getMarkerList (xAxis).removeChild (state, undoManager); } //============================================================================== @@ -473,21 +548,32 @@ const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& controlPoints[2] = newControlPoint[2]; } + const int numMarkersX = controller.getNumMarkers (true); + const int numMarkersY = controller.getNumMarkers (false); + // Remove deleted markers... int i; - for (i = markers.size(); --i >= controller.getNumMarkers();) + for (i = markersX.size(); --i >= numMarkersX;) { if (damageRect.isEmpty()) damageRect = getUntransformedBounds(); - removeMarker (i); + markersX.remove (i); + } + + for (i = markersY.size(); --i >= numMarkersY;) + { + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + markersY.remove (i); } // Update markers and add new ones.. - for (i = 0; i < controller.getNumMarkers(); ++i) + for (i = 0; i < numMarkersX; ++i) { - const Marker newMarker (controller.getMarker (i)); - Marker* m = markers[i]; + const Marker newMarker (controller.getMarker (true, controller.getMarkerState (true, i))); + Marker* m = markersX[i]; if (m == 0 || newMarker != *m) { @@ -496,7 +582,25 @@ const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& damageRect = getUntransformedBounds(); if (m == 0) - markers.add (new Marker (newMarker)); + markersX.add (new Marker (newMarker)); + else + *m = newMarker; + } + } + + for (i = 0; i < numMarkersY; ++i) + { + const Marker newMarker (controller.getMarker (false, controller.getMarkerState (false, i))); + Marker* m = markersY[i]; + + if (m == 0 || newMarker != *m) + { + redrawAll = true; + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + if (m == 0) + markersY.add (new Marker (newMarker)); else *m = newMarker; } @@ -561,11 +665,11 @@ const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider for (i = 0; i < drawables.size(); ++i) v.addDrawable (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); - for (i = 0; i < markers.size(); ++i) - { - const Marker* m = markers.getUnchecked(i); - v.setMarker (m->name, m->isOnXAxis, m->position, 0); - } + for (i = 0; i < markersX.size(); ++i) + v.setMarker (true, *markersX.getUnchecked(i), 0); + + for (i = 0; i < markersY.size(); ++i) + v.setMarker (false, *markersY.getUnchecked(i), 0); return tree; } diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.h b/src/gui/graphics/drawables/juce_DrawableComposite.h index a3e48df2d6..76b2099988 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.h +++ b/src/gui/graphics/drawables/juce_DrawableComposite.h @@ -154,18 +154,17 @@ public: struct Marker { Marker (const Marker&); - Marker (const String& name, const RelativeCoordinate& position, bool isOnXAxis); + Marker (const String& name, const RelativeCoordinate& position); 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(); + const Marker* getMarker (bool xAxis, int index) const throw(); void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position); - void removeMarker (int index); + void removeMarker (bool xAxis, int index); //============================================================================== /** @internal */ @@ -212,19 +211,24 @@ public: 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); + int getNumMarkers (bool xAxis) const; + const ValueTree getMarkerState (bool xAxis, int index) const; + const ValueTree getMarkerState (bool xAxis, const String& name) const; + bool containsMarker (bool xAxis, const ValueTree& state) const; + const Marker getMarker (bool xAxis, const ValueTree& state) const; + void setMarker (bool xAxis, const Marker& marker, UndoManager* undoManager); + void removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager); + + static const Identifier nameProperty, posProperty; private: - static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTag, - markerTag, nameProperty, xAxisProperty, posProperty; + static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTagX, + markerGroupTagY, markerTag; ValueTree getChildList() const; ValueTree getChildListCreating (UndoManager* undoManager); - ValueTree getMarkerList() const; - ValueTree getMarkerListCreating (UndoManager* undoManager); + ValueTree getMarkerList (bool xAxis) const; + ValueTree getMarkerListCreating (bool xAxis, UndoManager* undoManager); }; //============================================================================== @@ -233,7 +237,7 @@ public: private: OwnedArray drawables; RelativePoint controlPoints[3]; - OwnedArray markers; + OwnedArray markersX, markersY; const Rectangle getUntransformedBounds() const; const AffineTransform calculateTransform() const; diff --git a/src/gui/graphics/drawables/juce_DrawablePath.cpp b/src/gui/graphics/drawables/juce_DrawablePath.cpp index e537b7cfe0..3af7b83693 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.cpp +++ b/src/gui/graphics/drawables/juce_DrawablePath.cpp @@ -251,7 +251,7 @@ void DrawablePath::ValueTreeWrapper::setPath (const String& newPath, UndoManager state.setProperty (path, newPath, undoManager); } -const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider*) { Rectangle damageRect; ValueTreeWrapper v (tree); @@ -301,7 +301,7 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree return damageRect; } -const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) const +const ValueTree DrawablePath::createValueTree (ImageProvider*) const { ValueTree tree (valueTreeType); ValueTreeWrapper v (tree); diff --git a/src/gui/graphics/drawables/juce_DrawablePath.h b/src/gui/graphics/drawables/juce_DrawablePath.h index 74ff1cd4f1..34343e28c4 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.h +++ b/src/gui/graphics/drawables/juce_DrawablePath.h @@ -140,7 +140,6 @@ public: void getPath (RelativePointPath& path) const; void setPath (const String& newPath, UndoManager* undoManager); - private: static const Identifier fill, stroke, jointStyle, capStyle, strokeWidth, path; }; diff --git a/src/gui/graphics/drawables/juce_DrawableText.cpp b/src/gui/graphics/drawables/juce_DrawableText.cpp index 226c9c6c20..76d2cb24a8 100644 --- a/src/gui/graphics/drawables/juce_DrawableText.cpp +++ b/src/gui/graphics/drawables/juce_DrawableText.cpp @@ -100,7 +100,7 @@ DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) jassert (state.hasType (valueTreeType)); } -const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider*) { ValueTreeWrapper v (tree); setName (v.getID()); @@ -110,7 +110,7 @@ const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree return Rectangle(); } -const ValueTree DrawableText::createValueTree (ImageProvider* imageProvider) const +const ValueTree DrawableText::createValueTree (ImageProvider*) const { ValueTree tree (valueTreeType); ValueTreeWrapper v (tree); diff --git a/src/gui/graphics/fonts/juce_GlyphArrangement.cpp b/src/gui/graphics/fonts/juce_GlyphArrangement.cpp index a997b7c194..7724b9c6e1 100644 --- a/src/gui/graphics/fonts/juce_GlyphArrangement.cpp +++ b/src/gui/graphics/fonts/juce_GlyphArrangement.cpp @@ -165,9 +165,7 @@ PositionedGlyph& GlyphArrangement::getGlyph (const int index) const void GlyphArrangement::addGlyphArrangement (const GlyphArrangement& other) { glyphs.ensureStorageAllocated (glyphs.size() + other.glyphs.size()); - - for (int i = 0; i < other.glyphs.size(); ++i) - glyphs.add (new PositionedGlyph (*other.glyphs.getUnchecked (i))); + glyphs.addCopiesOf (other.glyphs); } void GlyphArrangement::removeRangeOfGlyphs (int startIndex, const int num) diff --git a/src/gui/graphics/fonts/juce_GlyphArrangement.h b/src/gui/graphics/fonts/juce_GlyphArrangement.h index bfda8e16ed..0357ea8478 100644 --- a/src/gui/graphics/fonts/juce_GlyphArrangement.h +++ b/src/gui/graphics/fonts/juce_GlyphArrangement.h @@ -41,6 +41,8 @@ class JUCE_API PositionedGlyph { public: //============================================================================== + PositionedGlyph (const PositionedGlyph& other); + /** Returns the character the glyph represents. */ juce_wchar getCharacter() const { return character; } /** Checks whether the glyph is actually empty. */ @@ -91,7 +93,6 @@ private: int glyph; PositionedGlyph (float x, float y, float w, const Font& font, juce_wchar character, int glyph); - PositionedGlyph (const PositionedGlyph& other); }; diff --git a/src/gui/graphics/fonts/juce_TextLayout.cpp b/src/gui/graphics/fonts/juce_TextLayout.cpp index 238b62ac5f..95e910bf0c 100644 --- a/src/gui/graphics/fonts/juce_TextLayout.cpp +++ b/src/gui/graphics/fonts/juce_TextLayout.cpp @@ -118,9 +118,7 @@ TextLayout& TextLayout::operator= (const TextLayout& other) clear(); totalLines = other.totalLines; - - for (int i = 0; i < other.tokens.size(); ++i) - tokens.add (new Token (*other.tokens.getUnchecked(i))); + tokens.addCopiesOf (other.tokens); } return *this; diff --git a/src/gui/graphics/geometry/juce_RelativeCoordinate.h b/src/gui/graphics/geometry/juce_RelativeCoordinate.h index 74c380fc1e..377ef18054 100644 --- a/src/gui/graphics/geometry/juce_RelativeCoordinate.h +++ b/src/gui/graphics/geometry/juce_RelativeCoordinate.h @@ -462,6 +462,10 @@ public: virtual RelativePoint* getControlPoints (int& numPoints) = 0; const ElementType type; + + private: + ElementBase (const ElementBase&); + ElementBase& operator= (const ElementBase&); }; class JUCE_API StartSubPath : public ElementBase @@ -474,6 +478,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint startPos; + + private: + StartSubPath (const StartSubPath&); + StartSubPath& operator= (const StartSubPath&); }; class JUCE_API CloseSubPath : public ElementBase @@ -484,6 +492,10 @@ public: void write (OutputStream& out, ElementType lastTypeWritten) const; void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; RelativePoint* getControlPoints (int& numPoints); + + private: + CloseSubPath (const CloseSubPath&); + CloseSubPath& operator= (const CloseSubPath&); }; class JUCE_API LineTo : public ElementBase @@ -496,6 +508,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint endPoint; + + private: + LineTo (const LineTo&); + LineTo& operator= (const LineTo&); }; class JUCE_API QuadraticTo : public ElementBase @@ -508,6 +524,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint controlPoints[2]; + + private: + QuadraticTo (const QuadraticTo&); + QuadraticTo& operator= (const QuadraticTo&); }; class JUCE_API CubicTo : public ElementBase @@ -520,6 +540,10 @@ public: RelativePoint* getControlPoints (int& numPoints); RelativePoint controlPoints[3]; + + private: + CubicTo (const CubicTo&); + CubicTo& operator= (const CubicTo&); }; //============================================================================== diff --git a/src/io/network/juce_URL.cpp b/src/io/network/juce_URL.cpp index 406b26bc7a..8df99b3396 100644 --- a/src/io/network/juce_URL.cpp +++ b/src/io/network/juce_URL.cpp @@ -244,6 +244,8 @@ void juce_closeInternetFile (void* handle); int juce_readFromInternetFile (void* handle, void* dest, int bytesToRead); int juce_seekInInternetFile (void* handle, int newPosition); int64 juce_getInternetFileContentLength (void* handle); +void juce_getInternetFileHeaders (void* handle, StringPairArray& headers); + //============================================================================== @@ -256,7 +258,8 @@ public: URL::OpenStreamProgressCallback* const progressCallback_, void* const progressCallbackContext_, const String& extraHeaders, - int timeOutMs_) + const int timeOutMs_, + StringPairArray* const responseHeaders) : position (0), finished (false), isPost (isPost_), @@ -277,6 +280,9 @@ public: handle = juce_openInternetFile (server, headers, postData, isPost, progressCallback_, progressCallbackContext_, timeOutMs); + + if (responseHeaders != 0) + juce_getInternetFileHeaders (handle, *responseHeaders); } ~WebInputStream() @@ -419,12 +425,12 @@ InputStream* URL::createInputStream (const bool usePostCommand, OpenStreamProgressCallback* const progressCallback, void* const progressCallbackContext, const String& extraHeaders, - const int timeOutMs) const + const int timeOutMs, + StringPairArray* const responseHeaders) const { ScopedPointer wi (new WebInputStream (*this, usePostCommand, progressCallback, progressCallbackContext, - extraHeaders, - timeOutMs)); + extraHeaders, timeOutMs, responseHeaders)); return wi->isError() ? 0 : wi.release(); } diff --git a/src/io/network/juce_URL.h b/src/io/network/juce_URL.h index f54c22f65a..82c6eaf61c 100644 --- a/src/io/network/juce_URL.h +++ b/src/io/network/juce_URL.h @@ -96,7 +96,7 @@ public: const URL withNewSubPath (const String& newPath) const; //============================================================================== - /** Returns a copy of this URL, with a GET parameter added to the end. + /** Returns a copy of this URL, with a GET or POST parameter added to the end. Any control characters in the value will be encoded. @@ -203,12 +203,17 @@ public: @param connectionTimeOutMs if 0, this will use whatever default setting the OS chooses. If a negative number, it will be infinite. Otherwise it specifies a time in milliseconds. - */ + @param responseHeaders if this is non-zero, all the (key, value) pairs received as headers + in the response will be stored in this array + @returns an input stream that the caller must delete, or a null pointer if there was an + error trying to open it. + */ InputStream* createInputStream (bool usePostCommand, OpenStreamProgressCallback* progressCallback = 0, void* progressCallbackContext = 0, const String& extraHeaders = String::empty, - int connectionTimeOutMs = 0) const; + int connectionTimeOutMs = 0, + StringPairArray* responseHeaders = 0) const; //============================================================================== diff --git a/src/native/linux/juce_linux_Network.cpp b/src/native/linux/juce_linux_Network.cpp index 40641c5f3f..774f2fbafc 100644 --- a/src/native/linux/juce_linux_Network.cpp +++ b/src/native/linux/juce_linux_Network.cpp @@ -458,6 +458,17 @@ int64 juce_getInternetFileContentLength (void* handle) return -1; } +void juce_getInternetFileHeaders (void* handle, StringPairArray& headers) +{ + JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle; + + if (s != 0) + { + // xxx todo + jassertfalse; + } +} + int juce_seekInInternetFile (void* handle, int newPosition) { JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle; diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index 735283de95..0134c2fa9c 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -2763,6 +2763,9 @@ void juce_updateMultiMonitorInfo (Array >& monitorCoords, const { void* h = dlopen ("libXinerama.so", RTLD_GLOBAL | RTLD_NOW); + if (h == 0) + h = dlopen ("libXinerama.so.1", RTLD_GLOBAL | RTLD_NOW); + if (h != 0) { xXineramaIsActive = (tXineramaIsActive) dlsym (h, "XineramaIsActive"); diff --git a/src/native/mac/juce_mac_Network.mm b/src/native/mac/juce_mac_Network.mm index 5630a5ffda..2edbc97f0f 100644 --- a/src/native/mac/juce_mac_Network.mm +++ b/src/native/mac/juce_mac_Network.mm @@ -137,6 +137,7 @@ using namespace JUCE_NAMESPACE; bool initialised, hasFailed, hasFinished; int position; int64 contentLength; + NSDictionary* headers; NSLock* dataLock; } @@ -200,6 +201,7 @@ public: hasFailed = false; hasFinished = false; contentLength = -1; + headers = 0; runLoopThread = new JuceURLConnectionMessageThread (self); runLoopThread->startThread(); @@ -224,6 +226,7 @@ public: [data release]; [dataLock release]; [request release]; + [headers release]; [super dealloc]; } @@ -244,6 +247,12 @@ public: [dataLock unlock]; initialised = true; contentLength = [response expectedContentLength]; + + [headers release]; + headers = 0; + + if ([response isKindOfClass: [NSHTTPURLResponse class]]) + headers = [[((NSHTTPURLResponse*) response) allHeaderFields] retain]; } - (void) connection: (NSURLConnection*) conn didFailWithError: (NSError*) error @@ -416,6 +425,26 @@ int64 juce_getInternetFileContentLength (void* handle) return -1; } +bool juce_getInternetFileHeaders (void* handle, StringPairArray& headers) +{ + JuceURLConnection* const s = (JuceURLConnection*) handle; + + if (s != 0 && s->headers != 0) + { + NSEnumerator* enumerator = [s->headers keyEnumerator]; + NSString* key; + + while ((key = [enumerator nextObject]) != nil) + headers.set (nsStringToJuce (key), + nsStringToJuce ((NSString*) [s->headers objectForKey: key])); + + return true; + } + + return false; +} + + int juce_seekInInternetFile (void* handle, int /*newPosition*/) { JuceURLConnection* const s = (JuceURLConnection*) handle; diff --git a/src/native/windows/juce_win32_Network.cpp b/src/native/windows/juce_win32_Network.cpp index 60733276ab..fd5b52af51 100644 --- a/src/native/windows/juce_win32_Network.cpp +++ b/src/native/windows/juce_win32_Network.cpp @@ -269,16 +269,49 @@ int64 juce_getInternetFileContentLength (void* handle) { DWORD index = 0, result = 0, size = sizeof (result); - if (HttpQueryInfo (crs->request, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, - &result, &size, &index)) - { + if (HttpQueryInfo (crs->request, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &result, &size, &index)) return (int64) result; - } } return -1; } +void juce_getInternetFileHeaders (void* handle, StringPairArray& headers) +{ + const ConnectionAndRequestStruct* const crs = static_cast (handle); + + if (crs != 0) + { + DWORD bufferSizeBytes = 4096; + + for (;;) + { + HeapBlock buffer ((size_t) bufferSizeBytes); + + if (HttpQueryInfo (crs->request, HTTP_QUERY_RAW_HEADERS_CRLF, buffer.getData(), &bufferSizeBytes, 0)) + { + StringArray headersArray; + headersArray.addLines (reinterpret_cast (buffer.getData())); + + for (int i = 0; i < headersArray.size(); ++i) + { + const String& header = headersArray[i]; + const String key (header.upToFirstOccurrenceOf (": ", false, false)); + const String value (header.fromFirstOccurrenceOf (": ", false, false)); + const String previousValue (headers [key]); + + headers.set (key, previousValue.isEmpty() ? value : (previousValue + ";" + value)); + } + + break; + } + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + break; + } + } +} + void juce_closeInternetFile (void* handle) { if (handle != 0) diff --git a/src/text/juce_CharacterFunctions.cpp b/src/text/juce_CharacterFunctions.cpp index f620f4d3e3..83cf8b910d 100644 --- a/src/text/juce_CharacterFunctions.cpp +++ b/src/text/juce_CharacterFunctions.cpp @@ -785,11 +785,11 @@ int CharacterFunctions::getHexDigitValue (const juce_wchar digit) throw() if (d < (unsigned int) 10) return (int) d; - d += '0' - 'a'; + d += (unsigned int) ('0' - 'a'); if (d < (unsigned int) 6) return (int) d + 10; - d += 'a' - 'A'; + d += (unsigned int) ('a' - 'A'); if (d < (unsigned int) 6) return (int) d + 10;