| @@ -43,6 +43,7 @@ ifeq ($(CONFIG),Release) | |||
| endif | |||
| OBJECTS := \ | |||
| $(OBJDIR)/jucer_ComponentTypeManager.o \ | |||
| $(OBJDIR)/jucer_ComponentDocument.o \ | |||
| $(OBJDIR)/jucer_Coordinate.o \ | |||
| $(OBJDIR)/jucer_DrawableDocument.o \ | |||
| @@ -88,6 +89,11 @@ clean: | |||
| -@rm -rf $(OBJDIR)/* | |||
| -@rm -rf $(OBJDIR) | |||
| $(OBJDIR)/jucer_ComponentTypeManager.o: ../../Source/model/Component\ Types/jucer_ComponentTypeManager.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo $(notdir $<) | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/jucer_ComponentDocument.o: ../../Source/model/jucer_ComponentDocument.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo $(notdir $<) | |||
| @@ -17,6 +17,7 @@ | |||
| DBE3CE9482B19CF1AE700805 = { isa = PBXBuildFile; fileRef = 23CF69B4C644D1E6E61E5C82; }; | |||
| 93C9F3F27602A33DDC9C2250 = { isa = PBXBuildFile; fileRef = 2767E1D082874D301D5D5F43; }; | |||
| 2E6836738CE7EB452FDC7E9A = { isa = PBXBuildFile; fileRef = D9FB1A5365FEEB854A0FF7BF; }; | |||
| 52D75B8B0F52DD4F37A4B1C0 = { isa = PBXBuildFile; fileRef = 82A1EC47692975C7031B3973; }; | |||
| CD4226951C3F7FE19CF8A7CE = { isa = PBXBuildFile; fileRef = 2D6D6985B452EA0B67A18914; }; | |||
| 1DF9688E29753A0459E6C32A = { isa = PBXBuildFile; fileRef = 45C80436FD5A8438D0E6BE17; }; | |||
| 1174D3512AF8207950094C56 = { isa = PBXBuildFile; fileRef = FF625CB50FB5C3536BA40604; }; | |||
| @@ -59,8 +60,20 @@ | |||
| D9FB1A5365FEEB854A0FF7BF = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = System/Library/Frameworks/QuickTime.framework; sourceTree = SDKROOT; }; | |||
| 12E1601866B3489844AFD645 = { isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jucer.app; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
| F4C5CF1AA7EB9298043D89D3 = { isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = SOURCE_ROOT; }; | |||
| A6FAA90B494DCD7CA5911196 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ToggleButton.h; path = "../../Source/model/Component Types/jucer_ToggleButton.h"; sourceTree = SOURCE_ROOT; }; | |||
| 82A1EC47692975C7031B3973 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ComponentTypeManager.cpp; path = "../../Source/model/Component Types/jucer_ComponentTypeManager.cpp"; sourceTree = SOURCE_ROOT; }; | |||
| 4F23FF649E7BA3A0F737E3BE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ComponentTypeManager.h; path = "../../Source/model/Component Types/jucer_ComponentTypeManager.h"; sourceTree = SOURCE_ROOT; }; | |||
| 6FD54B7E8992FD692BAA0DC6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ComponentTypes.h; path = "../../Source/model/Component Types/jucer_ComponentTypes.h"; sourceTree = SOURCE_ROOT; }; | |||
| 926FC04F4EAF24C7C4671207 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ComboBox.h; path = "../../Source/model/Component Types/jucer_ComboBox.h"; sourceTree = SOURCE_ROOT; }; | |||
| C6263909812DBE995167932B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_GenericComponent.h; path = "../../Source/model/Component Types/jucer_GenericComponent.h"; sourceTree = SOURCE_ROOT; }; | |||
| 6B5504F7274B11DFAD3B2E26 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_GroupComponent.h; path = "../../Source/model/Component Types/jucer_GroupComponent.h"; sourceTree = SOURCE_ROOT; }; | |||
| 133385B65A02DF50291B222F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_JucerComponent.h; path = "../../Source/model/Component Types/jucer_JucerComponent.h"; sourceTree = SOURCE_ROOT; }; | |||
| C64A89EA5C3F0A701F9EBA79 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Label.h; path = "../../Source/model/Component Types/jucer_Label.h"; sourceTree = SOURCE_ROOT; }; | |||
| 40716207B98461E05DC46F14 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Slider.h; path = "../../Source/model/Component Types/jucer_Slider.h"; sourceTree = SOURCE_ROOT; }; | |||
| 4A22DE9DF590115F174CA70E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TabbedComponent.h; path = "../../Source/model/Component Types/jucer_TabbedComponent.h"; sourceTree = SOURCE_ROOT; }; | |||
| E18C99BDD4EF3DFD767F3770 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TextButton.h; path = "../../Source/model/Component Types/jucer_TextButton.h"; sourceTree = SOURCE_ROOT; }; | |||
| 1BBF86F1D833DAD4A1503C82 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TextEditor.h; path = "../../Source/model/Component Types/jucer_TextEditor.h"; sourceTree = SOURCE_ROOT; }; | |||
| A6FAA90B494DCD7CA5911196 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ToggleButton.h; path = "../../Source/model/Component Types/jucer_ToggleButton.h"; sourceTree = SOURCE_ROOT; }; | |||
| 03AD2BF6C80C6AF47BBDB7E9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Viewport.h; path = "../../Source/model/Component Types/jucer_Viewport.h"; sourceTree = SOURCE_ROOT; }; | |||
| 2D6D6985B452EA0B67A18914 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ComponentDocument.cpp; path = ../../Source/model/jucer_ComponentDocument.cpp; sourceTree = SOURCE_ROOT; }; | |||
| E6CC3A04349F6B227FDAB26F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ComponentDocument.h; path = ../../Source/model/jucer_ComponentDocument.h; sourceTree = SOURCE_ROOT; }; | |||
| 45C80436FD5A8438D0E6BE17 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Coordinate.cpp; path = ../../Source/model/jucer_Coordinate.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -141,8 +154,20 @@ | |||
| 268B4FFB1C675B679138545F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode3.mm; path = ../../JuceLibraryCode/JuceLibraryCode3.mm; sourceTree = SOURCE_ROOT; }; | |||
| 60A217F62952DE8A752BD79F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode4.mm; path = ../../JuceLibraryCode/JuceLibraryCode4.mm; sourceTree = SOURCE_ROOT; }; | |||
| D3D6EC2C17524688F2E803EB = { isa = PBXGroup; children = ( | |||
| 82A1EC47692975C7031B3973, | |||
| 4F23FF649E7BA3A0F737E3BE, | |||
| 6FD54B7E8992FD692BAA0DC6, | |||
| 926FC04F4EAF24C7C4671207, | |||
| C6263909812DBE995167932B, | |||
| 6B5504F7274B11DFAD3B2E26, | |||
| 133385B65A02DF50291B222F, | |||
| C64A89EA5C3F0A701F9EBA79, | |||
| 40716207B98461E05DC46F14, | |||
| 4A22DE9DF590115F174CA70E, | |||
| E18C99BDD4EF3DFD767F3770, | |||
| 1BBF86F1D833DAD4A1503C82, | |||
| A6FAA90B494DCD7CA5911196, | |||
| E18C99BDD4EF3DFD767F3770 ); name = "Component Types"; sourceTree = "<group>"; }; | |||
| 03AD2BF6C80C6AF47BBDB7E9 ); name = "Component Types"; sourceTree = "<group>"; }; | |||
| BF6238C9155879B9A9C47213 = { isa = PBXGroup; children = ( | |||
| D3D6EC2C17524688F2E803EB, | |||
| 2D6D6985B452EA0B67A18914, | |||
| @@ -323,6 +348,7 @@ | |||
| 673FACB8969ADED17ACEFF7C ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; | |||
| 87CCE4CB1FAB40B6F21DEACE = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; | |||
| 5362E03ADF975A126C1F2F7B = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( | |||
| 52D75B8B0F52DD4F37A4B1C0, | |||
| CD4226951C3F7FE19CF8A7CE, | |||
| 1DF9688E29753A0459E6C32A, | |||
| 1174D3512AF8207950094C56, | |||
| @@ -134,8 +134,20 @@ | |||
| <Filter Name="The Jucer"> | |||
| <Filter Name="Model"> | |||
| <Filter Name="Component Types"> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ToggleButton.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComponentTypeManager.cpp"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComponentTypeManager.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComponentTypes.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComboBox.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_GenericComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_GroupComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_JucerComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_Label.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_Slider.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_TabbedComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_TextButton.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_TextEditor.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ToggleButton.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_Viewport.h"/> | |||
| </Filter> | |||
| <File RelativePath="..\..\Source\model\jucer_ComponentDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\model\jucer_ComponentDocument.h"/> | |||
| @@ -134,8 +134,20 @@ | |||
| <Filter Name="The Jucer"> | |||
| <Filter Name="Model"> | |||
| <Filter Name="Component Types"> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ToggleButton.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComponentTypeManager.cpp"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComponentTypeManager.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComponentTypes.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ComboBox.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_GenericComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_GroupComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_JucerComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_Label.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_Slider.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_TabbedComponent.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_TextButton.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_TextEditor.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_ToggleButton.h"/> | |||
| <File RelativePath="..\..\Source\model\Component Types\jucer_Viewport.h"/> | |||
| </Filter> | |||
| <File RelativePath="..\..\Source\model\jucer_ComponentDocument.cpp"/> | |||
| <File RelativePath="..\..\Source\model\jucer_ComponentDocument.h"/> | |||
| @@ -28,10 +28,34 @@ | |||
| <MAINGROUP name="The Jucer" id="NhrJq66R"> | |||
| <GROUP id="EmpOiUg6" name="Model"> | |||
| <GROUP id="7IAOlGP0H" name="Component Types"> | |||
| <FILE id="EOwXntvc" name="jucer_ToggleButton.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_ToggleButton.h"/> | |||
| <FILE id="dhwVkC0LQ" name="jucer_ComponentTypeManager.cpp" compile="1" | |||
| resource="0" file="Source/model/Component Types/jucer_ComponentTypeManager.cpp"/> | |||
| <FILE id="rSuW9uAYG" name="jucer_ComponentTypeManager.h" compile="0" | |||
| resource="0" file="Source/model/Component Types/jucer_ComponentTypeManager.h"/> | |||
| <FILE id="X1JJNqL9d" name="jucer_ComponentTypes.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_ComponentTypes.h"/> | |||
| <FILE id="0kW52xWY0" name="jucer_ComboBox.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_ComboBox.h"/> | |||
| <FILE id="IgbLRcOlP" name="jucer_GenericComponent.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_GenericComponent.h"/> | |||
| <FILE id="dO5A44NtK" name="jucer_GroupComponent.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_GroupComponent.h"/> | |||
| <FILE id="5ooKsX1Oy" name="jucer_JucerComponent.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_JucerComponent.h"/> | |||
| <FILE id="J1dHwtOob" name="jucer_Label.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_Label.h"/> | |||
| <FILE id="K2f4ViI8f" name="jucer_Slider.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_Slider.h"/> | |||
| <FILE id="Yq56kjAjr" name="jucer_TabbedComponent.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_TabbedComponent.h"/> | |||
| <FILE id="lO2yuwiGR" name="jucer_TextButton.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_TextButton.h"/> | |||
| <FILE id="9kpY6Dy8E" name="jucer_TextEditor.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_TextEditor.h"/> | |||
| <FILE id="EOwXntvc" name="jucer_ToggleButton.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_ToggleButton.h"/> | |||
| <FILE id="dnB5Epzjx" name="jucer_Viewport.h" compile="0" resource="0" | |||
| file="Source/model/Component Types/jucer_Viewport.h"/> | |||
| </GROUP> | |||
| <FILE id="e6IQOUwvq" name="jucer_ComponentDocument.cpp" compile="1" | |||
| resource="0" file="Source/model/jucer_ComponentDocument.cpp"/> | |||
| @@ -0,0 +1,56 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (ComboBoxHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class ComboBoxHandler : public ComponentTypeHelper<ComboBox> | |||
| { | |||
| public: | |||
| ComboBoxHandler() : ComponentTypeHelper<ComboBox> ("ComboBox", "COMBOBOX", "comboBox") {} | |||
| ~ComboBoxHandler() {} | |||
| Component* createComponent() { return new ComboBox (String::empty); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 180, 24); } | |||
| void update (ComponentDocument& document, ComboBox* comp, const ValueTree& state) | |||
| { | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,336 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "jucer_ComponentTypeManager.h" | |||
| #include "jucer_ComponentTypes.h" | |||
| //============================================================================== | |||
| class ComponentBoundsEditor : public PropertyComponent, | |||
| public ButtonListener, | |||
| public Value::Listener | |||
| { | |||
| public: | |||
| enum Type | |||
| { | |||
| left, top, right, bottom | |||
| }; | |||
| //============================================================================== | |||
| ComponentBoundsEditor (ComponentDocument& document_, const String& name, Type type_, | |||
| const ValueTree& compState_, const Value& boundsValue_) | |||
| : PropertyComponent (name, 40), document (document_), type (type_), | |||
| compState (compState_), boundsValue (boundsValue_) | |||
| { | |||
| addAndMakeVisible (label = new Label (String::empty, String::empty)); | |||
| label->setEditable (true, true, false); | |||
| label->setColour (Label::backgroundColourId, Colours::white); | |||
| label->setColour (Label::outlineColourId, findColour (ComboBox::outlineColourId)); | |||
| label->getTextValue().referTo (Value (new BoundsCoordValueSource (boundsValue, type))); | |||
| addAndMakeVisible (proportionButton = new TextButton ("%")); | |||
| proportionButton->addButtonListener (this); | |||
| addAndMakeVisible (anchorButton1 = new TextButton (String::empty)); | |||
| anchorButton1->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom); | |||
| anchorButton1->setTriggeredOnMouseDown (true); | |||
| anchorButton1->addButtonListener (this); | |||
| addAndMakeVisible (anchorButton2 = new TextButton (String::empty)); | |||
| anchorButton2->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom); | |||
| anchorButton2->setTriggeredOnMouseDown (true); | |||
| anchorButton2->addButtonListener (this); | |||
| boundsValue.addListener (this); | |||
| valueChanged (boundsValue); | |||
| } | |||
| ~ComponentBoundsEditor() | |||
| { | |||
| boundsValue.removeListener (this); | |||
| deleteAllChildren(); | |||
| } | |||
| void resized() | |||
| { | |||
| const Rectangle<int> r (getLookAndFeel().getPropertyComponentContentPosition (*this)); | |||
| label->setBounds (r.getX(), r.getY(), r.getWidth() / 2, r.getHeight() / 2); | |||
| proportionButton->setBounds (r.getX() + r.getWidth() / 2, r.getY(), | |||
| r.getWidth() / 2, r.getHeight() / 2); | |||
| if (anchorButton2->isVisible()) | |||
| { | |||
| anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2); | |||
| anchorButton2->setBounds (r.getX() + r.getWidth() / 2, r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2); | |||
| } | |||
| else | |||
| { | |||
| anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth(), r.getHeight() / 2); | |||
| } | |||
| } | |||
| void refresh() | |||
| { | |||
| } | |||
| void buttonClicked (Button* button) | |||
| { | |||
| RectangleCoordinates r (boundsValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (compState)); | |||
| if (button == proportionButton) | |||
| { | |||
| coord.toggleProportionality (*markers); | |||
| boundsValue = r.toString(); | |||
| } | |||
| else if (button == anchorButton1) | |||
| { | |||
| const String marker (pickMarker (anchorButton1, coord.getAnchor1())); | |||
| if (marker.isNotEmpty()) | |||
| { | |||
| coord.changeAnchor1 (marker, *markers); | |||
| boundsValue = r.toString(); | |||
| } | |||
| } | |||
| else if (button == anchorButton2) | |||
| { | |||
| const String marker (pickMarker (anchorButton2, coord.getAnchor2())); | |||
| if (marker.isNotEmpty()) | |||
| { | |||
| coord.changeAnchor2 (marker, *markers); | |||
| boundsValue = r.toString(); | |||
| } | |||
| } | |||
| } | |||
| void valueChanged (Value&) | |||
| { | |||
| RectangleCoordinates r (boundsValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| anchorButton1->setButtonText (coord.getAnchor1()); | |||
| anchorButton2->setVisible (coord.isProportional()); | |||
| anchorButton2->setButtonText (coord.getAnchor2()); | |||
| resized(); | |||
| } | |||
| //============================================================================== | |||
| class BoundsCoordValueSource : public Value::ValueSource, | |||
| public Value::Listener | |||
| { | |||
| public: | |||
| BoundsCoordValueSource (const Value& sourceValue_, Type type_) | |||
| : sourceValue (sourceValue_), type (type_) | |||
| { | |||
| sourceValue.addListener (this); | |||
| } | |||
| ~BoundsCoordValueSource() {} | |||
| const var getValue() const | |||
| { | |||
| RectangleCoordinates r (sourceValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| if (coord.isProportional()) | |||
| return String (coord.getEditableValue()) + "%"; | |||
| return coord.getEditableValue(); | |||
| } | |||
| void setValue (const var& newValue) | |||
| { | |||
| RectangleCoordinates r (sourceValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| coord.setEditableValue ((double) newValue); | |||
| const String newVal (r.toString()); | |||
| if (sourceValue != newVal) | |||
| sourceValue = newVal; | |||
| } | |||
| void valueChanged (Value&) | |||
| { | |||
| sendChangeMessage (true); | |||
| } | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| Value sourceValue; | |||
| Type type; | |||
| Coordinate& getCoord (RectangleCoordinates& r) const | |||
| { | |||
| return getCoordForType (type, r); | |||
| } | |||
| BoundsCoordValueSource (const BoundsCoordValueSource&); | |||
| const BoundsCoordValueSource& operator= (const BoundsCoordValueSource&); | |||
| }; | |||
| static Coordinate& getCoordForType (const Type type, RectangleCoordinates& r) | |||
| { | |||
| switch (type) | |||
| { | |||
| case left: return r.left; | |||
| case right: return r.right; | |||
| case top: return r.top; | |||
| case bottom: return r.bottom; | |||
| default: jassertfalse; break; | |||
| } | |||
| return r.left; | |||
| } | |||
| const String pickMarker (Component* button, const String& currentMarker) | |||
| { | |||
| const StringArray markers (document.getComponentMarkers (type == left || type == right)); | |||
| PopupMenu m; | |||
| for (int i = 0; i < markers.size(); ++i) | |||
| m.addItem (i + 1, markers[i], true, currentMarker == markers[i]); | |||
| const int r = m.showAt (button); | |||
| if (r > 0) | |||
| return markers [r - 1]; | |||
| return String::empty; | |||
| } | |||
| private: | |||
| ComponentDocument& document; | |||
| Type type; | |||
| ValueTree compState; | |||
| Value boundsValue; | |||
| Label* label; | |||
| TextButton* proportionButton; | |||
| TextButton* anchorButton1; | |||
| TextButton* anchorButton2; | |||
| Coordinate& getCoord (RectangleCoordinates& r) | |||
| { | |||
| return getCoordForType (type, r); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| ComponentTypeHandler::ComponentTypeHandler (const String& name_, const String& xmlTag_, | |||
| const String& memberNameRoot_) | |||
| : name (name_), xmlTag (xmlTag_), | |||
| memberNameRoot (memberNameRoot_) | |||
| { | |||
| } | |||
| ComponentTypeHandler::~ComponentTypeHandler() | |||
| { | |||
| } | |||
| Value ComponentTypeHandler::getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const | |||
| { | |||
| return state.getPropertyAsValue (name, document.getUndoManager()); | |||
| } | |||
| void ComponentTypeHandler::updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state) | |||
| { | |||
| RectangleCoordinates pos (state [ComponentDocument::compBoundsProperty].toString()); | |||
| ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (state)); | |||
| comp->setBounds (pos.resolve (*markers)); | |||
| comp->setName (state [ComponentDocument::compNameProperty]); | |||
| } | |||
| void ComponentTypeHandler::initialiseNewItem (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| state.setProperty (ComponentDocument::compNameProperty, String::empty, 0); | |||
| state.setProperty (ComponentDocument::memberNameProperty, document.getNonExistentMemberName (getMemberNameRoot()), 0); | |||
| const Rectangle<int> bounds (getDefaultSize().withPosition (Point<int> (Random::getSystemRandom().nextInt (100) + 100, | |||
| Random::getSystemRandom().nextInt (100) + 100))); | |||
| state.setProperty (ComponentDocument::compBoundsProperty, RectangleCoordinates (bounds).toString(), 0); | |||
| } | |||
| void ComponentTypeHandler::createPropertyEditors (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| props.add (new ComponentBoundsEditor (document, "Left", ComponentBoundsEditor::left, state, getValue (ComponentDocument::compBoundsProperty, state, document))); | |||
| props.add (new ComponentBoundsEditor (document, "Right", ComponentBoundsEditor::right, state, getValue (ComponentDocument::compBoundsProperty, state, document))); | |||
| props.add (new ComponentBoundsEditor (document, "Top", ComponentBoundsEditor::top, state, getValue (ComponentDocument::compBoundsProperty, state, document))); | |||
| props.add (new ComponentBoundsEditor (document, "Bottom", ComponentBoundsEditor::bottom, state, getValue (ComponentDocument::compBoundsProperty, state, document))); | |||
| } | |||
| //============================================================================== | |||
| ComponentTypeManager::ComponentTypeManager() | |||
| { | |||
| #define ADD_TO_LIST(HandlerType) handlers.add (new HandlerType()); | |||
| #include "jucer_ComponentTypes.h" | |||
| #undef ADD_TO_LIST | |||
| } | |||
| ComponentTypeManager::~ComponentTypeManager() | |||
| { | |||
| } | |||
| Component* ComponentTypeManager::createFromStoredType (ComponentDocument& document, const ValueTree& value) | |||
| { | |||
| ComponentTypeHandler* handler = getHandlerFor (value.getType()); | |||
| if (handler == 0) | |||
| return 0; | |||
| Component* c = handler->createComponent(); | |||
| if (c != 0) | |||
| handler->updateComponent (document, c, value); | |||
| return c; | |||
| } | |||
| ComponentTypeHandler* ComponentTypeManager::getHandlerFor (const String& type) | |||
| { | |||
| for (int i = handlers.size(); --i >= 0;) | |||
| if (handlers.getUnchecked(i)->getXmlTag() == type) | |||
| return handlers.getUnchecked(i); | |||
| return 0; | |||
| } | |||
| const StringArray ComponentTypeManager::getTypeNames() const | |||
| { | |||
| StringArray s; | |||
| for (int i = 0; i < handlers.size(); ++i) | |||
| s.add (handlers.getUnchecked(i)->getName()); | |||
| return s; | |||
| } | |||
| juce_ImplementSingleton_SingleThreaded (ComponentTypeManager); | |||
| @@ -0,0 +1,127 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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_COMPONENTTYPEMANAGER_H_734EBF1__ | |||
| #define __JUCER_COMPONENTTYPEMANAGER_H_734EBF1__ | |||
| #include "../../jucer_Headers.h" | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class ComponentTypeHandler | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentTypeHandler (const String& name_, const String& xmlTag_, const String& memberNameRoot_); | |||
| virtual ~ComponentTypeHandler(); | |||
| const String& getName() const { return name; } | |||
| const String& getXmlTag() const { return xmlTag; } | |||
| const String& getMemberNameRoot() const { return memberNameRoot; } | |||
| virtual Component* createComponent() = 0; | |||
| virtual const Rectangle<int> getDefaultSize() = 0; | |||
| virtual void updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state); | |||
| virtual void initialiseNewItem (ComponentDocument& document, ValueTree& state); | |||
| virtual void createPropertyEditors (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props); | |||
| Value getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const; | |||
| //============================================================================== | |||
| protected: | |||
| const String name, xmlTag, memberNameRoot; | |||
| }; | |||
| //============================================================================== | |||
| class ComponentTypeManager : public DeletedAtShutdown | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentTypeManager(); | |||
| ~ComponentTypeManager(); | |||
| juce_DeclareSingleton_SingleThreaded_Minimal (ComponentTypeManager); | |||
| //============================================================================== | |||
| Component* createFromStoredType (ComponentDocument& document, const ValueTree& value); | |||
| int getNumHandlers() const { return handlers.size(); } | |||
| ComponentTypeHandler* getHandler (const int index) const { return handlers[index]; } | |||
| ComponentTypeHandler* getHandlerFor (const String& type); | |||
| const StringArray getTypeNames() const; | |||
| private: | |||
| //============================================================================== | |||
| OwnedArray <ComponentTypeHandler> handlers; | |||
| }; | |||
| //============================================================================== | |||
| template <class ComponentClass> | |||
| class ComponentTypeHelper : public ComponentTypeHandler | |||
| { | |||
| public: | |||
| ComponentTypeHelper (const String& name_, const String& xmlTag_, const String& memberNameRoot_) | |||
| : ComponentTypeHandler (name_, xmlTag_, memberNameRoot_) | |||
| { | |||
| } | |||
| virtual void update (ComponentDocument& document, ComponentClass* comp, const ValueTree& state) = 0; | |||
| void updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state) | |||
| { | |||
| ComponentTypeHandler::updateComponent (document, comp, state); | |||
| ComponentClass* const c = dynamic_cast <ComponentClass*> (comp); | |||
| jassert (c != 0); | |||
| update (document, c, state); | |||
| } | |||
| virtual void initialiseNew (ComponentDocument& document, ValueTree& state) = 0; | |||
| void initialiseNewItem (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| ComponentTypeHandler::initialiseNewItem (document, state); | |||
| initialiseNew (document, state); | |||
| } | |||
| virtual void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) = 0; | |||
| void createPropertyEditors (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| ComponentTypeHandler::createPropertyEditors (document, state, props); | |||
| createProperties (document, state, props); | |||
| } | |||
| }; | |||
| #endif // __JUCER_COMPONENTTYPEMANAGER_H_734EBF1__ | |||
| @@ -0,0 +1,36 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "jucer_TextButton.h" | |||
| #include "jucer_ToggleButton.h" | |||
| #include "jucer_TextEditor.h" | |||
| #include "jucer_Viewport.h" | |||
| #include "jucer_ComboBox.h" | |||
| #include "jucer_GroupComponent.h" | |||
| #include "jucer_JucerComponent.h" | |||
| #include "jucer_GenericComponent.h" | |||
| #include "jucer_Label.h" | |||
| #include "jucer_Slider.h" | |||
| #include "jucer_TabbedComponent.h" | |||
| @@ -0,0 +1,75 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (GenericComponentHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class GenericComponentHandler : public ComponentTypeHelper<Component> | |||
| { | |||
| public: | |||
| GenericComponentHandler() : ComponentTypeHelper<Component> ("Generic Component", "COMPONENT", "component") {} | |||
| ~GenericComponentHandler() {} | |||
| //============================================================================== | |||
| class PlaceholderComp : public Component | |||
| { | |||
| public: | |||
| PlaceholderComp() | |||
| { | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.setColour (Colours::grey); | |||
| g.drawRect (getLocalBounds()); | |||
| g.drawLine (0.5f, 0.5f, getWidth() - 0.5f, getHeight() - 0.5f); | |||
| g.drawLine (0.5f, getHeight() - 0.5f, getWidth() - 0.5f, 0.5f); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| Component* createComponent() { return new PlaceholderComp(); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 180, 24); } | |||
| void update (ComponentDocument& document, Component* comp, const ValueTree& state) | |||
| { | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,56 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (GroupComponentHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class GroupComponentHandler : public ComponentTypeHelper<GroupComponent> | |||
| { | |||
| public: | |||
| GroupComponentHandler() : ComponentTypeHelper<GroupComponent> ("GroupComponent", "GROUPCOMPONENT", "group") {} | |||
| ~GroupComponentHandler() {} | |||
| Component* createComponent() { return new GroupComponent (String::empty, String::empty); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 200, 200); } | |||
| void update (ComponentDocument& document, GroupComponent* comp, const ValueTree& state) | |||
| { | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,74 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (JucerComponentHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class JucerComponent : public Component | |||
| { | |||
| public: | |||
| JucerComponent() | |||
| { | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.setColour (Colours::grey); | |||
| g.drawRect (getLocalBounds()); | |||
| g.drawLine (0.5f, 0.5f, getWidth() - 0.5f, getHeight() - 0.5f); | |||
| g.drawLine (0.5f, getHeight() - 0.5f, getWidth() - 0.5f, 0.5f); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| class JucerComponentHandler : public ComponentTypeHelper<JucerComponent> | |||
| { | |||
| public: | |||
| JucerComponentHandler() : ComponentTypeHelper<JucerComponent> ("Jucer Component", "JUCERCOMPONENT", "jucerComp") {} | |||
| ~JucerComponentHandler() {} | |||
| //============================================================================== | |||
| Component* createComponent() { return new JucerComponent(); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 150, 150); } | |||
| void update (ComponentDocument& document, JucerComponent* comp, const ValueTree& state) | |||
| { | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,60 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (LabelHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class LabelHandler : public ComponentTypeHelper<Label> | |||
| { | |||
| public: | |||
| LabelHandler() : ComponentTypeHelper<Label> ("Label", "LABEL", "label") {} | |||
| ~LabelHandler() {} | |||
| Component* createComponent() { return new Label (String::empty, String::empty); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 180, 24); } | |||
| void update (ComponentDocument& document, Label* comp, const ValueTree& state) | |||
| { | |||
| comp->setText (state ["text"].toString(), false); | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| state.setProperty ("text", "New Label", 0); | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| props.add (new TextPropertyComponent (getValue ("text", state, document), "Text", 16384, true)); | |||
| props.getLast()->setTooltip ("The label's text."); | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,56 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (SliderHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class SliderHandler : public ComponentTypeHelper<Slider> | |||
| { | |||
| public: | |||
| SliderHandler() : ComponentTypeHelper<Slider> ("Slider", "SLIDER", "slider") {} | |||
| ~SliderHandler() {} | |||
| Component* createComponent() { return new Slider (String::empty); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 200, 24); } | |||
| void update (ComponentDocument& document, Slider* comp, const ValueTree& state) | |||
| { | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,56 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (TabbedComponentHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class TabbedComponentHandler : public ComponentTypeHelper<TabbedComponent> | |||
| { | |||
| public: | |||
| TabbedComponentHandler() : ComponentTypeHelper<TabbedComponent> ("TabbedComponent", "TABBEDCOMPONENT", "tabbedComponent") {} | |||
| ~TabbedComponentHandler() {} | |||
| Component* createComponent() { return new TabbedComponent (TabbedButtonBar::TabsAtTop); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 300, 200); } | |||
| void update (ComponentDocument& document, TabbedComponent* comp, const ValueTree& state) | |||
| { | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -23,38 +23,37 @@ | |||
| ============================================================================== | |||
| */ | |||
| #include "../jucer_ComponentDocument.h" | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (TextButtonHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class TextButtonHandler : public ComponentTypeHandler | |||
| class TextButtonHandler : public ComponentTypeHelper<TextButton> | |||
| { | |||
| public: | |||
| TextButtonHandler() : ComponentTypeHandler ("TextButton", "TEXTBUTTON", "textButton") {} | |||
| TextButtonHandler() : ComponentTypeHelper<TextButton> ("TextButton", "TEXTBUTTON", "textButton") {} | |||
| ~TextButtonHandler() {} | |||
| Component* createComponent() { return new TextButton (String::empty); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 150, 24); } | |||
| void updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state) | |||
| void update (ComponentDocument& document, TextButton* comp, const ValueTree& state) | |||
| { | |||
| TextButton* tb = dynamic_cast <TextButton*> (comp); | |||
| jassert (tb != 0); | |||
| ComponentTypeHandler::updateComponent (document, comp, state); | |||
| tb->setButtonText (state ["text"].toString()); | |||
| comp->setButtonText (state ["text"].toString()); | |||
| } | |||
| void initialiseNewItem (ComponentDocument& document, ValueTree& state) | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| ComponentTypeHandler::initialiseNewItem (document, state); | |||
| state.setProperty ("text", "New Toggle Button", 0); | |||
| state.setProperty ("text", "New Button", 0); | |||
| } | |||
| void createPropertyEditors (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| ComponentTypeHandler::createPropertyEditors (document, state, props); | |||
| props.add (new TextPropertyComponent (getValue ("text", state, document), "Button Text", 1024, false)); | |||
| props.getLast()->setTooltip ("The button's text."); | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,60 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (TextEditorHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class TextEditorHandler : public ComponentTypeHelper<TextEditor> | |||
| { | |||
| public: | |||
| TextEditorHandler() : ComponentTypeHelper<TextEditor> ("TextEditor", "TEXTEDITOR", "textEditor") {} | |||
| ~TextEditorHandler() {} | |||
| Component* createComponent() { return new TextEditor(); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 180, 24); } | |||
| void update (ComponentDocument& document, TextEditor* comp, const ValueTree& state) | |||
| { | |||
| comp->setText (state ["text"].toString()); | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| state.setProperty ("text", "Text Editor Content", 0); | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| props.add (new TextPropertyComponent (getValue ("text", state, document), "Text", 16384, true)); | |||
| props.getLast()->setTooltip ("The editor's initial content."); | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -23,38 +23,38 @@ | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (ToggleButtonHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class ToggleButtonHandler : public ComponentTypeHandler | |||
| class ToggleButtonHandler : public ComponentTypeHelper<ToggleButton> | |||
| { | |||
| public: | |||
| ToggleButtonHandler() : ComponentTypeHandler ("ToggleButton", "TOGGLEBUTTON", "toggleButton") {} | |||
| ToggleButtonHandler() : ComponentTypeHelper<ToggleButton> ("ToggleButton", "TOGGLEBUTTON", "toggleButton") {} | |||
| ~ToggleButtonHandler() {} | |||
| Component* createComponent() { return new ToggleButton (String::empty); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 180, 24); } | |||
| void updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state) | |||
| void update (ComponentDocument& document, ToggleButton* comp, const ValueTree& state) | |||
| { | |||
| ToggleButton* tb = dynamic_cast <ToggleButton*> (comp); | |||
| jassert (tb != 0); | |||
| ComponentTypeHandler::updateComponent (document, comp, state); | |||
| tb->setButtonText (state ["text"].toString()); | |||
| comp->setButtonText (state ["text"].toString()); | |||
| } | |||
| void initialiseNewItem (ComponentDocument& document, ValueTree& state) | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| ComponentTypeHandler::initialiseNewItem (document, state); | |||
| state.setProperty ("text", "New Toggle Button", 0); | |||
| } | |||
| void createPropertyEditors (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| ComponentTypeHandler::createPropertyEditors (document, state, props); | |||
| props.add (new TextPropertyComponent (getValue ("text", state, document), "Button Text", 1024, false)); | |||
| props.getLast()->setTooltip ("The button's text."); | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -0,0 +1,56 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-9 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. | |||
| ============================================================================== | |||
| */ | |||
| #ifdef ADD_TO_LIST | |||
| ADD_TO_LIST (ViewportHandler); | |||
| #else | |||
| #include "../jucer_ComponentDocument.h" | |||
| //============================================================================== | |||
| class ViewportHandler : public ComponentTypeHelper<Viewport> | |||
| { | |||
| public: | |||
| ViewportHandler() : ComponentTypeHelper<Viewport> ("Viewport", "VIEWPORT", "viewport") {} | |||
| ~ViewportHandler() {} | |||
| Component* createComponent() { return new Viewport(); } | |||
| const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 300, 200); } | |||
| void update (ComponentDocument& document, Viewport* comp, const ValueTree& state) | |||
| { | |||
| } | |||
| void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| } | |||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| } | |||
| }; | |||
| #endif | |||
| @@ -24,342 +24,20 @@ | |||
| */ | |||
| #include "jucer_ComponentDocument.h" | |||
| #include "Component Types/jucer_TextButton.h" | |||
| #include "Component Types/jucer_ToggleButton.h" | |||
| #include "Component Types/jucer_ComponentTypeManager.h" | |||
| //============================================================================== | |||
| static const char* const componentDocumentTag = "COMPONENT"; | |||
| static const char* const componentGroupTag = "COMPONENTS"; | |||
| static const char* const idProperty = "id"; | |||
| static const char* const compBoundsProperty = "position"; | |||
| static const char* const memberNameProperty = "memberName"; | |||
| static const char* const compNameProperty = "name"; | |||
| static const char* const metadataTagStart = "JUCER_" "COMPONENT_METADATA_START"; // written like this to avoid thinking this file is a component! | |||
| static const char* const metadataTagEnd = "JUCER_" "COMPONENT_METADATA_END"; | |||
| //============================================================================== | |||
| class ComponentBoundsEditor : public PropertyComponent, | |||
| public ButtonListener, | |||
| public Value::Listener | |||
| { | |||
| public: | |||
| enum Type | |||
| { | |||
| left, top, right, bottom | |||
| }; | |||
| //============================================================================== | |||
| ComponentBoundsEditor (ComponentDocument& document_, const String& name, Type type_, | |||
| const ValueTree& compState_, const Value& boundsValue_) | |||
| : PropertyComponent (name, 40), document (document_), type (type_), | |||
| compState (compState_), boundsValue (boundsValue_) | |||
| { | |||
| addAndMakeVisible (label = new Label (String::empty, String::empty)); | |||
| label->setEditable (true, true, false); | |||
| label->setColour (Label::backgroundColourId, Colours::white); | |||
| label->setColour (Label::outlineColourId, findColour (ComboBox::outlineColourId)); | |||
| label->getTextValue().referTo (Value (new BoundsCoordValueSource (boundsValue, type))); | |||
| addAndMakeVisible (proportionButton = new TextButton ("%")); | |||
| proportionButton->addButtonListener (this); | |||
| addAndMakeVisible (anchorButton1 = new TextButton (String::empty)); | |||
| anchorButton1->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom); | |||
| anchorButton1->setTriggeredOnMouseDown (true); | |||
| anchorButton1->addButtonListener (this); | |||
| addAndMakeVisible (anchorButton2 = new TextButton (String::empty)); | |||
| anchorButton2->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom); | |||
| anchorButton2->setTriggeredOnMouseDown (true); | |||
| anchorButton2->addButtonListener (this); | |||
| boundsValue.addListener (this); | |||
| valueChanged (boundsValue); | |||
| } | |||
| ~ComponentBoundsEditor() | |||
| { | |||
| boundsValue.removeListener (this); | |||
| deleteAllChildren(); | |||
| } | |||
| void resized() | |||
| { | |||
| const Rectangle<int> r (getLookAndFeel().getPropertyComponentContentPosition (*this)); | |||
| label->setBounds (r.getX(), r.getY(), r.getWidth() / 2, r.getHeight() / 2); | |||
| proportionButton->setBounds (r.getX() + r.getWidth() / 2, r.getY(), | |||
| r.getWidth() / 2, r.getHeight() / 2); | |||
| if (anchorButton2->isVisible()) | |||
| { | |||
| anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2); | |||
| anchorButton2->setBounds (r.getX() + r.getWidth() / 2, r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2); | |||
| } | |||
| else | |||
| { | |||
| anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth(), r.getHeight() / 2); | |||
| } | |||
| } | |||
| void refresh() | |||
| { | |||
| } | |||
| void buttonClicked (Button* button) | |||
| { | |||
| RectangleCoordinates r (boundsValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (compState)); | |||
| if (button == proportionButton) | |||
| { | |||
| coord.toggleProportionality (*markers); | |||
| boundsValue = r.toString(); | |||
| } | |||
| else if (button == anchorButton1) | |||
| { | |||
| const String marker (pickMarker (anchorButton1, coord.getAnchor1())); | |||
| if (marker.isNotEmpty()) | |||
| { | |||
| coord.changeAnchor1 (marker, *markers); | |||
| boundsValue = r.toString(); | |||
| } | |||
| } | |||
| else if (button == anchorButton2) | |||
| { | |||
| const String marker (pickMarker (anchorButton2, coord.getAnchor2())); | |||
| if (marker.isNotEmpty()) | |||
| { | |||
| coord.changeAnchor2 (marker, *markers); | |||
| boundsValue = r.toString(); | |||
| } | |||
| } | |||
| } | |||
| void valueChanged (Value&) | |||
| { | |||
| RectangleCoordinates r (boundsValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| anchorButton1->setButtonText (coord.getAnchor1()); | |||
| anchorButton2->setVisible (coord.isProportional()); | |||
| anchorButton2->setButtonText (coord.getAnchor2()); | |||
| resized(); | |||
| } | |||
| //============================================================================== | |||
| class BoundsCoordValueSource : public Value::ValueSource, | |||
| public Value::Listener | |||
| { | |||
| public: | |||
| BoundsCoordValueSource (const Value& sourceValue_, Type type_) | |||
| : sourceValue (sourceValue_), type (type_) | |||
| { | |||
| sourceValue.addListener (this); | |||
| } | |||
| ~BoundsCoordValueSource() {} | |||
| const var getValue() const | |||
| { | |||
| RectangleCoordinates r (sourceValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| if (coord.isProportional()) | |||
| return String (coord.getEditableValue()) + "%"; | |||
| return coord.getEditableValue(); | |||
| } | |||
| void setValue (const var& newValue) | |||
| { | |||
| RectangleCoordinates r (sourceValue.toString()); | |||
| Coordinate& coord = getCoord (r); | |||
| coord.setEditableValue ((double) newValue); | |||
| const String newVal (r.toString()); | |||
| if (sourceValue != newVal) | |||
| sourceValue = newVal; | |||
| } | |||
| void valueChanged (Value&) | |||
| { | |||
| sendChangeMessage (true); | |||
| } | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| Value sourceValue; | |||
| Type type; | |||
| Coordinate& getCoord (RectangleCoordinates& r) const | |||
| { | |||
| return getCoordForType (type, r); | |||
| } | |||
| BoundsCoordValueSource (const BoundsCoordValueSource&); | |||
| const BoundsCoordValueSource& operator= (const BoundsCoordValueSource&); | |||
| }; | |||
| static Coordinate& getCoordForType (const Type type, RectangleCoordinates& r) | |||
| { | |||
| switch (type) | |||
| { | |||
| case left: return r.left; | |||
| case right: return r.right; | |||
| case top: return r.top; | |||
| case bottom: return r.bottom; | |||
| default: jassertfalse; break; | |||
| } | |||
| return r.left; | |||
| } | |||
| const String pickMarker (Component* button, const String& currentMarker) | |||
| { | |||
| const StringArray markers (document.getComponentMarkers (type == left || type == right)); | |||
| PopupMenu m; | |||
| for (int i = 0; i < markers.size(); ++i) | |||
| m.addItem (i + 1, markers[i], true, currentMarker == markers[i]); | |||
| const int r = m.showAt (button); | |||
| if (r > 0) | |||
| return markers [r - 1]; | |||
| return String::empty; | |||
| } | |||
| private: | |||
| ComponentDocument& document; | |||
| Type type; | |||
| ValueTree compState; | |||
| Value boundsValue; | |||
| Label* label; | |||
| TextButton* proportionButton; | |||
| TextButton* anchorButton1; | |||
| TextButton* anchorButton2; | |||
| Coordinate& getCoord (RectangleCoordinates& r) | |||
| { | |||
| return getCoordForType (type, r); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| ComponentTypeHandler::ComponentTypeHandler (const String& name_, const String& xmlTag_, | |||
| const String& memberNameRoot_) | |||
| : name (name_), xmlTag (xmlTag_), | |||
| memberNameRoot (memberNameRoot_) | |||
| { | |||
| } | |||
| ComponentTypeHandler::~ComponentTypeHandler() | |||
| { | |||
| } | |||
| Value ComponentTypeHandler::getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const | |||
| { | |||
| return state.getPropertyAsValue (name, document.getUndoManager()); | |||
| } | |||
| void ComponentTypeHandler::updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state) | |||
| { | |||
| RectangleCoordinates pos (state [compBoundsProperty].toString()); | |||
| ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (state)); | |||
| comp->setBounds (pos.resolve (*markers)); | |||
| comp->setName (state [compNameProperty]); | |||
| } | |||
| void ComponentTypeHandler::initialiseNewItem (ComponentDocument& document, ValueTree& state) | |||
| { | |||
| state.setProperty (compNameProperty, String::empty, 0); | |||
| state.setProperty (memberNameProperty, document.getNonExistentMemberName (getMemberNameRoot()), 0); | |||
| const Rectangle<int> bounds (getDefaultSize().withPosition (Point<int> (Random::getSystemRandom().nextInt (100) + 100, | |||
| Random::getSystemRandom().nextInt (100) + 100))); | |||
| state.setProperty (compBoundsProperty, RectangleCoordinates (bounds).toString(), 0); | |||
| } | |||
| void ComponentTypeHandler::createPropertyEditors (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
| { | |||
| props.add (new ComponentBoundsEditor (document, "Left", ComponentBoundsEditor::left, state, getValue (compBoundsProperty, state, document))); | |||
| props.add (new ComponentBoundsEditor (document, "Right", ComponentBoundsEditor::right, state, getValue (compBoundsProperty, state, document))); | |||
| props.add (new ComponentBoundsEditor (document, "Top", ComponentBoundsEditor::top, state, getValue (compBoundsProperty, state, document))); | |||
| props.add (new ComponentBoundsEditor (document, "Bottom", ComponentBoundsEditor::bottom, state, getValue (compBoundsProperty, state, document))); | |||
| } | |||
| //============================================================================== | |||
| class ComponentTypeManager : public DeletedAtShutdown | |||
| { | |||
| public: | |||
| ComponentTypeManager() | |||
| { | |||
| handlers.add (new TextButtonHandler()); | |||
| handlers.add (new ToggleButtonHandler()); | |||
| } | |||
| ~ComponentTypeManager() | |||
| { | |||
| } | |||
| juce_DeclareSingleton_SingleThreaded_Minimal (ComponentTypeManager); | |||
| Component* createFromStoredType (ComponentDocument& document, const ValueTree& value) | |||
| { | |||
| ComponentTypeHandler* handler = getHandlerFor (value.getType()); | |||
| if (handler == 0) | |||
| return 0; | |||
| Component* c = handler->createComponent(); | |||
| if (c != 0) | |||
| handler->updateComponent (document, c, value); | |||
| return c; | |||
| } | |||
| ComponentTypeHandler* getHandlerFor (const String& type) | |||
| { | |||
| for (int i = handlers.size(); --i >= 0;) | |||
| if (handlers.getUnchecked(i)->getXmlTag() == type) | |||
| return handlers.getUnchecked(i); | |||
| return 0; | |||
| } | |||
| const StringArray getTypeNames() const | |||
| { | |||
| StringArray s; | |||
| for (int i = 0; i < handlers.size(); ++i) | |||
| s.add (handlers.getUnchecked(i)->getName()); | |||
| return s; | |||
| } | |||
| int getNumHandlers() const { return handlers.size(); } | |||
| ComponentTypeHandler* getHandler (const int index) const { return handlers[index]; } | |||
| private: | |||
| OwnedArray <ComponentTypeHandler> handlers; | |||
| }; | |||
| juce_ImplementSingleton_SingleThreaded (ComponentTypeManager); | |||
| const char* const ComponentDocument::idProperty = "id"; | |||
| const char* const ComponentDocument::compBoundsProperty = "position"; | |||
| const char* const ComponentDocument::memberNameProperty = "memberName"; | |||
| const char* const ComponentDocument::compNameProperty = "name"; | |||
| //============================================================================== | |||
| @@ -624,10 +302,10 @@ public: | |||
| const Coordinate findMarker (const String& name, bool isHorizontal) | |||
| { | |||
| if (name == "left") return RectangleCoordinates (state [compBoundsProperty]).left; | |||
| else if (name == "right") return RectangleCoordinates (state [compBoundsProperty]).right; | |||
| else if (name == "top") return RectangleCoordinates (state [compBoundsProperty]).top; | |||
| else if (name == "bottom") return RectangleCoordinates (state [compBoundsProperty]).bottom; | |||
| if (name == "left") return RectangleCoordinates (state [ComponentDocument::compBoundsProperty]).left; | |||
| else if (name == "right") return RectangleCoordinates (state [ComponentDocument::compBoundsProperty]).right; | |||
| else if (name == "top") return RectangleCoordinates (state [ComponentDocument::compBoundsProperty]).top; | |||
| else if (name == "bottom") return RectangleCoordinates (state [ComponentDocument::compBoundsProperty]).bottom; | |||
| else if (name == Coordinate::parentRightMarkerName) return Coordinate (parentWidth, isHorizontal); | |||
| else if (name == Coordinate::parentBottomMarkerName) return Coordinate (parentHeight, isHorizontal); | |||
| @@ -89,6 +89,11 @@ public: | |||
| void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged); | |||
| void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged); | |||
| static const char* const idProperty; | |||
| static const char* const compBoundsProperty; | |||
| static const char* const memberNameProperty; | |||
| static const char* const compNameProperty; | |||
| private: | |||
| Project* project; | |||
| File cppFile; | |||
| @@ -105,31 +110,5 @@ private: | |||
| }; | |||
| //============================================================================== | |||
| class ComponentTypeHandler | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| ComponentTypeHandler (const String& name_, const String& xmlTag_, const String& memberNameRoot_); | |||
| virtual ~ComponentTypeHandler(); | |||
| const String& getName() const { return name; } | |||
| const String& getXmlTag() const { return xmlTag; } | |||
| const String& getMemberNameRoot() const { return memberNameRoot; } | |||
| virtual Component* createComponent() = 0; | |||
| virtual const Rectangle<int> getDefaultSize() = 0; | |||
| virtual void updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state); | |||
| virtual void initialiseNewItem (ComponentDocument& document, ValueTree& state); | |||
| virtual void createPropertyEditors (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props); | |||
| Value getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const; | |||
| //============================================================================== | |||
| protected: | |||
| const String name, xmlTag, memberNameRoot; | |||
| }; | |||
| #endif // __JUCER_COMPONENTDOCUMENT_JUCEHEADER__ | |||
| @@ -27,16 +27,19 @@ | |||
| #include "jucer_ComponentEditor.h" | |||
| const float snapDistance = 8.0f; | |||
| static const Colour resizableBorderColour (0x7066aaff); | |||
| static const Colour alignmentMarkerColour (0x77ff0000); | |||
| //============================================================================== | |||
| class SizeGuideComponent : public Component, | |||
| public ComponentListener | |||
| { | |||
| public: | |||
| enum Type | |||
| { | |||
| left, right, top, bottom | |||
| }; | |||
| enum Type { left, right, top, bottom }; | |||
| //============================================================================== | |||
| SizeGuideComponent (ComponentDocument& document_, const ValueTree& state_, Component* component_, | |||
| Component& parentForOverlays, Type type_) | |||
| : document (document_), state (state_), component (component_), type (type_), | |||
| @@ -55,6 +58,39 @@ public: | |||
| component->removeComponentListener (this); | |||
| } | |||
| //============================================================================== | |||
| void paint (Graphics& g) | |||
| { | |||
| const float dashes[] = { 4.0f, 3.0f }; | |||
| g.setColour (resizableBorderColour); | |||
| g.drawDashedLine (lineEnd1.getX() + 0.5f, lineEnd1.getY() + 0.5f, | |||
| lineEnd2.getX() + 0.5f, lineEnd2.getY() + 0.5f, | |||
| dashes, 2, 1.0f); | |||
| g.setFont (font); | |||
| g.setColour (Colours::white); | |||
| for (int y = -1; y <= 1; ++y) | |||
| for (int x = -1; x <= 1; ++x) | |||
| g.drawText (getName(), textArea.getX() + x, textArea.getY() + y, textArea.getWidth(), textArea.getHeight(), Justification::centred, 1); | |||
| g.setColour (Colours::black); | |||
| g.drawText (getName(), textArea.getX(), textArea.getY(), textArea.getWidth(), textArea.getHeight(), Justification::centred, 1); | |||
| } | |||
| void componentMovedOrResized (Component&, bool, bool) | |||
| { | |||
| updatePosition(); | |||
| } | |||
| void componentBeingDeleted (Component&) | |||
| { | |||
| setVisible (false); | |||
| component = 0; | |||
| } | |||
| //============================================================================== | |||
| void updatePosition() | |||
| { | |||
| RectangleCoordinates coords (document.getCoordsFor (state)); | |||
| @@ -118,37 +154,6 @@ public: | |||
| repaint(); | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| const float dashes[] = { 4.0f, 3.0f }; | |||
| g.setColour (Colours::grey.withAlpha (0.4f)); | |||
| g.drawDashedLine (lineEnd1.getX() + 0.5f, lineEnd1.getY() + 0.5f, | |||
| lineEnd2.getX() + 0.5f, lineEnd2.getY() + 0.5f, | |||
| dashes, 2, 1.0f); | |||
| g.setFont (font); | |||
| g.setColour (Colours::white); | |||
| for (int y = -1; y <= 1; ++y) | |||
| for (int x = -1; x <= 1; ++x) | |||
| g.drawText (getName(), textArea.getX() + x, textArea.getY() + y, textArea.getWidth(), textArea.getHeight(), Justification::centred, 1); | |||
| g.setColour (Colours::black); | |||
| g.drawText (getName(), textArea.getX(), textArea.getY(), textArea.getWidth(), textArea.getHeight(), Justification::centred, 1); | |||
| } | |||
| void componentMovedOrResized (Component&, bool, bool) | |||
| { | |||
| updatePosition(); | |||
| } | |||
| void componentBeingDeleted (Component&) | |||
| { | |||
| setVisible (false); | |||
| component = 0; | |||
| } | |||
| private: | |||
| ComponentDocument& document; | |||
| ValueTree state; | |||
| @@ -165,6 +170,7 @@ class ComponentEditor::Canvas : public Component, | |||
| public Timer | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| Canvas (ComponentEditor& editor_) | |||
| : editor (editor_), border (14), resizerThickness (4), | |||
| dragStartWidth (0), dragStartHeight (0) | |||
| @@ -187,6 +193,21 @@ public: | |||
| deleteAllChildren(); | |||
| } | |||
| //============================================================================== | |||
| ComponentEditor& getEditor() { return editor; } | |||
| ComponentDocument& getDocument() { return editor.getDocument(); } | |||
| ComponentDocument::SelectedItems& getSelection() { return selection; } | |||
| Component* getComponentHolder() const { return componentHolder; } | |||
| void timerCallback() | |||
| { | |||
| stopTimer(); | |||
| if (! Component::isMouseButtonDownAnywhere()) | |||
| getDocument().beginNewTransaction(); | |||
| } | |||
| //============================================================================== | |||
| void paint (Graphics& g) | |||
| { | |||
| g.fillAll (Colours::white); | |||
| @@ -211,7 +232,6 @@ public: | |||
| void drawXAxis (Graphics& g, const Rectangle<int>& r) | |||
| { | |||
| TickIterator ticks (0, r.getWidth(), 1.0, 10, 50); | |||
| float pos, tickLength; | |||
| String label; | |||
| @@ -228,7 +248,6 @@ public: | |||
| void drawYAxis (Graphics& g, const Rectangle<int>& r) | |||
| { | |||
| TickIterator ticks (0, r.getHeight(), 1.0, 10, 80); | |||
| float pos, tickLength; | |||
| String label; | |||
| @@ -243,6 +262,12 @@ public: | |||
| } | |||
| } | |||
| const Rectangle<int> getContentArea() const | |||
| { | |||
| return border.subtractedFrom (getLocalBounds()); | |||
| } | |||
| //============================================================================== | |||
| void resized() | |||
| { | |||
| componentHolder->setBounds (getContentArea()); | |||
| @@ -250,29 +275,6 @@ public: | |||
| updateComponents(); | |||
| } | |||
| void zoom (float newScale, const Point<int>& centre) | |||
| { | |||
| } | |||
| ComponentEditor& getEditor() { return editor; } | |||
| ComponentDocument& getDocument() { return editor.getDocument(); } | |||
| ComponentDocument::SelectedItems& getSelection() { return selection; } | |||
| Component* findComponentFor (const ValueTree& state) | |||
| { | |||
| ComponentDocument& doc = getDocument(); | |||
| for (int i = componentHolder->getNumChildComponents(); --i >= 0;) | |||
| { | |||
| Component* c = componentHolder->getChildComponent (i); | |||
| if (doc.isStateForComponent (state, c)) | |||
| return c; | |||
| } | |||
| return 0; | |||
| } | |||
| void updateComponents() | |||
| { | |||
| ComponentDocument& doc = getDocument(); | |||
| @@ -295,7 +297,7 @@ public: | |||
| for (i = 0; i < num; ++i) | |||
| { | |||
| const ValueTree v (doc.getComponent (i)); | |||
| Component* c = findComponentFor (v); | |||
| Component* c = getComponentForState (v); | |||
| if (c == 0) | |||
| { | |||
| @@ -323,23 +325,7 @@ public: | |||
| { | |||
| } | |||
| Component* getComponentHolder() const { return componentHolder; } | |||
| const Array<Component*> getSelectedComps() const | |||
| { | |||
| Array<Component*> comps; | |||
| for (int i = 0; i < selection.getNumSelected(); ++i) | |||
| { | |||
| Component* c = getComponentForUID (selection.getSelectedItem (i)); | |||
| jassert (c != 0); | |||
| if (c != 0) | |||
| comps.add (c); | |||
| } | |||
| return comps; | |||
| } | |||
| //============================================================================== | |||
| void getSelectedItemProperties (Array <PropertyComponent*>& props) | |||
| { | |||
| //xxx needs to handle multiple selections.. | |||
| @@ -347,18 +333,12 @@ public: | |||
| if (selection.getNumSelected() == 1) | |||
| { | |||
| Component* c = getComponentForUID (selection.getSelectedItem (0)); | |||
| jassert (c != 0); | |||
| getDocument().getComponentProperties (props, c); | |||
| } | |||
| } | |||
| void timerCallback() | |||
| { | |||
| stopTimer(); | |||
| if (! Component::isMouseButtonDownAnywhere()) | |||
| getDocument().beginNewTransaction(); | |||
| } | |||
| //============================================================================== | |||
| void mouseMove (const MouseEvent& e) | |||
| { | |||
| updateDragZone (e.getPosition()); | |||
| @@ -409,30 +389,19 @@ public: | |||
| public: | |||
| DragOperation (Canvas& canvas_, | |||
| const Array<Component*>& items, | |||
| const Array<Component*>& itemsToSnapTo, | |||
| const MouseEvent& e, | |||
| const ResizableBorderComponent::Zone& zone_) | |||
| : canvas (canvas_), | |||
| zone (zone_) | |||
| { | |||
| for (int i = 0; i < items.size(); ++i) | |||
| int i; | |||
| for (i = 0; i < items.size(); ++i) | |||
| { | |||
| Component* comp = items.getUnchecked(i); | |||
| jassert (comp != 0); | |||
| const ValueTree v (getDocument().getComponentState (comp)); | |||
| jassert (items.getUnchecked(i) != 0); | |||
| const ValueTree v (getDocument().getComponentState (items.getUnchecked(i))); | |||
| draggedComponents.add (v); | |||
| Rectangle<int> pos; | |||
| { | |||
| RectangleCoordinates relativePos (getDocument().getCoordsFor (v)); | |||
| ScopedPointer<Coordinate::MarkerResolver> markers (getDocument().createMarkerResolver (v)); | |||
| pos = relativePos.resolve (*markers); | |||
| originalPositions.add (pos); | |||
| } | |||
| const Rectangle<float> floatPos ((float) pos.getX(), (float) pos.getY(), | |||
| (float) pos.getWidth(), (float) pos.getHeight()); | |||
| const Rectangle<float> floatPos (getComponentPosition (v)); | |||
| if (zone.isDraggingWholeObject() || zone.isDraggingLeftEdge()) | |||
| verticalSnapPositions.add (SnapLine (floatPos.getX(), floatPos.getY(), floatPos.getBottom())); | |||
| @@ -453,17 +422,51 @@ public: | |||
| horizontalSnapPositions.add (SnapLine (floatPos.getBottom(), floatPos.getX(), floatPos.getRight())); | |||
| } | |||
| verticalSnapTargets.add (SnapLine (0, 0, 10000.0f)); | |||
| verticalSnapTargets.add (SnapLine (getDocument().getCanvasWidth().getValue(), 0, 10000.0f)); | |||
| if (isDraggingLeftRight()) | |||
| { | |||
| verticalSnapTargets.add (SnapLine (0, 0, 10000.0f)); | |||
| verticalSnapTargets.add (SnapLine (getDocument().getCanvasWidth().getValue(), 0, 10000.0f)); | |||
| if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge())) | |||
| verticalSnapTargets.add (SnapLine ((float) getDocument().getCanvasWidth().getValue() / 2.0f, 0, 10000.0f)); | |||
| if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge())) | |||
| verticalSnapTargets.add (SnapLine ((float) getDocument().getCanvasWidth().getValue() / 2.0f, 0, 10000.0f)); | |||
| } | |||
| if (isDraggingUpDown()) | |||
| { | |||
| horizontalSnapTargets.add (SnapLine (0, 0, 10000.0f)); | |||
| horizontalSnapTargets.add (SnapLine (getDocument().getCanvasHeight().getValue(), 0, 10000.0f)); | |||
| if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge())) | |||
| horizontalSnapTargets.add (SnapLine ((float) getDocument().getCanvasHeight().getValue() / 2.0f, 0, 10000.0f)); | |||
| } | |||
| horizontalSnapTargets.add (SnapLine (0, 0, 10000.0f)); | |||
| horizontalSnapTargets.add (SnapLine (getDocument().getCanvasHeight().getValue(), 0, 10000.0f)); | |||
| for (i = 0; i < itemsToSnapTo.size(); ++i) | |||
| { | |||
| jassert (itemsToSnapTo.getUnchecked(i) != 0); | |||
| const ValueTree v (getDocument().getComponentState (itemsToSnapTo.getUnchecked(i))); | |||
| const Rectangle<float> floatPos (getComponentPosition (v)); | |||
| if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge())) | |||
| horizontalSnapTargets.add (SnapLine ((float) getDocument().getCanvasHeight().getValue() / 2.0f, 0, 10000.0f)); | |||
| if (isDraggingLeftRight()) | |||
| { | |||
| verticalSnapTargets.add (SnapLine (floatPos.getX(), floatPos.getY(), floatPos.getBottom())); | |||
| verticalSnapTargets.add (SnapLine (floatPos.getRight(), floatPos.getY(), floatPos.getBottom())); | |||
| } | |||
| if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge())) | |||
| verticalSnapTargets.add (SnapLine (floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom())); | |||
| if (isDraggingUpDown()) | |||
| { | |||
| horizontalSnapTargets.add (SnapLine (floatPos.getY(), floatPos.getX(), floatPos.getRight())); | |||
| horizontalSnapTargets.add (SnapLine (floatPos.getBottom(), floatPos.getX(), floatPos.getRight())); | |||
| } | |||
| if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge())) | |||
| horizontalSnapTargets.add (SnapLine (floatPos.getCentreY(), floatPos.getX(), floatPos.getRight())); | |||
| } | |||
| mergeSnapLines (verticalSnapTargets); | |||
| mergeSnapLines (horizontalSnapTargets); | |||
| getDocument().beginNewTransaction(); | |||
| } | |||
| @@ -473,69 +476,65 @@ public: | |||
| getDocument().beginNewTransaction(); | |||
| } | |||
| //============================================================================== | |||
| struct SnapLine | |||
| { | |||
| SnapLine (float position_, float start_, float end_) | |||
| SnapLine() : position (0), start (0), end (0) {} | |||
| SnapLine (const float position_, const float start_, const float end_) | |||
| : position (position_), start (start_), end (end_) | |||
| {} | |||
| float position, start, end; | |||
| }; | |||
| class SnapGuideComponent : public Component | |||
| //============================================================================== | |||
| class AlignmentHintComponent : public Component | |||
| { | |||
| public: | |||
| SnapGuideComponent (const SnapLine& line_, bool isVertical_, Component* parent) | |||
| AlignmentHintComponent (const SnapLine& line_, bool isVertical_, Component* parent) | |||
| : line (line_), isVertical (isVertical_) | |||
| { | |||
| const int extraEndLength = 5; | |||
| setAlwaysOnTop (true); | |||
| if (isVertical) | |||
| setBounds (roundToInt (line.position), roundToInt (line.start), 1, roundToInt (line.end - line.start)); | |||
| setBounds (roundToInt (line.position), roundToInt (line.start) - extraEndLength, 1, roundToInt (line.end - line.start) + extraEndLength * 2); | |||
| else | |||
| setBounds (roundToInt (line.start), roundToInt (line.position), roundToInt (line.end - line.start), 1); | |||
| setBounds (roundToInt (line.start) - extraEndLength, roundToInt (line.position), roundToInt (line.end - line.start) + extraEndLength * 2, 1); | |||
| parent->addAndMakeVisible (this); | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.fillAll (Colours::blue.withAlpha (0.3f)); | |||
| g.fillAll (alignmentMarkerColour); | |||
| } | |||
| private: | |||
| const SnapLine line; | |||
| const bool isVertical; | |||
| SnapGuideComponent (const SnapGuideComponent&); | |||
| SnapGuideComponent& operator= (const SnapGuideComponent&); | |||
| AlignmentHintComponent (const AlignmentHintComponent&); | |||
| AlignmentHintComponent& operator= (const AlignmentHintComponent&); | |||
| }; | |||
| //============================================================================== | |||
| void drag (const MouseEvent& e) | |||
| { | |||
| const float snapThreshold = 8.0f; | |||
| getDocument().getUndoManager()->undoCurrentTransactionOnly(); | |||
| Point<int> distance (e.getOffsetFromDragStart()); | |||
| snapGuides.clear(); | |||
| if (! isDraggingLeftRight()) | |||
| distance = Point<int> (0, distance.getY()); | |||
| SnapLine snap (0, 0, 0); | |||
| const float snapX = findBestSnapDistance (verticalSnapTargets, getVerticalSnapPositions (distance), snap); | |||
| if (fabsf (snapX) < snapThreshold) | |||
| { | |||
| distance = Point<int> (distance.getX() + snapX, distance.getY()); | |||
| if (! isDraggingUpDown()) | |||
| distance = Point<int> (distance.getX(), 0); | |||
| if (snap.position != 0) | |||
| snapGuides.add (new SnapGuideComponent (snap, true, canvas.overlay)); | |||
| } | |||
| const float snapY = findBestSnapDistance (horizontalSnapTargets, getHorizontalSnapPositions (distance), snap); | |||
| if (fabsf (snapY) < snapThreshold) | |||
| { | |||
| distance = Point<int> (distance.getX(), distance.getY() + snapY); | |||
| snapGuides.clear(); | |||
| if (snap.position != 0) | |||
| snapGuides.add (new SnapGuideComponent (snap, false, canvas.overlay)); | |||
| } | |||
| performSnap (verticalSnapTargets, getVerticalSnapPositions (distance), true, distance); | |||
| performSnap (horizontalSnapTargets, getHorizontalSnapPositions (distance), false, distance); | |||
| for (int n = 50;;) | |||
| { | |||
| @@ -570,71 +569,131 @@ public: | |||
| return getDocument().setCoordsFor (v, pr); | |||
| } | |||
| const Array<SnapLine> getVerticalSnapPositions (const Point<int>& distance) const | |||
| //============================================================================== | |||
| private: | |||
| Canvas& canvas; | |||
| Array <ValueTree> draggedComponents; | |||
| Array <Rectangle<int> > originalPositions; | |||
| Array <SnapLine> verticalSnapPositions, horizontalSnapPositions; | |||
| Array <SnapLine> verticalSnapTargets, horizontalSnapTargets; | |||
| const ResizableBorderComponent::Zone zone; | |||
| OwnedArray<Component> snapGuides; | |||
| ComponentDocument& getDocument() throw() { return canvas.getDocument(); } | |||
| const Rectangle<float> getComponentPosition (const ValueTree& state) | |||
| { | |||
| Array<SnapLine> p (verticalSnapPositions); | |||
| for (int i = p.size(); --i >= 0;) | |||
| p.getReference(i).position += distance.getX(); | |||
| RectangleCoordinates relativePos (getDocument().getCoordsFor (state)); | |||
| ScopedPointer<Coordinate::MarkerResolver> markers (getDocument().createMarkerResolver (state)); | |||
| const Rectangle<int> intPos (relativePos.resolve (*markers)); | |||
| originalPositions.add (intPos); | |||
| return p; | |||
| return Rectangle<float> ((float) intPos.getX(), (float) intPos.getY(), | |||
| (float) intPos.getWidth(), (float) intPos.getHeight()); | |||
| } | |||
| const Array<SnapLine> getHorizontalSnapPositions (const Point<int>& distance) const | |||
| static void mergeSnapLines (Array <SnapLine>& lines) | |||
| { | |||
| Array<SnapLine> p (horizontalSnapPositions); | |||
| for (int i = p.size(); --i >= 0;) | |||
| p.getReference(i).position += distance.getY(); | |||
| for (int i = lines.size(); --i > 0;) | |||
| { | |||
| SnapLine& s1 = lines.getReference(i); | |||
| return p; | |||
| for (int j = i; --j >= 0;) | |||
| { | |||
| SnapLine& s2 = lines.getReference(j); | |||
| if (s1.position == s2.position) | |||
| { | |||
| s2.start = jmin (s1.start, s2.start); | |||
| s2.end = jmax (s1.end, s2.end); | |||
| lines.remove (i); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| static float findBestSnapDistance (const Array<SnapLine>& targets, const Array<SnapLine>& sources, SnapLine& line) | |||
| void performSnap (const Array<SnapLine>& targets, const Array<SnapLine>& sources, bool isVertical, Point<int>& distance) | |||
| { | |||
| if (targets.size() == 0 || sources.size() == 0) | |||
| return 0.0f; | |||
| return; | |||
| float best = 1.0e10f; | |||
| float best = std::numeric_limits<float>::max(); | |||
| float absBest = fabsf (best); | |||
| line = SnapLine (1.0e10f, 0, 0); | |||
| Array <SnapLine> lines; | |||
| for (int i = 0; i < targets.size(); ++i) | |||
| { | |||
| const SnapLine& target = targets.getReference(i); | |||
| for (int j = 0; j < sources.size(); ++j) | |||
| { | |||
| SnapLine& target = targets.getReference(i); | |||
| SnapLine& source = sources.getReference(j); | |||
| const SnapLine& source = sources.getReference(j); | |||
| const float diff = target.position - source.position; | |||
| const float absDiff = fabsf (diff); | |||
| if (absDiff < absBest) | |||
| if (absDiff <= absBest) | |||
| { | |||
| line = SnapLine (target.position, jmin (target.start, source.start), jmax (target.end, source.end)); | |||
| if (absDiff < absBest) | |||
| lines.clearQuick(); | |||
| lines.add (SnapLine (target.position, jmin (target.start, source.start), jmax (target.end, source.end))); | |||
| best = diff; | |||
| absBest = absDiff; | |||
| } | |||
| } | |||
| } | |||
| jassert (absBest < 1.0e10f); | |||
| return best; | |||
| jassert (absBest < std::numeric_limits<float>::max()); | |||
| if (absBest < snapDistance) | |||
| { | |||
| distance += isVertical ? Point<int> (roundToInt (best), 0) : Point<int> (0, roundToInt (best)); | |||
| for (int i = lines.size(); --i >= 0;) | |||
| if (lines.getReference(i).position != 0) | |||
| snapGuides.add (new AlignmentHintComponent (lines.getReference(i), isVertical, canvas.overlay)); | |||
| } | |||
| } | |||
| private: | |||
| Canvas& canvas; | |||
| Array <ValueTree> draggedComponents; | |||
| Array <Rectangle<int> > originalPositions; | |||
| const Array<SnapLine> getVerticalSnapPositions (const Point<int>& distance) const | |||
| { | |||
| Array<SnapLine> p (verticalSnapPositions); | |||
| for (int i = p.size(); --i >= 0;) | |||
| { | |||
| SnapLine& s = p.getReference(i); | |||
| s.position += distance.getX(); | |||
| s.start += distance.getY(); | |||
| s.end += distance.getY(); | |||
| } | |||
| Array <SnapLine> verticalSnapPositions, horizontalSnapPositions; | |||
| Array <SnapLine> verticalSnapTargets, horizontalSnapTargets; | |||
| const ResizableBorderComponent::Zone zone; | |||
| OwnedArray<Component> snapGuides; | |||
| return p; | |||
| } | |||
| ComponentDocument& getDocument() throw() { return canvas.getDocument(); } | |||
| const Array<SnapLine> getHorizontalSnapPositions (const Point<int>& distance) const | |||
| { | |||
| Array<SnapLine> p (horizontalSnapPositions); | |||
| for (int i = p.size(); --i >= 0;) | |||
| { | |||
| SnapLine& s = p.getReference(i); | |||
| s.position += distance.getY(); | |||
| s.start += distance.getX(); | |||
| s.end += distance.getX(); | |||
| } | |||
| return p; | |||
| } | |||
| bool isDraggingLeftRight() const { return zone.isDraggingWholeObject() || zone.isDraggingLeftEdge() || zone.isDraggingRightEdge(); } | |||
| bool isDraggingUpDown() const { return zone.isDraggingWholeObject() || zone.isDraggingTopEdge() || zone.isDraggingBottomEdge(); } | |||
| DragOperation (const DragOperation&); | |||
| DragOperation& operator= (const DragOperation&); | |||
| }; | |||
| //============================================================================== | |||
| void beginDrag (const MouseEvent& e, const ResizableBorderComponent::Zone& zone) | |||
| { | |||
| dragger = new DragOperation (*this, getSelectedComps(), e, zone); | |||
| dragger = new DragOperation (*this, getSelectedComps(), getUnselectedComps(), e, zone); | |||
| } | |||
| void continueDrag (const MouseEvent& e) | |||
| @@ -660,11 +719,6 @@ private: | |||
| ResizableBorderComponent::Zone dragZone; | |||
| int dragStartWidth, dragStartHeight; | |||
| const Rectangle<int> getContentArea() const | |||
| { | |||
| return border.subtractedFrom (getLocalBounds()); | |||
| } | |||
| //============================================================================== | |||
| class ComponentResizeFrame : public Component, | |||
| public ComponentListener | |||
| @@ -688,26 +742,13 @@ private: | |||
| void paint (Graphics& g) | |||
| { | |||
| g.setColour (Colours::red.withAlpha (0.1f)); | |||
| g.setColour (resizableBorderColour); | |||
| g.drawRect (0, 0, getWidth(), getHeight(), borderThickness); | |||
| } | |||
| void mouseEnter (const MouseEvent& e) | |||
| { | |||
| //repaint(); | |||
| updateDragZone (e.getPosition()); | |||
| } | |||
| void mouseExit (const MouseEvent& e) | |||
| { | |||
| //repaint(); | |||
| updateDragZone (e.getPosition()); | |||
| } | |||
| void mouseMove (const MouseEvent& e) | |||
| { | |||
| updateDragZone (e.getPosition()); | |||
| } | |||
| void mouseEnter (const MouseEvent& e) { updateDragZone (e.getPosition()); } | |||
| void mouseExit (const MouseEvent& e) { updateDragZone (e.getPosition()); } | |||
| void mouseMove (const MouseEvent& e) { updateDragZone (e.getPosition()); } | |||
| void mouseDown (const MouseEvent& e) | |||
| { | |||
| @@ -815,6 +856,7 @@ private: | |||
| deleteAllChildren(); | |||
| } | |||
| //============================================================================== | |||
| void mouseDown (const MouseEvent& e) | |||
| { | |||
| lasso = 0; | |||
| @@ -831,10 +873,17 @@ private: | |||
| } | |||
| else | |||
| { | |||
| Component* underMouse = canvas.getComponentHolder()->getComponentAt (e.x, e.y); | |||
| Component* underMouse = 0; | |||
| if (underMouse == canvas.getComponentHolder()) | |||
| underMouse = 0; | |||
| for (int i = canvas.getComponentHolder()->getNumChildComponents(); --i >= 0;) | |||
| { | |||
| Component* const c = canvas.getComponentHolder()->getChildComponent(i); | |||
| if (c->getBounds().contains (e.getPosition())) | |||
| { | |||
| underMouse = c; | |||
| break; | |||
| } | |||
| } | |||
| if (underMouse == 0 || e.mods.isAltDown()) | |||
| { | |||
| @@ -906,7 +955,7 @@ private: | |||
| } | |||
| } | |||
| ComponentDocument::SelectedItems& getLassoSelection() { return canvas.getSelection(); } | |||
| ComponentDocument::SelectedItems& getLassoSelection() { return canvas.getSelection(); } | |||
| void changeListenerCallback (void*) | |||
| { | |||
| @@ -939,6 +988,7 @@ private: | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| Canvas& canvas; | |||
| ScopedPointer <LassoComponent <ComponentDocument::SelectedItems::ItemType> > lasso; | |||
| bool mouseDownResult, isDraggingClickedComp; | |||
| @@ -979,6 +1029,7 @@ private: | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| Component* componentHolder; | |||
| OverlayComponent* overlay; | |||
| ComponentDocument::SelectedItems selection; | |||
| @@ -991,6 +1042,47 @@ private: | |||
| return 0; | |||
| } | |||
| Component* getComponentForState (const ValueTree& state) | |||
| { | |||
| ComponentDocument& doc = getDocument(); | |||
| for (int i = componentHolder->getNumChildComponents(); --i >= 0;) | |||
| { | |||
| Component* const c = componentHolder->getChildComponent (i); | |||
| if (doc.isStateForComponent (state, c)) | |||
| return c; | |||
| } | |||
| return 0; | |||
| } | |||
| const Array<Component*> getSelectedComps() const | |||
| { | |||
| Array<Component*> comps; | |||
| for (int i = 0; i < selection.getNumSelected(); ++i) | |||
| { | |||
| Component* c = getComponentForUID (selection.getSelectedItem (i)); | |||
| jassert (c != 0); | |||
| if (c != 0) | |||
| comps.add (c); | |||
| } | |||
| return comps; | |||
| } | |||
| const Array<Component*> getUnselectedComps() const | |||
| { | |||
| Array<Component*> comps; | |||
| for (int i = componentHolder->getNumChildComponents(); --i >= 0;) | |||
| if (! selection.isSelected (componentHolder->getChildComponent(i)->getComponentUID())) | |||
| comps.add (componentHolder->getChildComponent(i)); | |||
| return comps; | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| @@ -29647,7 +29647,7 @@ END_JUCE_NAMESPACE | |||
| /*** Start of inlined file: juce_AudioUnitPluginFormat.mm ***/ | |||
| #if JUCE_PLUGINHOST_AU && (! (defined (LINUX) || defined (_WIN32))) | |||
| #if JUCE_PLUGINHOST_AU && ! (JUCE_LINUX || JUCE_WINDOWS) | |||
| #include <AudioUnit/AudioUnit.h> | |||
| #include <AudioUnit/AUCocoaUIView.h> | |||
| @@ -31105,7 +31105,7 @@ END_JUCE_NAMESPACE | |||
| /*** Start of inlined file: juce_VSTPluginFormat.cpp ***/ | |||
| #if JUCE_PLUGINHOST_VST | |||
| #if (defined (_WIN32) || defined (_WIN64)) | |||
| #if JUCE_WINDOWS | |||
| #undef _WIN32_WINNT | |||
| #define _WIN32_WINNT 0x500 | |||
| #undef STRICT | |||
| @@ -31113,7 +31113,7 @@ END_JUCE_NAMESPACE | |||
| #include <windows.h> | |||
| #include <float.h> | |||
| #pragma warning (disable : 4312 4355) | |||
| #elif defined (LINUX) || defined (__linux__) | |||
| #elif JUCE_LINUX | |||
| #include <float.h> | |||
| #include <sys/time.h> | |||
| #include <X11/Xlib.h> | |||
| @@ -26,7 +26,7 @@ | |||
| #include "../../../core/juce_TargetPlatform.h" | |||
| #include "../../../../juce_Config.h" | |||
| #if JUCE_PLUGINHOST_AU && (! (defined (LINUX) || defined (_WIN32))) | |||
| #if JUCE_PLUGINHOST_AU && ! (JUCE_LINUX || JUCE_WINDOWS) | |||
| #include <AudioUnit/AudioUnit.h> | |||
| #include <AudioUnit/AUCocoaUIView.h> | |||
| @@ -47,6 +47,7 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "../../../events/juce_Timer.h" | |||
| #include "../../../core/juce_PlatformUtilities.h" | |||
| #include "../../../gui/components/layout/juce_ComponentMovementWatcher.h" | |||
| #include "../../../gui/components/windows/juce_ComponentPeer.h" | |||
| #include "../../../gui/components/special/juce_NSViewComponent.h" | |||
| #if JUCE_MAC && JUCE_SUPPORT_CARBON | |||
| #include "../../../native/mac/juce_mac_CarbonViewWrapperComponent.h" | |||
| @@ -28,7 +28,7 @@ | |||
| #if JUCE_PLUGINHOST_VST | |||
| #if (defined (_WIN32) || defined (_WIN64)) | |||
| #if JUCE_WINDOWS | |||
| #undef _WIN32_WINNT | |||
| #define _WIN32_WINNT 0x500 | |||
| #undef STRICT | |||
| @@ -36,7 +36,7 @@ | |||
| #include <windows.h> | |||
| #include <float.h> | |||
| #pragma warning (disable : 4312 4355) | |||
| #elif defined (LINUX) || defined (__linux__) | |||
| #elif JUCE_LINUX | |||
| #include <float.h> | |||
| #include <sys/time.h> | |||
| #include <X11/Xlib.h> | |||
| @@ -72,6 +72,7 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "../../../events/juce_AsyncUpdater.h" | |||
| #include "../../../events/juce_MessageManager.h" | |||
| #include "../../../gui/components/layout/juce_ComponentMovementWatcher.h" | |||
| #include "../../../gui/components/windows/juce_ComponentPeer.h" | |||
| #include "../../../application/juce_Application.h" | |||
| #include "../../../core/juce_PlatformUtilities.h" | |||