Browse Source

Refactoring of Drawables with new class MarkerList. Fixes for Mac 10.5 SDK includes and minor change to win32 repainting.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
faecab9ca5
26 changed files with 1265 additions and 687 deletions
  1. +6
    -0
      Builds/Linux/Makefile
  2. +6
    -0
      Builds/MacOSX/Juce.xcodeproj/project.pbxproj
  3. +2
    -0
      Builds/VisualStudio2005/Juce.vcproj
  4. +2
    -0
      Builds/VisualStudio2008/Juce.vcproj
  5. +2
    -0
      Builds/VisualStudio2008_DLL/Juce.vcproj
  6. +2
    -0
      Builds/VisualStudio2010/Juce.vcxproj
  7. +6
    -0
      Builds/VisualStudio2010/Juce.vcxproj.filters
  8. +6
    -0
      Builds/iPhone/Juce.xcodeproj/project.pbxproj
  9. +4
    -0
      Juce.jucer
  10. +1
    -0
      amalgamation/juce_amalgamated_template.cpp
  11. +347
    -264
      juce_amalgamated.cpp
  12. +233
    -78
      juce_amalgamated.h
  13. +1
    -1
      src/core/juce_StandardHeader.h
  14. +6
    -0
      src/gui/components/juce_Component.cpp
  15. +9
    -0
      src/gui/components/juce_Component.h
  16. +50
    -41
      src/gui/components/layout/juce_ComponentBuilder.cpp
  17. +100
    -40
      src/gui/components/layout/juce_ComponentBuilder.h
  18. +262
    -0
      src/gui/components/layout/juce_MarkerList.cpp
  19. +141
    -0
      src/gui/components/layout/juce_MarkerList.h
  20. +16
    -24
      src/gui/graphics/drawables/juce_Drawable.cpp
  21. +7
    -5
      src/gui/graphics/drawables/juce_Drawable.h
  22. +41
    -196
      src/gui/graphics/drawables/juce_DrawableComposite.cpp
  23. +8
    -33
      src/gui/graphics/drawables/juce_DrawableComposite.h
  24. +3
    -0
      src/juce_app_includes.h
  25. +2
    -2
      src/native/mac/juce_mac_NativeIncludes.h
  26. +2
    -3
      src/native/windows/juce_win32_Windowing.cpp

+ 6
- 0
Builds/Linux/Makefile View File

@@ -174,6 +174,7 @@ OBJECTS := \
$(OBJDIR)/juce_ComponentBuilder_2aa6c5a.o \
$(OBJDIR)/juce_ComponentMovementWatcher_cbb3e7cc.o \
$(OBJDIR)/juce_GroupComponent_456e237a.o \
$(OBJDIR)/juce_MarkerList_aea878b4.o \
$(OBJDIR)/juce_MultiDocumentPanel_50e05aac.o \
$(OBJDIR)/juce_ResizableBorderComponent_7f4f2182.o \
$(OBJDIR)/juce_ResizableCornerComponent_1cac2df9.o \
@@ -1038,6 +1039,11 @@ $(OBJDIR)/juce_GroupComponent_456e237a.o: ../../src/gui/components/layout/juce_G
@echo "Compiling juce_GroupComponent.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/juce_MarkerList_aea878b4.o: ../../src/gui/components/layout/juce_MarkerList.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling juce_MarkerList.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/juce_MultiDocumentPanel_50e05aac.o: ../../src/gui/components/layout/juce_MultiDocumentPanel.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling juce_MultiDocumentPanel.cpp"


+ 6
- 0
Builds/MacOSX/Juce.xcodeproj/project.pbxproj View File

@@ -143,6 +143,7 @@
9AA76460DA7D34CE6A69E2B1 = { isa = PBXBuildFile; fileRef = 45E5EE9E0173683D721FABDA; };
4E81BC4A50CF1883F529E152 = { isa = PBXBuildFile; fileRef = F8FCCCE06D31FEF697FCD80D; };
8FBB6BF0C5406E1BA481CFEF = { isa = PBXBuildFile; fileRef = A6AD7357F905309D1B461EB7; };
260EF664D324038F9DC6C35B = { isa = PBXBuildFile; fileRef = F665A039C3A85EFDAA3E1245; };
F5F3F25D9F377128DC74D95B = { isa = PBXBuildFile; fileRef = FF046140CCF1EDB0DFF80178; };
C64A2BF05224582134872415 = { isa = PBXBuildFile; fileRef = A95F42C5CB0C2E5052B31568; };
0A9C9486A6B31F21B1472D2B = { isa = PBXBuildFile; fileRef = A31221E2A50CCE9DF06B5F4B; };
@@ -666,6 +667,8 @@
44CDA79090B115C3B62A2168 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentMovementWatcher.h; path = ../../src/gui/components/layout/juce_ComponentMovementWatcher.h; sourceTree = SOURCE_ROOT; };
A6AD7357F905309D1B461EB7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GroupComponent.cpp; path = ../../src/gui/components/layout/juce_GroupComponent.cpp; sourceTree = SOURCE_ROOT; };
E9242E8425497D889C764C66 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GroupComponent.h; path = ../../src/gui/components/layout/juce_GroupComponent.h; sourceTree = SOURCE_ROOT; };
F665A039C3A85EFDAA3E1245 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MarkerList.cpp; path = ../../src/gui/components/layout/juce_MarkerList.cpp; sourceTree = SOURCE_ROOT; };
8A9F1A98C0C96BF655F606AB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MarkerList.h; path = ../../src/gui/components/layout/juce_MarkerList.h; sourceTree = SOURCE_ROOT; };
FF046140CCF1EDB0DFF80178 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MultiDocumentPanel.cpp; path = ../../src/gui/components/layout/juce_MultiDocumentPanel.cpp; sourceTree = SOURCE_ROOT; };
B6A223FB5B4A9388C83D6FC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MultiDocumentPanel.h; path = ../../src/gui/components/layout/juce_MultiDocumentPanel.h; sourceTree = SOURCE_ROOT; };
A95F42C5CB0C2E5052B31568 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ResizableBorderComponent.cpp; path = ../../src/gui/components/layout/juce_ResizableBorderComponent.cpp; sourceTree = SOURCE_ROOT; };
@@ -1397,6 +1400,8 @@
44CDA79090B115C3B62A2168,
A6AD7357F905309D1B461EB7,
E9242E8425497D889C764C66,
F665A039C3A85EFDAA3E1245,
8A9F1A98C0C96BF655F606AB,
FF046140CCF1EDB0DFF80178,
B6A223FB5B4A9388C83D6FC7,
A95F42C5CB0C2E5052B31568,
@@ -2077,6 +2082,7 @@
9AA76460DA7D34CE6A69E2B1,
4E81BC4A50CF1883F529E152,
8FBB6BF0C5406E1BA481CFEF,
260EF664D324038F9DC6C35B,
F5F3F25D9F377128DC74D95B,
C64A2BF05224582134872415,
0A9C9486A6B31F21B1472D2B,


+ 2
- 0
Builds/VisualStudio2005/Juce.vcproj View File

@@ -548,6 +548,8 @@
<File RelativePath="..\..\src\gui\components\layout\juce_ComponentMovementWatcher.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_GroupComponent.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_GroupComponent.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MarkerList.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MarkerList.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MultiDocumentPanel.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MultiDocumentPanel.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_ResizableBorderComponent.cpp"/>


+ 2
- 0
Builds/VisualStudio2008/Juce.vcproj View File

@@ -548,6 +548,8 @@
<File RelativePath="..\..\src\gui\components\layout\juce_ComponentMovementWatcher.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_GroupComponent.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_GroupComponent.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MarkerList.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MarkerList.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MultiDocumentPanel.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MultiDocumentPanel.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_ResizableBorderComponent.cpp"/>


+ 2
- 0
Builds/VisualStudio2008_DLL/Juce.vcproj View File

@@ -550,6 +550,8 @@
<File RelativePath="..\..\src\gui\components\layout\juce_ComponentMovementWatcher.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_GroupComponent.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_GroupComponent.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MarkerList.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MarkerList.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MultiDocumentPanel.cpp"/>
<File RelativePath="..\..\src\gui\components\layout\juce_MultiDocumentPanel.h"/>
<File RelativePath="..\..\src\gui\components\layout\juce_ResizableBorderComponent.cpp"/>


+ 2
- 0
Builds/VisualStudio2010/Juce.vcxproj View File

@@ -257,6 +257,7 @@
<ClCompile Include="..\..\src\gui\components\layout\juce_ComponentBuilder.cpp"/>
<ClCompile Include="..\..\src\gui\components\layout\juce_ComponentMovementWatcher.cpp"/>
<ClCompile Include="..\..\src\gui\components\layout\juce_GroupComponent.cpp"/>
<ClCompile Include="..\..\src\gui\components\layout\juce_MarkerList.cpp"/>
<ClCompile Include="..\..\src\gui\components\layout\juce_MultiDocumentPanel.cpp"/>
<ClCompile Include="..\..\src\gui\components\layout\juce_ResizableBorderComponent.cpp"/>
<ClCompile Include="..\..\src\gui\components\layout\juce_ResizableCornerComponent.cpp"/>
@@ -607,6 +608,7 @@
<ClInclude Include="..\..\src\gui\components\layout\juce_ComponentBuilder.h"/>
<ClInclude Include="..\..\src\gui\components\layout\juce_ComponentMovementWatcher.h"/>
<ClInclude Include="..\..\src\gui\components\layout\juce_GroupComponent.h"/>
<ClInclude Include="..\..\src\gui\components\layout\juce_MarkerList.h"/>
<ClInclude Include="..\..\src\gui\components\layout\juce_MultiDocumentPanel.h"/>
<ClInclude Include="..\..\src\gui\components\layout\juce_ResizableBorderComponent.h"/>
<ClInclude Include="..\..\src\gui\components\layout\juce_ResizableCornerComponent.h"/>


+ 6
- 0
Builds/VisualStudio2010/Juce.vcxproj.filters View File

@@ -625,6 +625,9 @@
<ClCompile Include="..\..\src\gui\components\layout\juce_GroupComponent.cpp">
<Filter>Juce\Source\gui\components\layout</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gui\components\layout\juce_MarkerList.cpp">
<Filter>Juce\Source\gui\components\layout</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gui\components\layout\juce_MultiDocumentPanel.cpp">
<Filter>Juce\Source\gui\components\layout</Filter>
</ClCompile>
@@ -1749,6 +1752,9 @@
<ClInclude Include="..\..\src\gui\components\layout\juce_GroupComponent.h">
<Filter>Juce\Source\gui\components\layout</Filter>
</ClInclude>
<ClInclude Include="..\..\src\gui\components\layout\juce_MarkerList.h">
<Filter>Juce\Source\gui\components\layout</Filter>
</ClInclude>
<ClInclude Include="..\..\src\gui\components\layout\juce_MultiDocumentPanel.h">
<Filter>Juce\Source\gui\components\layout</Filter>
</ClInclude>


+ 6
- 0
Builds/iPhone/Juce.xcodeproj/project.pbxproj View File

@@ -143,6 +143,7 @@
9AA76460DA7D34CE6A69E2B1 = { isa = PBXBuildFile; fileRef = 45E5EE9E0173683D721FABDA; };
4E81BC4A50CF1883F529E152 = { isa = PBXBuildFile; fileRef = F8FCCCE06D31FEF697FCD80D; };
8FBB6BF0C5406E1BA481CFEF = { isa = PBXBuildFile; fileRef = A6AD7357F905309D1B461EB7; };
260EF664D324038F9DC6C35B = { isa = PBXBuildFile; fileRef = F665A039C3A85EFDAA3E1245; };
F5F3F25D9F377128DC74D95B = { isa = PBXBuildFile; fileRef = FF046140CCF1EDB0DFF80178; };
C64A2BF05224582134872415 = { isa = PBXBuildFile; fileRef = A95F42C5CB0C2E5052B31568; };
0A9C9486A6B31F21B1472D2B = { isa = PBXBuildFile; fileRef = A31221E2A50CCE9DF06B5F4B; };
@@ -666,6 +667,8 @@
44CDA79090B115C3B62A2168 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentMovementWatcher.h; path = ../../src/gui/components/layout/juce_ComponentMovementWatcher.h; sourceTree = SOURCE_ROOT; };
A6AD7357F905309D1B461EB7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GroupComponent.cpp; path = ../../src/gui/components/layout/juce_GroupComponent.cpp; sourceTree = SOURCE_ROOT; };
E9242E8425497D889C764C66 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GroupComponent.h; path = ../../src/gui/components/layout/juce_GroupComponent.h; sourceTree = SOURCE_ROOT; };
F665A039C3A85EFDAA3E1245 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MarkerList.cpp; path = ../../src/gui/components/layout/juce_MarkerList.cpp; sourceTree = SOURCE_ROOT; };
8A9F1A98C0C96BF655F606AB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MarkerList.h; path = ../../src/gui/components/layout/juce_MarkerList.h; sourceTree = SOURCE_ROOT; };
FF046140CCF1EDB0DFF80178 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MultiDocumentPanel.cpp; path = ../../src/gui/components/layout/juce_MultiDocumentPanel.cpp; sourceTree = SOURCE_ROOT; };
B6A223FB5B4A9388C83D6FC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MultiDocumentPanel.h; path = ../../src/gui/components/layout/juce_MultiDocumentPanel.h; sourceTree = SOURCE_ROOT; };
A95F42C5CB0C2E5052B31568 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ResizableBorderComponent.cpp; path = ../../src/gui/components/layout/juce_ResizableBorderComponent.cpp; sourceTree = SOURCE_ROOT; };
@@ -1397,6 +1400,8 @@
44CDA79090B115C3B62A2168,
A6AD7357F905309D1B461EB7,
E9242E8425497D889C764C66,
F665A039C3A85EFDAA3E1245,
8A9F1A98C0C96BF655F606AB,
FF046140CCF1EDB0DFF80178,
B6A223FB5B4A9388C83D6FC7,
A95F42C5CB0C2E5052B31568,
@@ -2077,6 +2082,7 @@
9AA76460DA7D34CE6A69E2B1,
4E81BC4A50CF1883F529E152,
8FBB6BF0C5406E1BA481CFEF,
260EF664D324038F9DC6C35B,
F5F3F25D9F377128DC74D95B,
C64A2BF05224582134872415,
0A9C9486A6B31F21B1472D2B,


+ 4
- 0
Juce.jucer View File

@@ -728,6 +728,10 @@
file="src/gui/components/layout/juce_GroupComponent.cpp"/>
<FILE id="JsmHuUYf" name="juce_GroupComponent.h" compile="0" resource="0"
file="src/gui/components/layout/juce_GroupComponent.h"/>
<FILE id="V5xE9Zr" name="juce_MarkerList.cpp" compile="1" resource="0"
file="src/gui/components/layout/juce_MarkerList.cpp"/>
<FILE id="yRrV92n" name="juce_MarkerList.h" compile="0" resource="0"
file="src/gui/components/layout/juce_MarkerList.h"/>
<FILE id="VDH7MUcn5" name="juce_MultiDocumentPanel.cpp" compile="1"
resource="0" file="src/gui/components/layout/juce_MultiDocumentPanel.cpp"/>
<FILE id="FHg3JXTUa" name="juce_MultiDocumentPanel.h" compile="0" resource="0"


+ 1
- 0
amalgamation/juce_amalgamated_template.cpp View File

@@ -277,6 +277,7 @@
#include "../src/gui/components/layout/juce_ComponentBoundsConstrainer.cpp"
#include "../src/gui/components/layout/juce_ComponentMovementWatcher.cpp"
#include "../src/gui/components/layout/juce_GroupComponent.cpp"
#include "../src/gui/components/layout/juce_MarkerList.cpp"
#include "../src/gui/components/layout/juce_MultiDocumentPanel.cpp"
#include "../src/gui/components/layout/juce_ResizableBorderComponent.cpp"
#include "../src/gui/components/layout/juce_ResizableCornerComponent.cpp"


+ 347
- 264
juce_amalgamated.cpp View File

@@ -892,8 +892,8 @@ protected:
#import <IOKit/hid/IOHIDKeys.h>
#import <IOKit/pwr_mgt/IOPMLib.h>
#endif
#if JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \
&& ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
#if (JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU)) \
|| ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
#include <Carbon/Carbon.h>
#endif
#include <sys/dir.h>
@@ -41524,6 +41524,11 @@ void Component::colourChanged()
{
}

MarkerList* Component::getMarkers (bool /*xAxis*/)
{
return 0;
}

const Rectangle<int> Component::getLocalBounds() const throw()
{
return Rectangle<int> (getWidth(), getHeight());
@@ -61337,6 +61342,35 @@ namespace ComponentBuilderHelpers
c->setComponentID (getStateId (state));
return c;
}

void updateComponent (ComponentBuilder& builder, const ValueTree& state)
{
Component* topLevelComp = builder.getManagedComponent();

if (topLevelComp != 0)
{
const String compId (getStateId (state));

if (compId.isEmpty() && state.getParent().isValid())
{
// ..handle the case where a child of the actual state node has changed.
updateComponent (builder, state.getParent());
}
else
{
ComponentBuilder::TypeHandler* const type = builder.getHandlerForState (state);

if (type != 0)
{
Component* const changedComp = findComponentWithID (topLevelComp, compId);

if (changedComp != 0)
type->updateComponentFromState (changedComp, state);
}
}
}
}

}

const Identifier ComponentBuilder::idProperty ("id");
@@ -61350,28 +61384,36 @@ ComponentBuilder::ComponentBuilder (const ValueTree& state_)
ComponentBuilder::~ComponentBuilder()
{
state.removeListener (this);

#if JUCE_DEBUG
// Don't delete the managed component!! The builder owns that component, and will delete
// it automatically when it gets deleted.
jassert (componentRef.get() == static_cast <Component*> (component));
#endif
}

Component* ComponentBuilder::getComponent()
Component* ComponentBuilder::getManagedComponent()
{
if (component == 0)
{
jassert (types.size() > 0); // You need to register all the necessary types before you can load a component!
component = createComponent();

TypeHandler* const type = getHandlerForState (state);
jassert (type != 0); // trying to create a component from an unknown type of ValueTree

if (type != 0)
component = ComponentBuilderHelpers::createNewComponent (*type, state, 0);
#if JUCE_DEBUG
componentRef = component;
#endif
}

return component;
}

Component* ComponentBuilder::getAndReleaseComponent()
Component* ComponentBuilder::createComponent()
{
getComponent();
return component.release();
jassert (types.size() > 0); // You need to register all the necessary types before you can load a component!

TypeHandler* const type = getHandlerForState (state);
jassert (type != 0); // trying to create a component from an unknown type of ValueTree

return type != 0 ? ComponentBuilderHelpers::createNewComponent (*type, state, 0) : 0;
}

void ComponentBuilder::registerTypeHandler (ComponentBuilder::TypeHandler* const type)
@@ -61411,34 +61453,6 @@ ComponentBuilder::TypeHandler* ComponentBuilder::getHandler (const int index) co
return types [index];
}

void ComponentBuilder::updateComponent (const ValueTree& state)
{
using namespace ComponentBuilderHelpers;

if (component != 0)
{
const String compId (getStateId (state));

if (compId.isEmpty() && state.getParent().isValid())
{
// ..handle the case where a child of the actual state node has changed.
updateComponent (state.getParent());
}
else
{
TypeHandler* const type = getHandlerForState (state);

if (type != 0)
{
Component* const changedComp = findComponentWithID (component, compId);

if (changedComp != 0)
type->updateComponentFromState (changedComp, state);
}
}
}
}

void ComponentBuilder::setImageProvider (ImageProvider* newImageProvider) throw()
{
imageProvider = newImageProvider;
@@ -61451,17 +61465,17 @@ ComponentBuilder::ImageProvider* ComponentBuilder::getImageProvider() const thro

void ComponentBuilder::valueTreePropertyChanged (ValueTree& tree, const Identifier&)
{
updateComponent (tree);
ComponentBuilderHelpers::updateComponent (*this, tree);
}

void ComponentBuilder::valueTreeChildrenChanged (ValueTree& tree)
{
updateComponent (tree);
ComponentBuilderHelpers::updateComponent (*this, tree);
}

void ComponentBuilder::valueTreeParentChanged (ValueTree& tree)
{
updateComponent (tree);
ComponentBuilderHelpers::updateComponent (*this, tree);
}

ComponentBuilder::TypeHandler::TypeHandler (const Identifier& valueTreeType_)
@@ -61995,6 +62009,238 @@ END_JUCE_NAMESPACE
/*** End of inlined file: juce_GroupComponent.cpp ***/


/*** Start of inlined file: juce_MarkerList.cpp ***/
BEGIN_JUCE_NAMESPACE

MarkerList::MarkerList()
{
}

MarkerList::MarkerList (const MarkerList& other)
{
operator= (other);
}

MarkerList& MarkerList::operator= (const MarkerList& other)
{
if (other != *this)
{
markers.clear();
markers.addCopiesOf (other.markers);
markersHaveChanged();
}

return *this;
}

MarkerList::~MarkerList()
{
}

bool MarkerList::operator== (const MarkerList& other) const throw()
{
if (other.markers.size() != markers.size())
return false;

for (int i = markers.size(); --i >= 0;)
{
const Marker* const m1 = markers.getUnchecked(i);
jassert (m1 != 0);

const Marker* const m2 = other.getMarker (m1->name);

if (m2 == 0 || *m1 != *m2)
return false;
}

return true;
}

bool MarkerList::operator!= (const MarkerList& other) const throw()
{
return ! operator== (other);
}

int MarkerList::getNumMarkers() const throw()
{
return markers.size();
}

const MarkerList::Marker* MarkerList::getMarker (const int index) const throw()
{
return markers [index];
}

const MarkerList::Marker* MarkerList::getMarker (const String& name) const throw()
{
for (int i = 0; i < markers.size(); ++i)
{
const Marker* const m = markers.getUnchecked(i);

if (m->name == name)
return m;
}

return 0;
}

void MarkerList::setMarker (const String& name, const RelativeCoordinate& position)
{
Marker* const m = const_cast <Marker*> (getMarker (name));

if (m != 0)
{
if (m->position != position)
{
m->position = position;
markersHaveChanged();
}

return;
}

markers.add (new Marker (name, position));
markersHaveChanged();
}

void MarkerList::removeMarker (const int index)
{
if (isPositiveAndBelow (index, markers.size()))
{
markers.remove (index);
markersHaveChanged();
}
}

void MarkerList::removeMarker (const String& name)
{
for (int i = 0; i < markers.size(); ++i)
{
const Marker* const m = markers.getUnchecked(i);

if (m->name == name)
{
markers.remove (i);
markersHaveChanged();
}
}
}

void MarkerList::markersHaveChanged()
{
sendChangeMessage();
}

MarkerList::Marker::Marker (const Marker& other)
: name (other.name), position (other.position)
{
}

MarkerList::Marker::Marker (const String& name_, const RelativeCoordinate& position_)
: name (name_), position (position_)
{
}

bool MarkerList::Marker::operator== (const Marker& other) const throw()
{
return name == other.name && position == other.position;
}

bool MarkerList::Marker::operator!= (const Marker& other) const throw()
{
return ! operator== (other);
}

const Identifier MarkerList::ValueTreeWrapper::markerTag ("Marker");
const Identifier MarkerList::ValueTreeWrapper::nameProperty ("name");
const Identifier MarkerList::ValueTreeWrapper::posProperty ("position");

MarkerList::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
: state (state_)
{
}

int MarkerList::ValueTreeWrapper::getNumMarkers() const
{
return state.getNumChildren();
}

const ValueTree MarkerList::ValueTreeWrapper::getMarkerState (int index) const
{
return state.getChild (index);
}

const ValueTree MarkerList::ValueTreeWrapper::getMarkerState (const String& name) const
{
return state.getChildWithProperty (nameProperty, name);
}

bool MarkerList::ValueTreeWrapper::containsMarker (const ValueTree& marker) const
{
return marker.isAChildOf (state);
}

const MarkerList::Marker MarkerList::ValueTreeWrapper::getMarker (const ValueTree& marker) const
{
jassert (containsMarker (marker));

return MarkerList::Marker (marker [nameProperty], RelativeCoordinate (marker [posProperty].toString()));
}

void MarkerList::ValueTreeWrapper::setMarker (const MarkerList::Marker& m, UndoManager* undoManager)
{
ValueTree marker (state.getChildWithProperty (nameProperty, m.name));

if (marker.isValid())
{
marker.setProperty (posProperty, m.position.toString(), undoManager);
}
else
{
marker = ValueTree (markerTag);
marker.setProperty (nameProperty, m.name, 0);
marker.setProperty (posProperty, m.position.toString(), 0);
state.addChild (marker, -1, undoManager);
}
}

void MarkerList::ValueTreeWrapper::removeMarker (const ValueTree& marker, UndoManager* undoManager)
{
state.removeChild (marker, undoManager);
}

void MarkerList::ValueTreeWrapper::applyTo (MarkerList& markerList)
{
const int numMarkers = getNumMarkers();

StringArray updatedMarkers;

int i;
for (i = 0; i < numMarkers; ++i)
{
const ValueTree marker (state.getChild (i));
const String name (marker [nameProperty].toString());
markerList.setMarker (name, RelativeCoordinate (marker [posProperty].toString()));
updatedMarkers.add (name);
}

for (i = markerList.getNumMarkers(); --i >= 0;)
if (! updatedMarkers.contains (markerList.getMarker (i)->name))
markerList.removeMarker (i);
}

void MarkerList::ValueTreeWrapper::readFrom (const MarkerList& markerList, UndoManager* undoManager)
{
state.removeAllChildren (undoManager);

for (int i = 0; i < markerList.getNumMarkers(); ++i)
setMarker (*markerList.getMarker(i), undoManager);
}

END_JUCE_NAMESPACE
/*** End of inlined file: juce_MarkerList.cpp ***/


/*** Start of inlined file: juce_MultiDocumentPanel.cpp ***/
BEGIN_JUCE_NAMESPACE

@@ -85738,10 +85984,6 @@ void Drawable::transformContextToCorrectOrigin (Graphics& g)
originRelativeToComponent.getY());
}

void Drawable::markerHasMoved()
{
}

void Drawable::parentHierarchyChanged()
{
setBoundsToEnclose (getDrawableBounds());
@@ -85816,20 +86058,6 @@ Drawable* Drawable::createFromImageFile (const File& file)
return fin != 0 ? createFromImageDataStream (*fin) : 0;
}

Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider)
{
ComponentBuilder builder (tree);
builder.setImageProvider (imageProvider);
registerDrawableTypes (builder);

Drawable* d = dynamic_cast<Drawable*> (builder.getComponent());

if (d != 0)
return dynamic_cast<Drawable*> (builder.getAndReleaseComponent());

return 0;
}

template <class DrawableClass>
class DrawableTypeHandler : public ComponentBuilder::TypeHandler
{
@@ -85858,7 +86086,7 @@ public:
}
};

void Drawable::registerDrawableTypes (ComponentBuilder& builder)
void Drawable::registerDrawableTypeHandlers (ComponentBuilder& builder)
{
builder.registerTypeHandler (new DrawableTypeHandler <DrawablePath>());
builder.registerTypeHandler (new DrawableTypeHandler <DrawableComposite>());
@@ -85867,12 +86095,23 @@ void Drawable::registerDrawableTypes (ComponentBuilder& builder)
builder.registerTypeHandler (new DrawableTypeHandler <DrawableText>());
}

Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_)
: state (state_)
Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider)
{
ComponentBuilder builder (tree);
builder.setImageProvider (imageProvider);
registerDrawableTypeHandlers (builder);

ScopedPointer<Component> comp (builder.createComponent());
Drawable* const d = dynamic_cast<Drawable*> (static_cast <Component*> (comp));

if (d != 0)
comp.release();

return d;
}

Drawable::ValueTreeWrapperBase::~ValueTreeWrapperBase()
Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_)
: state (state_)
{
}

@@ -86248,6 +86487,8 @@ DrawableComposite::DrawableComposite()

DrawableComposite::DrawableComposite (const DrawableComposite& other)
: bounds (other.bounds),
markersX (other.markersX),
markersY (other.markersY),
updateBoundsReentrant (false)
{
for (int i = 0; i < other.getNumChildComponents(); ++i)
@@ -86257,9 +86498,6 @@ DrawableComposite::DrawableComposite (const DrawableComposite& other)
if (d != 0)
addAndMakeVisible (d->createCopy());
}

markersX.addCopiesOf (other.markersX);
markersY.addCopiesOf (other.markersY);
}

DrawableComposite::~DrawableComposite()
@@ -86283,32 +86521,26 @@ const Rectangle<float> DrawableComposite::getDrawableBounds() const
return r;
}

void DrawableComposite::markerHasMoved()
MarkerList* DrawableComposite::getMarkers (bool xAxis)
{
for (int i = getNumChildComponents(); --i >= 0;)
{
Drawable* const d = dynamic_cast <Drawable*> (getChildComponent(i));

if (d != 0)
d->markerHasMoved();
}
return xAxis ? &markersX : &markersY;
}

const RelativeRectangle DrawableComposite::getContentArea() const
{
jassert (markersX.size() >= 2 && getMarker (true, 0)->name == contentLeftMarkerName && getMarker (true, 1)->name == contentRightMarkerName);
jassert (markersY.size() >= 2 && getMarker (false, 0)->name == contentTopMarkerName && getMarker (false, 1)->name == contentBottomMarkerName);
jassert (markersX.getNumMarkers() >= 2 && markersX.getMarker (0)->name == contentLeftMarkerName && markersX.getMarker (1)->name == contentRightMarkerName);
jassert (markersY.getNumMarkers() >= 2 && markersY.getMarker (0)->name == contentTopMarkerName && markersY.getMarker (1)->name == contentBottomMarkerName);

return RelativeRectangle (markersX.getUnchecked(0)->position, markersX.getUnchecked(1)->position,
markersY.getUnchecked(0)->position, markersY.getUnchecked(1)->position);
return RelativeRectangle (markersX.getMarker(0)->position, markersX.getMarker(1)->position,
markersY.getMarker(0)->position, markersY.getMarker(1)->position);
}

void DrawableComposite::setContentArea (const RelativeRectangle& newArea)
{
setMarker (contentLeftMarkerName, true, newArea.left);
setMarker (contentRightMarkerName, true, newArea.right);
setMarker (contentTopMarkerName, false, newArea.top);
setMarker (contentBottomMarkerName, false, newArea.bottom);
markersX.setMarker (contentLeftMarkerName, newArea.left);
markersX.setMarker (contentRightMarkerName, newArea.right);
markersY.setMarker (contentTopMarkerName, newArea.top);
markersY.setMarker (contentBottomMarkerName, newArea.bottom);
refreshTransformFromBounds();
}

@@ -86422,80 +86654,17 @@ const char* const DrawableComposite::contentRightMarkerName = "right";
const char* const DrawableComposite::contentTopMarkerName = "top";
const char* const DrawableComposite::contentBottomMarkerName = "bottom";

DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other)
: name (other.name), position (other.position)
{
}

DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_)
: name (name_), position (position_)
{
}

bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw()
{
return name != other.name || position != other.position;
}

int DrawableComposite::getNumMarkers (const bool xAxis) const throw()
{
return (xAxis ? markersX : markersY).size();
}

const DrawableComposite::Marker* DrawableComposite::getMarker (const bool xAxis, const int index) const throw()
{
return (xAxis ? markersX : markersY) [index];
}

void DrawableComposite::setMarker (const String& name, const bool xAxis, const RelativeCoordinate& position)
{
OwnedArray <Marker>& markers = (xAxis ? markersX : markersY);

for (int i = 0; i < markers.size(); ++i)
{
Marker* const m = markers.getUnchecked(i);
if (m->name == name)
{
if (m->position != position)
{
m->position = position;
markerHasMoved();
}

return;
}
}

(xAxis ? markersX : markersY).add (new Marker (name, position));
markerHasMoved();
}

void DrawableComposite::removeMarker (const bool xAxis, const int index)
{
jassert (index >= 2);

if (index >= 2)
(xAxis ? markersX : markersY).remove (index);
}

const Expression DrawableComposite::getSymbolValue (const String& symbol, const String& member) const
{
jassert (member.isEmpty()) // the only symbols available in a Drawable are markers.

int i;
for (i = 0; i < markersX.size(); ++i)
{
Marker* const m = markersX.getUnchecked(i);
if (m->name == symbol)
return m->position.getExpression();
}
const MarkerList::Marker* m = markersX.getMarker (symbol);

for (i = 0; i < markersY.size(); ++i)
{
Marker* const m = markersY.getUnchecked(i);
if (m->name == symbol)
return m->position.getExpression();
}
if (m == 0)
m = markersY.getMarker (symbol);

if (m != 0)
return m->position.getExpression();

throw Expression::EvaluationError (symbol, member);
}
@@ -86513,9 +86682,6 @@ const Identifier DrawableComposite::ValueTreeWrapper::bottomLeft ("bottomLeft");
const Identifier DrawableComposite::ValueTreeWrapper::childGroupTag ("Drawables");
const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagX ("MarkersX");
const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagY ("MarkersY");
const Identifier DrawableComposite::ValueTreeWrapper::markerTag ("Marker");
const Identifier DrawableComposite::ValueTreeWrapper::nameProperty ("name");
const Identifier DrawableComposite::ValueTreeWrapper::posProperty ("position");

DrawableComposite::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
: ValueTreeWrapperBase (state_)
@@ -86558,85 +86724,36 @@ void DrawableComposite::ValueTreeWrapper::resetBoundingBoxToContentArea (UndoMan

const RelativeRectangle DrawableComposite::ValueTreeWrapper::getContentArea() const
{
return RelativeRectangle (getMarker (true, getMarkerState (true, 0)).position,
getMarker (true, getMarkerState (true, 1)).position,
getMarker (false, getMarkerState (false, 0)).position,
getMarker (false, getMarkerState (false, 1)).position);
MarkerList::ValueTreeWrapper markersX (getMarkerList (true));
MarkerList::ValueTreeWrapper markersY (getMarkerList (false));

return RelativeRectangle (markersX.getMarker (markersX.getMarkerState (0)).position,
markersX.getMarker (markersX.getMarkerState (1)).position,
markersY.getMarker (markersY.getMarkerState (0)).position,
markersY.getMarker (markersY.getMarkerState (1)).position);
}

void DrawableComposite::ValueTreeWrapper::setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager)
{
setMarker (true, Marker (contentLeftMarkerName, newArea.left), undoManager);
setMarker (true, Marker (contentRightMarkerName, newArea.right), undoManager);
setMarker (false, Marker (contentTopMarkerName, newArea.top), undoManager);
setMarker (false, Marker (contentBottomMarkerName, newArea.bottom), undoManager);
MarkerList::ValueTreeWrapper markersX (getMarkerListCreating (true, 0));
MarkerList::ValueTreeWrapper markersY (getMarkerListCreating (false, 0));

markersX.setMarker (MarkerList::Marker (contentLeftMarkerName, newArea.left), undoManager);
markersX.setMarker (MarkerList::Marker (contentRightMarkerName, newArea.right), undoManager);
markersY.setMarker (MarkerList::Marker (contentTopMarkerName, newArea.top), undoManager);
markersY.setMarker (MarkerList::Marker (contentBottomMarkerName, newArea.bottom), undoManager);
}

ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const
MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const
{
return state.getChildWithName (xAxis ? markerGroupTagX : markerGroupTagY);
}

ValueTree DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager)
MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager)
{
return state.getOrCreateChildWithName (xAxis ? markerGroupTagX : markerGroupTagY, undoManager);
}

int DrawableComposite::ValueTreeWrapper::getNumMarkers (bool xAxis) const
{
return getMarkerList (xAxis).getNumChildren();
}

const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, int index) const
{
return getMarkerList (xAxis).getChild (index);
}

const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, const String& name) const
{
return getMarkerList (xAxis).getChildWithProperty (nameProperty, name);
}

bool DrawableComposite::ValueTreeWrapper::containsMarker (bool xAxis, const ValueTree& state) const
{
return state.isAChildOf (getMarkerList (xAxis));
}

const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (bool xAxis, const ValueTree& state) const
{
(void) xAxis;
jassert (containsMarker (xAxis, state));

return Marker (state [nameProperty], RelativeCoordinate (state [posProperty].toString()));
}

void DrawableComposite::ValueTreeWrapper::setMarker (bool xAxis, const Marker& m, UndoManager* undoManager)
{
ValueTree markerList (getMarkerListCreating (xAxis, undoManager));
ValueTree marker (markerList.getChildWithProperty (nameProperty, m.name));

if (marker.isValid())
{
marker.setProperty (posProperty, m.position.toString(), undoManager);
}
else
{
marker = ValueTree (markerTag);
marker.setProperty (nameProperty, m.name, 0);
marker.setProperty (posProperty, m.position.toString(), 0);
markerList.addChild (marker, -1, undoManager);
}
}

void DrawableComposite::ValueTreeWrapper::removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager)
{
if (state [nameProperty].toString() != contentLeftMarkerName
&& state [nameProperty].toString() != contentRightMarkerName
&& state [nameProperty].toString() != contentTopMarkerName
&& state [nameProperty].toString() != contentBottomMarkerName)
getMarkerList (xAxis).removeChild (state, undoManager);
}

void DrawableComposite::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder)
{
const ValueTreeWrapper wrapper (tree);
@@ -86646,39 +86763,8 @@ void DrawableComposite::refreshFromValueTree (const ValueTree& tree, ComponentBu
if (bounds != newBounds)
bounds = newBounds;

const int numMarkersX = wrapper.getNumMarkers (true);
const int numMarkersY = wrapper.getNumMarkers (false);

// Remove deleted markers...
if (markersX.size() > numMarkersX || markersY.size() > numMarkersY)
{
markersX.removeRange (jmax (2, numMarkersX), markersX.size());
markersY.removeRange (jmax (2, numMarkersY), markersY.size());
}

// Update markers and add new ones..
int i;
for (i = 0; i < numMarkersX; ++i)
{
const Marker newMarker (wrapper.getMarker (true, wrapper.getMarkerState (true, i)));
Marker* m = markersX[i];

if (m == 0)
markersX.add (new Marker (newMarker));
else if (newMarker != *m)
*m = newMarker;
}

for (i = 0; i < numMarkersY; ++i)
{
const Marker newMarker (wrapper.getMarker (false, wrapper.getMarkerState (false, i)));
Marker* m = markersY[i];

if (m == 0)
markersY.add (new Marker (newMarker));
else if (newMarker != *m)
*m = newMarker;
}
wrapper.getMarkerList (true).applyTo (markersX);
wrapper.getMarkerList (false).applyTo (markersY);

builder.updateChildComponents (*this, wrapper.getChildList());

@@ -86695,18 +86781,16 @@ const ValueTree DrawableComposite::createValueTree (ComponentBuilder::ImageProvi

ValueTree childList (v.getChildListCreating (0));

int i;
for (i = getNumChildComponents(); --i >= 0;)
for (int i = getNumChildComponents(); --i >= 0;)
{
const Drawable* const d = dynamic_cast <const Drawable*> (getChildComponent(i));
jassert (d != 0); // You can't save a mix of Drawables and normal components!

childList.addChild (d->createValueTree (imageProvider), -1, 0);
}

for (i = 0; i < markersX.size(); ++i)
v.setMarker (true, *markersX.getUnchecked(i), 0);

for (i = 0; i < markersY.size(); ++i)
v.setMarker (false, *markersY.getUnchecked(i), 0);
v.getMarkerListCreating (true, 0).readFrom (markersX, 0);
v.getMarkerListCreating (false, 0).readFrom (markersY, 0);

return tree;
}
@@ -243214,11 +243298,10 @@ private:
return 0;

case WM_NCPAINT:
if (wParam != 1)
handlePaintMessage();

if (hasTitleBar())
break;
else if (wParam != 1)
handlePaintMessage();

return 0;



+ 233
- 78
juce_amalgamated.h View File

@@ -73,7 +73,7 @@ namespace JuceDummyNamespace {}
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 2
#define JUCE_BUILDNUMBER 3

/** Current Juce version number.

@@ -26874,6 +26874,7 @@ class LookAndFeel;
class MouseInputSource;
class MouseInputSourceInternal;
class ComponentPeer;
class MarkerList;

/**
The base class for all JUCE user-interface objects.
@@ -28803,6 +28804,13 @@ public:
*/
virtual void colourChanged();

/** Components can implement this method to provide a MarkerList.
The default implementation of this method returns 0, but you can override it to
return a pointer to the component's marker list. If xAxis is true, it should
return the X marker list; if false, it should return the Y markers.
*/
virtual MarkerList* getMarkers (bool xAxis);

/** Returns the underlying native window handle for this component.

This is platform-dependent and strictly for power-users only!
@@ -45704,58 +45712,97 @@ public:
class JUCE_API ComponentBuilder : public ValueTree::Listener
{
public:
/**
/** Creates a ComponentBuilder that will use the given state.
Once you've created your builder, you should use registerTypeHandler() to register some
type handlers for it, and then you can call createComponent() or getManagedComponent()
to get the actual component.
*/
explicit ComponentBuilder (const ValueTree& state);

/** Destructor. */
~ComponentBuilder();

/**
*/
/** Returns the ValueTree that this builder is working with. */
ValueTree& getState() throw() { return state; }

/**
*/
/** Returns the ValueTree that this builder is working with. */
const ValueTree& getState() const throw() { return state; }

/**
/** Returns the builder's component (creating it if necessary).

The first time that this method is called, the builder will attempt to create a component
from the ValueTree, so you must have registered some suitable type handlers before calling
this. If there's a problem and the component can't be created, this method returns 0.

The component that is returned is owned by this ComponentBuilder, so you can put it inside
your own parent components, but don't delete it! The ComponentBuilder will delete it automatically
when the builder is destroyed. If you want to get a component that you can delete yourself,
call createComponent() instead.

The ComponentBuilder will update this component if any changes are made to the ValueTree, so if
there's a chance that the tree might change, be careful not to keep any pointers to sub-components,
as they may be changed or removed.
*/
Component* getComponent();
Component* getManagedComponent();

/**
/** Creates and returns a new instance of the component that the ValueTree represents.
The caller is responsible for using and deleting the object that is returned. Unlike
getManagedComponent(), the component that is returned will not be updated by the builder.
*/
Component* getAndReleaseComponent();
Component* createComponent();

/**
The class is a base class for objects that manage the loading of a type of component
from a ValueTree.

To store and re-load a tree of components as a ValueTree, each component type must have
a TypeHandler to represent it.

@see ComponentBuilder::registerTypeHandler(), Drawable::registerDrawableTypeHandlers()
*/
class JUCE_API TypeHandler
{
public:
/**

/** Creates a TypeHandler.
The valueTreeType must be the type name of the ValueTrees that this handler can parse.
*/
explicit TypeHandler (const Identifier& valueTreeType);

/** Destructor. */
virtual ~TypeHandler();

/**
*/
/** Returns the type of the ValueTrees that this handler can parse. */
const Identifier& getType() const throw() { return valueTreeType; }

/**
/** Returns the builder that this type is registered with. */
ComponentBuilder* getBuilder() const throw();

/** This method must create a new component from the given state, add it to the specified
parent component (which may be null), and return it.

The ValueTree will have been pre-checked to make sure that its type matches the type
that this handler supports.

There's no need to set the new Component's ID to match that of the state - the builder
will take care of that itself.
*/
virtual Component* addNewComponentFromState (const ValueTree& state, Component* parent) = 0;

/**
*/
virtual void updateComponentFromState (Component* component, const ValueTree& state) = 0;
/** This method must update an existing component from a new ValueTree state.

A component that has been created with addNewComponentFromState() may need to be updated
if the ValueTree changes, so this method is used to do that. Your implementation must do
whatever's necessary to update the component from the new state provided.

/**
The ValueTree will have been pre-checked to make sure that its type matches the type
that this handler supports, and the component will have been created by this type's
addNewComponentFromState() method.
*/
ComponentBuilder* getBuilder() const throw();
virtual void updateComponentFromState (Component* component, const ValueTree& state) = 0;

private:

friend class ComponentBuilder;
ComponentBuilder* builder;
const Identifier valueTreeType;
@@ -45763,25 +45810,35 @@ public:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TypeHandler);
};

/**
/** Adds a type handler that the builder can use when trying to load components.
@see Drawable::registerDrawableTypeHandlers()
*/
void registerTypeHandler (TypeHandler* type);

/**
*/
/** Tries to find a registered type handler that can load a component from the given ValueTree. */
TypeHandler* getHandlerForState (const ValueTree& state) const;

/**
/** Returns the number of registered type handlers.
@see getHandler, registerTypeHandler
*/
int getNumHandlers() const throw();

/**
/** Returns one of the registered type handlers.
@see getNumHandlers, registerTypeHandler
*/
TypeHandler* getHandler (int index) const throw();

/** This class is used when loading Drawables that contain images, and retrieves
the image for a stored identifier.
@see Drawable::createFromValueTree
/** This class is used when references to images need to be stored in ValueTrees.

An instance of an ImageProvider provides a mechanism for converting an Image to/from
a reference, which may be a file, URL, ID string, or whatever system is appropriate in
your app.

When you're loading components from a ValueTree that may need a way of loading images, you
should call ComponentBuilder::setImageProvider() to supply a suitable provider before
trying to load the component.

@see ComponentBuilder::setImageProvider()
*/
class JUCE_API ImageProvider
{
@@ -45798,18 +45855,33 @@ public:
virtual const Image getImageForIdentifier (const var& imageIdentifier) = 0;

/** Returns an identifier to be used to refer to a given image.
This is used when converting a drawable into a ValueTree, so if you're
only loading drawables, you can just return a var::null here.
This is used when a reference to an image is stored in a ValueTree.
*/
virtual const var getIdentifierForImage (const Image& image) = 0;
};

/** */
/** Gives the builder an ImageProvider object that the type handlers can use when
loading images from stored references.

The object that is passed in is not owned by the builder, so the caller must delete
it when it is no longer needed, but not while the builder may still be using it. To
clear the image provider, just call setImageProvider (0).
*/
void setImageProvider (ImageProvider* newImageProvider) throw();

/** */
/** Returns the current image provider that this builder is using, or 0 if none has been set. */
ImageProvider* getImageProvider() const throw();

/** Updates the children of a parent component by updating them from the children of
a given ValueTree.
*/
void updateChildComponents (Component& parent, const ValueTree& children);

/** An identifier for the property of the ValueTrees that is used to store a unique ID
for that component.
*/
static const Identifier idProperty;

/** @internal */
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
/** @internal */
@@ -45817,22 +45889,15 @@ public:
/** @internal */
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);

/**
*/
void updateChildComponents (Component& parent, const ValueTree& children);

/**
*/
static const Identifier idProperty;

private:

ValueTree state;
OwnedArray <TypeHandler> types;
ScopedPointer<Component> component;
ImageProvider* imageProvider;

void updateComponent (const ValueTree& state);
#if JUCE_DEBUG
WeakReference<Component> componentRef;
#endif

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentBuilder);
};
@@ -45964,6 +46029,7 @@ public:
If there are any images used within the drawable, you'll need to provide a valid
ImageProvider object that can be used to retrieve these images from whatever type
of identifier is used to represent them.
Internally, this uses a ComponentBuilder, and registerDrawableTypeHandlers().
*/
static Drawable* createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider);

@@ -45985,7 +46051,6 @@ public:
{
public:
ValueTreeWrapperBase (const ValueTree& state);
~ValueTreeWrapperBase();

ValueTree& getState() throw() { return state; }

@@ -45995,7 +46060,11 @@ public:
ValueTree state;
};

static void registerDrawableTypes (ComponentBuilder& componentBuilder);
/** Registers a set of ComponentBuilder::TypeHandler objects that can be used to
load all the different Drawable types from a saved state.
@see ComponentBuilder::registerTypeHandler()
*/
static void registerDrawableTypeHandlers (ComponentBuilder& componentBuilder);

protected:

@@ -46005,8 +46074,6 @@ protected:
/** @internal */
void transformContextToCorrectOrigin (Graphics& g);
/** @internal */
void markerHasMoved();
/** @internal */
void parentHierarchyChanged();
/** @internal */
void setBoundsToEnclose (const Rectangle<float>& area);
@@ -53890,6 +53957,120 @@ private:
/*** End of inlined file: juce_GroupComponent.h ***/


#endif
#ifndef __JUCE_MARKERLIST_JUCEHEADER__

/*** Start of inlined file: juce_MarkerList.h ***/
#ifndef __JUCE_MARKERLIST_JUCEHEADER__
#define __JUCE_MARKERLIST_JUCEHEADER__

/**
Holds a set of named marker points along a one-dimensional axis.

This class is used to store sets of X and Y marker points in components.
@see Component::getMarkers().

The MarkerList is also a ChangeBroadcaster, so that listeners can register to receive
a callback when a marker is moved,
*/
class JUCE_API MarkerList : public ChangeBroadcaster
{
public:

/** Creates an empty marker list. */
MarkerList();
/** Creates a copy of another marker list. */
MarkerList (const MarkerList& other);
/** Copies another marker list to this one. */
MarkerList& operator= (const MarkerList& other);
/** Destructor. */
~MarkerList();

/** Represents a marker in a MarkerList. */
class JUCE_API Marker
{
public:
/** Creates a copy of another Marker. */
Marker (const Marker& other);
/** Creates a Marker with a given name and position. */
Marker (const String& name, const RelativeCoordinate& position);

/** The marker's name. */
String name;

/** The marker's position. */
RelativeCoordinate position;

/** Returns true if both the names and positions of these two markers match. */
bool operator== (const Marker&) const throw();
/** Returns true if either the name or position of these two markers differ. */
bool operator!= (const Marker&) const throw();
};

/** Returns the number of markers in the list. */
int getNumMarkers() const throw();

/** Returns one of the markers in the list, by its index. */
const Marker* getMarker (int index) const throw();

/** Returns a named marker, or 0 if no such name is found.
Note that name comparisons are case-sensitive.
*/
const Marker* getMarker (const String& name) const throw();

/** Sets the position of a marker.

If the name already exists, then the existing marker is moved; if it doesn't exist, then a
new marker is added.
*/
void setMarker (const String& name, const RelativeCoordinate& position);

/** Deletes the marker at the given list index. */
void removeMarker (int index);

/** Deletes the marker with the given name. */
void removeMarker (const String& name);

/** Returns true if all the markers in these two lists match exactly. */
bool operator== (const MarkerList& other) const throw();
/** Returns true if not all the markers in these two lists match exactly. */
bool operator!= (const MarkerList& other) const throw();

/** Forms a wrapper around a ValueTree that can be used for storing a MarkerList. */
class ValueTreeWrapper
{
public:
ValueTreeWrapper (const ValueTree& state);

int getNumMarkers() const;
const ValueTree getMarkerState (int index) const;
const ValueTree getMarkerState (const String& name) const;
bool containsMarker (const ValueTree& state) const;
const MarkerList::Marker getMarker (const ValueTree& state) const;
void setMarker (const MarkerList::Marker& marker, UndoManager* undoManager);
void removeMarker (const ValueTree& state, UndoManager* undoManager);

void applyTo (MarkerList& markerList);
void readFrom (const MarkerList& markerList, UndoManager* undoManager);

private:
ValueTree state;

static const Identifier markerTag, nameProperty, posProperty;
};

private:

OwnedArray<Marker> markers;
void markersHaveChanged();

JUCE_LEAK_DETECTOR (MarkerList);
};

#endif // __JUCE_MARKERLIST_JUCEHEADER__
/*** End of inlined file: juce_MarkerList.h ***/


#endif
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__

@@ -61398,24 +61579,6 @@ public:
*/
void resetContentAreaAndBoundingBoxToFitChildren();

/** Represents a named marker position.
@see DrawableComposite::getMarker
*/
struct Marker
{
Marker (const Marker&);
Marker (const String& name, const RelativeCoordinate& position);
bool operator!= (const Marker&) const throw();

String name;
RelativeCoordinate position;
};

int getNumMarkers (bool xAxis) const throw();
const Marker* getMarker (bool xAxis, int index) const throw();
void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position);
void removeMarker (bool xAxis, int index);

/** The name of the marker that defines the left edge of the content area. */
static const char* const contentLeftMarkerName;
/** The name of the marker that defines the right edge of the content area. */
@@ -61438,13 +61601,13 @@ public:
/** @internal */
const Rectangle<float> getDrawableBounds() const;
/** @internal */
void markerHasMoved();
/** @internal */
void childBoundsChanged (Component*);
/** @internal */
void childrenChanged();
/** @internal */
void parentHierarchyChanged();
/** @internal */
MarkerList* getMarkers (bool xAxis);

/** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */
class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase
@@ -61462,27 +61625,19 @@ public:
const RelativeRectangle getContentArea() const;
void setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager);

int getNumMarkers (bool xAxis) const;
const ValueTree getMarkerState (bool xAxis, int index) const;
const ValueTree getMarkerState (bool xAxis, const String& name) const;
bool containsMarker (bool xAxis, const ValueTree& state) const;
const Marker getMarker (bool xAxis, const ValueTree& state) const;
void setMarker (bool xAxis, const Marker& marker, UndoManager* undoManager);
void removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager);
MarkerList::ValueTreeWrapper getMarkerList (bool xAxis) const;
MarkerList::ValueTreeWrapper getMarkerListCreating (bool xAxis, UndoManager* undoManager);

static const Identifier nameProperty, posProperty, topLeft, topRight, bottomLeft;
static const Identifier topLeft, topRight, bottomLeft;

private:
static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY, markerTag;

ValueTree getMarkerList (bool xAxis) const;
ValueTree getMarkerListCreating (bool xAxis, UndoManager* undoManager);
static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY;
};

private:

RelativeParallelogram bounds;
OwnedArray <Marker> markersX, markersY;
MarkerList markersX, markersY;
bool updateBoundsReentrant;

void refreshTransformFromBounds();


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

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 2
#define JUCE_BUILDNUMBER 3
/** Current Juce version number.


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

@@ -2049,6 +2049,12 @@ void Component::colourChanged()
{
}
//==============================================================================
MarkerList* Component::getMarkers (bool /*xAxis*/)
{
return 0;
}
//==============================================================================
const Rectangle<int> Component::getLocalBounds() const throw()
{


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

@@ -47,6 +47,7 @@ class LookAndFeel;
class MouseInputSource;
class MouseInputSourceInternal;
class ComponentPeer;
class MarkerList;
//==============================================================================
@@ -2016,6 +2017,14 @@ public:
*/
virtual void colourChanged();
//==============================================================================
/** Components can implement this method to provide a MarkerList.
The default implementation of this method returns 0, but you can override it to
return a pointer to the component's marker list. If xAxis is true, it should
return the X marker list; if false, it should return the Y markers.
*/
virtual MarkerList* getMarkers (bool xAxis);
//==============================================================================
/** Returns the underlying native window handle for this component.


+ 50
- 41
src/gui/components/layout/juce_ComponentBuilder.cpp View File

@@ -78,6 +78,35 @@ namespace ComponentBuilderHelpers
c->setComponentID (getStateId (state));
return c;
}
void updateComponent (ComponentBuilder& builder, const ValueTree& state)
{
Component* topLevelComp = builder.getManagedComponent();
if (topLevelComp != 0)
{
const String compId (getStateId (state));
if (compId.isEmpty() && state.getParent().isValid())
{
// ..handle the case where a child of the actual state node has changed.
updateComponent (builder, state.getParent());
}
else
{
ComponentBuilder::TypeHandler* const type = builder.getHandlerForState (state);
if (type != 0)
{
Component* const changedComp = findComponentWithID (topLevelComp, compId);
if (changedComp != 0)
type->updateComponentFromState (changedComp, state);
}
}
}
}
}
//=============================================================================
@@ -92,28 +121,36 @@ ComponentBuilder::ComponentBuilder (const ValueTree& state_)
ComponentBuilder::~ComponentBuilder()
{
state.removeListener (this);
#if JUCE_DEBUG
// Don't delete the managed component!! The builder owns that component, and will delete
// it automatically when it gets deleted.
jassert (componentRef.get() == static_cast <Component*> (component));
#endif
}
Component* ComponentBuilder::getComponent()
Component* ComponentBuilder::getManagedComponent()
{
if (component == 0)
{
jassert (types.size() > 0); // You need to register all the necessary types before you can load a component!
TypeHandler* const type = getHandlerForState (state);
jassert (type != 0); // trying to create a component from an unknown type of ValueTree
component = createComponent();
if (type != 0)
component = ComponentBuilderHelpers::createNewComponent (*type, state, 0);
#if JUCE_DEBUG
componentRef = component;
#endif
}
return component;
}
Component* ComponentBuilder::getAndReleaseComponent()
Component* ComponentBuilder::createComponent()
{
getComponent();
return component.release();
jassert (types.size() > 0); // You need to register all the necessary types before you can load a component!
TypeHandler* const type = getHandlerForState (state);
jassert (type != 0); // trying to create a component from an unknown type of ValueTree
return type != 0 ? ComponentBuilderHelpers::createNewComponent (*type, state, 0) : 0;
}
void ComponentBuilder::registerTypeHandler (ComponentBuilder::TypeHandler* const type)
@@ -153,34 +190,6 @@ ComponentBuilder::TypeHandler* ComponentBuilder::getHandler (const int index) co
return types [index];
}
void ComponentBuilder::updateComponent (const ValueTree& state)
{
using namespace ComponentBuilderHelpers;
if (component != 0)
{
const String compId (getStateId (state));
if (compId.isEmpty() && state.getParent().isValid())
{
// ..handle the case where a child of the actual state node has changed.
updateComponent (state.getParent());
}
else
{
TypeHandler* const type = getHandlerForState (state);
if (type != 0)
{
Component* const changedComp = findComponentWithID (component, compId);
if (changedComp != 0)
type->updateComponentFromState (changedComp, state);
}
}
}
}
void ComponentBuilder::setImageProvider (ImageProvider* newImageProvider) throw()
{
imageProvider = newImageProvider;
@@ -193,17 +202,17 @@ ComponentBuilder::ImageProvider* ComponentBuilder::getImageProvider() const thro
void ComponentBuilder::valueTreePropertyChanged (ValueTree& tree, const Identifier&)
{
updateComponent (tree);
ComponentBuilderHelpers::updateComponent (*this, tree);
}
void ComponentBuilder::valueTreeChildrenChanged (ValueTree& tree)
{
updateComponent (tree);
ComponentBuilderHelpers::updateComponent (*this, tree);
}
void ComponentBuilder::valueTreeParentChanged (ValueTree& tree)
{
updateComponent (tree);
ComponentBuilderHelpers::updateComponent (*this, tree);
}
//==============================================================================


+ 100
- 40
src/gui/components/layout/juce_ComponentBuilder.h View File

@@ -49,7 +49,10 @@
class JUCE_API ComponentBuilder : public ValueTree::Listener
{
public:
/**
/** Creates a ComponentBuilder that will use the given state.
Once you've created your builder, you should use registerTypeHandler() to register some
type handlers for it, and then you can call createComponent() or getManagedComponent()
to get the actual component.
*/
explicit ComponentBuilder (const ValueTree& state);
@@ -57,52 +60,89 @@ public:
~ComponentBuilder();
//==============================================================================
/**
*/
/** Returns the ValueTree that this builder is working with. */
ValueTree& getState() throw() { return state; }
/**
*/
/** Returns the ValueTree that this builder is working with. */
const ValueTree& getState() const throw() { return state; }
/**
/** Returns the builder's component (creating it if necessary).
The first time that this method is called, the builder will attempt to create a component
from the ValueTree, so you must have registered some suitable type handlers before calling
this. If there's a problem and the component can't be created, this method returns 0.
The component that is returned is owned by this ComponentBuilder, so you can put it inside
your own parent components, but don't delete it! The ComponentBuilder will delete it automatically
when the builder is destroyed. If you want to get a component that you can delete yourself,
call createComponent() instead.
The ComponentBuilder will update this component if any changes are made to the ValueTree, so if
there's a chance that the tree might change, be careful not to keep any pointers to sub-components,
as they may be changed or removed.
*/
Component* getComponent();
Component* getManagedComponent();
/**
/** Creates and returns a new instance of the component that the ValueTree represents.
The caller is responsible for using and deleting the object that is returned. Unlike
getManagedComponent(), the component that is returned will not be updated by the builder.
*/
Component* getAndReleaseComponent();
Component* createComponent();
//==============================================================================
/**
The class is a base class for objects that manage the loading of a type of component
from a ValueTree.
To store and re-load a tree of components as a ValueTree, each component type must have
a TypeHandler to represent it.
@see ComponentBuilder::registerTypeHandler(), Drawable::registerDrawableTypeHandlers()
*/
class JUCE_API TypeHandler
{
public:
/**
//==============================================================================
/** Creates a TypeHandler.
The valueTreeType must be the type name of the ValueTrees that this handler can parse.
*/
explicit TypeHandler (const Identifier& valueTreeType);
/** Destructor. */
virtual ~TypeHandler();
/**
*/
/** Returns the type of the ValueTrees that this handler can parse. */
const Identifier& getType() const throw() { return valueTreeType; }
/**
/** Returns the builder that this type is registered with. */
ComponentBuilder* getBuilder() const throw();
//==============================================================================
/** This method must create a new component from the given state, add it to the specified
parent component (which may be null), and return it.
The ValueTree will have been pre-checked to make sure that its type matches the type
that this handler supports.
There's no need to set the new Component's ID to match that of the state - the builder
will take care of that itself.
*/
virtual Component* addNewComponentFromState (const ValueTree& state, Component* parent) = 0;
/**
*/
virtual void updateComponentFromState (Component* component, const ValueTree& state) = 0;
/** This method must update an existing component from a new ValueTree state.
/**
A component that has been created with addNewComponentFromState() may need to be updated
if the ValueTree changes, so this method is used to do that. Your implementation must do
whatever's necessary to update the component from the new state provided.
The ValueTree will have been pre-checked to make sure that its type matches the type
that this handler supports, and the component will have been created by this type's
addNewComponentFromState() method.
*/
ComponentBuilder* getBuilder() const throw();
virtual void updateComponentFromState (Component* component, const ValueTree& state) = 0;
private:
//==============================================================================
friend class ComponentBuilder;
ComponentBuilder* builder;
const Identifier valueTreeType;
@@ -110,26 +150,37 @@ public:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TypeHandler);
};
/**
//==============================================================================
/** Adds a type handler that the builder can use when trying to load components.
@see Drawable::registerDrawableTypeHandlers()
*/
void registerTypeHandler (TypeHandler* type);
/**
*/
/** Tries to find a registered type handler that can load a component from the given ValueTree. */
TypeHandler* getHandlerForState (const ValueTree& state) const;
/**
/** Returns the number of registered type handlers.
@see getHandler, registerTypeHandler
*/
int getNumHandlers() const throw();
/**
/** Returns one of the registered type handlers.
@see getNumHandlers, registerTypeHandler
*/
TypeHandler* getHandler (int index) const throw();
//=============================================================================
/** This class is used when loading Drawables that contain images, and retrieves
the image for a stored identifier.
@see Drawable::createFromValueTree
/** This class is used when references to images need to be stored in ValueTrees.
An instance of an ImageProvider provides a mechanism for converting an Image to/from
a reference, which may be a file, URL, ID string, or whatever system is appropriate in
your app.
When you're loading components from a ValueTree that may need a way of loading images, you
should call ComponentBuilder::setImageProvider() to supply a suitable provider before
trying to load the component.
@see ComponentBuilder::setImageProvider()
*/
class JUCE_API ImageProvider
{
@@ -146,19 +197,35 @@ public:
virtual const Image getImageForIdentifier (const var& imageIdentifier) = 0;
/** Returns an identifier to be used to refer to a given image.
This is used when converting a drawable into a ValueTree, so if you're
only loading drawables, you can just return a var::null here.
This is used when a reference to an image is stored in a ValueTree.
*/
virtual const var getIdentifierForImage (const Image& image) = 0;
};
/** */
//==============================================================================
/** Gives the builder an ImageProvider object that the type handlers can use when
loading images from stored references.
The object that is passed in is not owned by the builder, so the caller must delete
it when it is no longer needed, but not while the builder may still be using it. To
clear the image provider, just call setImageProvider (0).
*/
void setImageProvider (ImageProvider* newImageProvider) throw();
/** */
/** Returns the current image provider that this builder is using, or 0 if none has been set. */
ImageProvider* getImageProvider() const throw();
//=============================================================================
/** Updates the children of a parent component by updating them from the children of
a given ValueTree.
*/
void updateChildComponents (Component& parent, const ValueTree& children);
/** An identifier for the property of the ValueTrees that is used to store a unique ID
for that component.
*/
static const Identifier idProperty;
/** @internal */
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
/** @internal */
@@ -166,22 +233,15 @@ public:
/** @internal */
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);
/**
*/
void updateChildComponents (Component& parent, const ValueTree& children);
/**
*/
static const Identifier idProperty;
private:
//=============================================================================
ValueTree state;
OwnedArray <TypeHandler> types;
ScopedPointer<Component> component;
ImageProvider* imageProvider;
void updateComponent (const ValueTree& state);
#if JUCE_DEBUG
WeakReference<Component> componentRef;
#endif
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentBuilder);
};


+ 262
- 0
src/gui/components/layout/juce_MarkerList.cpp View File

@@ -0,0 +1,262 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../../../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_MarkerList.h"
//==============================================================================
MarkerList::MarkerList()
{
}
MarkerList::MarkerList (const MarkerList& other)
{
operator= (other);
}
MarkerList& MarkerList::operator= (const MarkerList& other)
{
if (other != *this)
{
markers.clear();
markers.addCopiesOf (other.markers);
markersHaveChanged();
}
return *this;
}
MarkerList::~MarkerList()
{
}
bool MarkerList::operator== (const MarkerList& other) const throw()
{
if (other.markers.size() != markers.size())
return false;
for (int i = markers.size(); --i >= 0;)
{
const Marker* const m1 = markers.getUnchecked(i);
jassert (m1 != 0);
const Marker* const m2 = other.getMarker (m1->name);
if (m2 == 0 || *m1 != *m2)
return false;
}
return true;
}
bool MarkerList::operator!= (const MarkerList& other) const throw()
{
return ! operator== (other);
}
//==============================================================================
int MarkerList::getNumMarkers() const throw()
{
return markers.size();
}
const MarkerList::Marker* MarkerList::getMarker (const int index) const throw()
{
return markers [index];
}
const MarkerList::Marker* MarkerList::getMarker (const String& name) const throw()
{
for (int i = 0; i < markers.size(); ++i)
{
const Marker* const m = markers.getUnchecked(i);
if (m->name == name)
return m;
}
return 0;
}
void MarkerList::setMarker (const String& name, const RelativeCoordinate& position)
{
Marker* const m = const_cast <Marker*> (getMarker (name));
if (m != 0)
{
if (m->position != position)
{
m->position = position;
markersHaveChanged();
}
return;
}
markers.add (new Marker (name, position));
markersHaveChanged();
}
void MarkerList::removeMarker (const int index)
{
if (isPositiveAndBelow (index, markers.size()))
{
markers.remove (index);
markersHaveChanged();
}
}
void MarkerList::removeMarker (const String& name)
{
for (int i = 0; i < markers.size(); ++i)
{
const Marker* const m = markers.getUnchecked(i);
if (m->name == name)
{
markers.remove (i);
markersHaveChanged();
}
}
}
void MarkerList::markersHaveChanged()
{
sendChangeMessage();
}
//==============================================================================
MarkerList::Marker::Marker (const Marker& other)
: name (other.name), position (other.position)
{
}
MarkerList::Marker::Marker (const String& name_, const RelativeCoordinate& position_)
: name (name_), position (position_)
{
}
bool MarkerList::Marker::operator== (const Marker& other) const throw()
{
return name == other.name && position == other.position;
}
bool MarkerList::Marker::operator!= (const Marker& other) const throw()
{
return ! operator== (other);
}
//==============================================================================
const Identifier MarkerList::ValueTreeWrapper::markerTag ("Marker");
const Identifier MarkerList::ValueTreeWrapper::nameProperty ("name");
const Identifier MarkerList::ValueTreeWrapper::posProperty ("position");
MarkerList::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
: state (state_)
{
}
int MarkerList::ValueTreeWrapper::getNumMarkers() const
{
return state.getNumChildren();
}
const ValueTree MarkerList::ValueTreeWrapper::getMarkerState (int index) const
{
return state.getChild (index);
}
const ValueTree MarkerList::ValueTreeWrapper::getMarkerState (const String& name) const
{
return state.getChildWithProperty (nameProperty, name);
}
bool MarkerList::ValueTreeWrapper::containsMarker (const ValueTree& marker) const
{
return marker.isAChildOf (state);
}
const MarkerList::Marker MarkerList::ValueTreeWrapper::getMarker (const ValueTree& marker) const
{
jassert (containsMarker (marker));
return MarkerList::Marker (marker [nameProperty], RelativeCoordinate (marker [posProperty].toString()));
}
void MarkerList::ValueTreeWrapper::setMarker (const MarkerList::Marker& m, UndoManager* undoManager)
{
ValueTree marker (state.getChildWithProperty (nameProperty, m.name));
if (marker.isValid())
{
marker.setProperty (posProperty, m.position.toString(), undoManager);
}
else
{
marker = ValueTree (markerTag);
marker.setProperty (nameProperty, m.name, 0);
marker.setProperty (posProperty, m.position.toString(), 0);
state.addChild (marker, -1, undoManager);
}
}
void MarkerList::ValueTreeWrapper::removeMarker (const ValueTree& marker, UndoManager* undoManager)
{
state.removeChild (marker, undoManager);
}
void MarkerList::ValueTreeWrapper::applyTo (MarkerList& markerList)
{
const int numMarkers = getNumMarkers();
StringArray updatedMarkers;
int i;
for (i = 0; i < numMarkers; ++i)
{
const ValueTree marker (state.getChild (i));
const String name (marker [nameProperty].toString());
markerList.setMarker (name, RelativeCoordinate (marker [posProperty].toString()));
updatedMarkers.add (name);
}
for (i = markerList.getNumMarkers(); --i >= 0;)
if (! updatedMarkers.contains (markerList.getMarker (i)->name))
markerList.removeMarker (i);
}
void MarkerList::ValueTreeWrapper::readFrom (const MarkerList& markerList, UndoManager* undoManager)
{
state.removeAllChildren (undoManager);
for (int i = 0; i < markerList.getNumMarkers(); ++i)
setMarker (*markerList.getMarker(i), undoManager);
}
END_JUCE_NAMESPACE

+ 141
- 0
src/gui/components/layout/juce_MarkerList.h View File

@@ -0,0 +1,141 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_MARKERLIST_JUCEHEADER__
#define __JUCE_MARKERLIST_JUCEHEADER__
#include "../../../containers/juce_ValueTree.h"
#include "../../graphics/geometry/juce_RelativeCoordinate.h"
//==============================================================================
/**
Holds a set of named marker points along a one-dimensional axis.
This class is used to store sets of X and Y marker points in components.
@see Component::getMarkers().
The MarkerList is also a ChangeBroadcaster, so that listeners can register to receive
a callback when a marker is moved,
*/
class JUCE_API MarkerList : public ChangeBroadcaster
{
public:
//==============================================================================
/** Creates an empty marker list. */
MarkerList();
/** Creates a copy of another marker list. */
MarkerList (const MarkerList& other);
/** Copies another marker list to this one. */
MarkerList& operator= (const MarkerList& other);
/** Destructor. */
~MarkerList();
//==============================================================================
/** Represents a marker in a MarkerList. */
class JUCE_API Marker
{
public:
/** Creates a copy of another Marker. */
Marker (const Marker& other);
/** Creates a Marker with a given name and position. */
Marker (const String& name, const RelativeCoordinate& position);
/** The marker's name. */
String name;
/** The marker's position. */
RelativeCoordinate position;
/** Returns true if both the names and positions of these two markers match. */
bool operator== (const Marker&) const throw();
/** Returns true if either the name or position of these two markers differ. */
bool operator!= (const Marker&) const throw();
};
//==============================================================================
/** Returns the number of markers in the list. */
int getNumMarkers() const throw();
/** Returns one of the markers in the list, by its index. */
const Marker* getMarker (int index) const throw();
/** Returns a named marker, or 0 if no such name is found.
Note that name comparisons are case-sensitive.
*/
const Marker* getMarker (const String& name) const throw();
/** Sets the position of a marker.
If the name already exists, then the existing marker is moved; if it doesn't exist, then a
new marker is added.
*/
void setMarker (const String& name, const RelativeCoordinate& position);
/** Deletes the marker at the given list index. */
void removeMarker (int index);
/** Deletes the marker with the given name. */
void removeMarker (const String& name);
/** Returns true if all the markers in these two lists match exactly. */
bool operator== (const MarkerList& other) const throw();
/** Returns true if not all the markers in these two lists match exactly. */
bool operator!= (const MarkerList& other) const throw();
//==============================================================================
/** Forms a wrapper around a ValueTree that can be used for storing a MarkerList. */
class ValueTreeWrapper
{
public:
ValueTreeWrapper (const ValueTree& state);
int getNumMarkers() const;
const ValueTree getMarkerState (int index) const;
const ValueTree getMarkerState (const String& name) const;
bool containsMarker (const ValueTree& state) const;
const MarkerList::Marker getMarker (const ValueTree& state) const;
void setMarker (const MarkerList::Marker& marker, UndoManager* undoManager);
void removeMarker (const ValueTree& state, UndoManager* undoManager);
void applyTo (MarkerList& markerList);
void readFrom (const MarkerList& markerList, UndoManager* undoManager);
private:
ValueTree state;
static const Identifier markerTag, nameProperty, posProperty;
};
private:
//==============================================================================
OwnedArray<Marker> markers;
void markersHaveChanged();
JUCE_LEAK_DETECTOR (MarkerList);
};
#endif // __JUCE_MARKERLIST_JUCEHEADER__

+ 16
- 24
src/gui/graphics/drawables/juce_Drawable.cpp View File

@@ -95,10 +95,6 @@ void Drawable::transformContextToCorrectOrigin (Graphics& g)
originRelativeToComponent.getY());
}
void Drawable::markerHasMoved()
{
}
void Drawable::parentHierarchyChanged()
{
setBoundsToEnclose (getDrawableBounds());
@@ -175,21 +171,6 @@ Drawable* Drawable::createFromImageFile (const File& file)
return fin != 0 ? createFromImageDataStream (*fin) : 0;
}
//==============================================================================
Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider)
{
ComponentBuilder builder (tree);
builder.setImageProvider (imageProvider);
registerDrawableTypes (builder);
Drawable* d = dynamic_cast<Drawable*> (builder.getComponent());
if (d != 0)
return dynamic_cast<Drawable*> (builder.getAndReleaseComponent());
return 0;
}
//==============================================================================
template <class DrawableClass>
class DrawableTypeHandler : public ComponentBuilder::TypeHandler
@@ -219,7 +200,7 @@ public:
}
};
void Drawable::registerDrawableTypes (ComponentBuilder& builder)
void Drawable::registerDrawableTypeHandlers (ComponentBuilder& builder)
{
builder.registerTypeHandler (new DrawableTypeHandler <DrawablePath>());
builder.registerTypeHandler (new DrawableTypeHandler <DrawableComposite>());
@@ -228,13 +209,24 @@ void Drawable::registerDrawableTypes (ComponentBuilder& builder)
builder.registerTypeHandler (new DrawableTypeHandler <DrawableText>());
}
//==============================================================================
Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_)
: state (state_)
Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider)
{
ComponentBuilder builder (tree);
builder.setImageProvider (imageProvider);
registerDrawableTypeHandlers (builder);
ScopedPointer<Component> comp (builder.createComponent());
Drawable* const d = dynamic_cast<Drawable*> (static_cast <Component*> (comp));
if (d != 0)
comp.release();
return d;
}
Drawable::ValueTreeWrapperBase::~ValueTreeWrapperBase()
//==============================================================================
Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_)
: state (state_)
{
}


+ 7
- 5
src/gui/graphics/drawables/juce_Drawable.h View File

@@ -28,7 +28,6 @@
#include "../../components/juce_Component.h"
#include "../geometry/juce_RelativeCoordinate.h"
#include "../../../text/juce_XmlElement.h"
#include "../../../containers/juce_ValueTree.h"
#include "../../components/layout/juce_ComponentBuilder.h"
class DrawableComposite;
@@ -163,6 +162,7 @@ public:
If there are any images used within the drawable, you'll need to provide a valid
ImageProvider object that can be used to retrieve these images from whatever type
of identifier is used to represent them.
Internally, this uses a ComponentBuilder, and registerDrawableTypeHandlers().
*/
static Drawable* createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider);
@@ -185,7 +185,6 @@ public:
{
public:
ValueTreeWrapperBase (const ValueTree& state);
~ValueTreeWrapperBase();
ValueTree& getState() throw() { return state; }
@@ -195,7 +194,12 @@ public:
ValueTree state;
};
static void registerDrawableTypes (ComponentBuilder& componentBuilder);
//==============================================================================
/** Registers a set of ComponentBuilder::TypeHandler objects that can be used to
load all the different Drawable types from a saved state.
@see ComponentBuilder::registerTypeHandler()
*/
static void registerDrawableTypeHandlers (ComponentBuilder& componentBuilder);
protected:
//==============================================================================
@@ -205,8 +209,6 @@ protected:
/** @internal */
void transformContextToCorrectOrigin (Graphics& g);
/** @internal */
void markerHasMoved();
/** @internal */
void parentHierarchyChanged();
/** @internal */
void setBoundsToEnclose (const Rectangle<float>& area);


+ 41
- 196
src/gui/graphics/drawables/juce_DrawableComposite.cpp View File

@@ -43,6 +43,8 @@ DrawableComposite::DrawableComposite()
DrawableComposite::DrawableComposite (const DrawableComposite& other)
: bounds (other.bounds),
markersX (other.markersX),
markersY (other.markersY),
updateBoundsReentrant (false)
{
for (int i = 0; i < other.getNumChildComponents(); ++i)
@@ -52,9 +54,6 @@ DrawableComposite::DrawableComposite (const DrawableComposite& other)
if (d != 0)
addAndMakeVisible (d->createCopy());
}
markersX.addCopiesOf (other.markersX);
markersY.addCopiesOf (other.markersY);
}
DrawableComposite::~DrawableComposite()
@@ -79,32 +78,26 @@ const Rectangle<float> DrawableComposite::getDrawableBounds() const
return r;
}
void DrawableComposite::markerHasMoved()
MarkerList* DrawableComposite::getMarkers (bool xAxis)
{
for (int i = getNumChildComponents(); --i >= 0;)
{
Drawable* const d = dynamic_cast <Drawable*> (getChildComponent(i));
if (d != 0)
d->markerHasMoved();
}
return xAxis ? &markersX : &markersY;
}
const RelativeRectangle DrawableComposite::getContentArea() const
{
jassert (markersX.size() >= 2 && getMarker (true, 0)->name == contentLeftMarkerName && getMarker (true, 1)->name == contentRightMarkerName);
jassert (markersY.size() >= 2 && getMarker (false, 0)->name == contentTopMarkerName && getMarker (false, 1)->name == contentBottomMarkerName);
jassert (markersX.getNumMarkers() >= 2 && markersX.getMarker (0)->name == contentLeftMarkerName && markersX.getMarker (1)->name == contentRightMarkerName);
jassert (markersY.getNumMarkers() >= 2 && markersY.getMarker (0)->name == contentTopMarkerName && markersY.getMarker (1)->name == contentBottomMarkerName);
return RelativeRectangle (markersX.getUnchecked(0)->position, markersX.getUnchecked(1)->position,
markersY.getUnchecked(0)->position, markersY.getUnchecked(1)->position);
return RelativeRectangle (markersX.getMarker(0)->position, markersX.getMarker(1)->position,
markersY.getMarker(0)->position, markersY.getMarker(1)->position);
}
void DrawableComposite::setContentArea (const RelativeRectangle& newArea)
{
setMarker (contentLeftMarkerName, true, newArea.left);
setMarker (contentRightMarkerName, true, newArea.right);
setMarker (contentTopMarkerName, false, newArea.top);
setMarker (contentBottomMarkerName, false, newArea.bottom);
markersX.setMarker (contentLeftMarkerName, newArea.left);
markersX.setMarker (contentRightMarkerName, newArea.right);
markersY.setMarker (contentTopMarkerName, newArea.top);
markersY.setMarker (contentBottomMarkerName, newArea.bottom);
refreshTransformFromBounds();
}
@@ -219,81 +212,18 @@ const char* const DrawableComposite::contentRightMarkerName = "right";
const char* const DrawableComposite::contentTopMarkerName = "top";
const char* const DrawableComposite::contentBottomMarkerName = "bottom";
DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other)
: name (other.name), position (other.position)
{
}
DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_)
: name (name_), position (position_)
{
}
bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw()
{
return name != other.name || position != other.position;
}
int DrawableComposite::getNumMarkers (const bool xAxis) const throw()
{
return (xAxis ? markersX : markersY).size();
}
const DrawableComposite::Marker* DrawableComposite::getMarker (const bool xAxis, const int index) const throw()
{
return (xAxis ? markersX : markersY) [index];
}
void DrawableComposite::setMarker (const String& name, const bool xAxis, const RelativeCoordinate& position)
{
OwnedArray <Marker>& markers = (xAxis ? markersX : markersY);
for (int i = 0; i < markers.size(); ++i)
{
Marker* const m = markers.getUnchecked(i);
if (m->name == name)
{
if (m->position != position)
{
m->position = position;
markerHasMoved();
}
return;
}
}
(xAxis ? markersX : markersY).add (new Marker (name, position));
markerHasMoved();
}
void DrawableComposite::removeMarker (const bool xAxis, const int index)
{
jassert (index >= 2);
if (index >= 2)
(xAxis ? markersX : markersY).remove (index);
}
//==============================================================================
const Expression DrawableComposite::getSymbolValue (const String& symbol, const String& member) const
{
jassert (member.isEmpty()) // the only symbols available in a Drawable are markers.
int i;
for (i = 0; i < markersX.size(); ++i)
{
Marker* const m = markersX.getUnchecked(i);
if (m->name == symbol)
return m->position.getExpression();
}
const MarkerList::Marker* m = markersX.getMarker (symbol);
for (i = 0; i < markersY.size(); ++i)
{
Marker* const m = markersY.getUnchecked(i);
if (m->name == symbol)
return m->position.getExpression();
}
if (m == 0)
m = markersY.getMarker (symbol);
if (m != 0)
return m->position.getExpression();
throw Expression::EvaluationError (symbol, member);
}
@@ -312,9 +242,6 @@ const Identifier DrawableComposite::ValueTreeWrapper::bottomLeft ("bottomLeft");
const Identifier DrawableComposite::ValueTreeWrapper::childGroupTag ("Drawables");
const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagX ("MarkersX");
const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagY ("MarkersY");
const Identifier DrawableComposite::ValueTreeWrapper::markerTag ("Marker");
const Identifier DrawableComposite::ValueTreeWrapper::nameProperty ("name");
const Identifier DrawableComposite::ValueTreeWrapper::posProperty ("position");
//==============================================================================
DrawableComposite::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
@@ -358,85 +285,36 @@ void DrawableComposite::ValueTreeWrapper::resetBoundingBoxToContentArea (UndoMan
const RelativeRectangle DrawableComposite::ValueTreeWrapper::getContentArea() const
{
return RelativeRectangle (getMarker (true, getMarkerState (true, 0)).position,
getMarker (true, getMarkerState (true, 1)).position,
getMarker (false, getMarkerState (false, 0)).position,
getMarker (false, getMarkerState (false, 1)).position);
MarkerList::ValueTreeWrapper markersX (getMarkerList (true));
MarkerList::ValueTreeWrapper markersY (getMarkerList (false));
return RelativeRectangle (markersX.getMarker (markersX.getMarkerState (0)).position,
markersX.getMarker (markersX.getMarkerState (1)).position,
markersY.getMarker (markersY.getMarkerState (0)).position,
markersY.getMarker (markersY.getMarkerState (1)).position);
}
void DrawableComposite::ValueTreeWrapper::setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager)
{
setMarker (true, Marker (contentLeftMarkerName, newArea.left), undoManager);
setMarker (true, Marker (contentRightMarkerName, newArea.right), undoManager);
setMarker (false, Marker (contentTopMarkerName, newArea.top), undoManager);
setMarker (false, Marker (contentBottomMarkerName, newArea.bottom), undoManager);
MarkerList::ValueTreeWrapper markersX (getMarkerListCreating (true, 0));
MarkerList::ValueTreeWrapper markersY (getMarkerListCreating (false, 0));
markersX.setMarker (MarkerList::Marker (contentLeftMarkerName, newArea.left), undoManager);
markersX.setMarker (MarkerList::Marker (contentRightMarkerName, newArea.right), undoManager);
markersY.setMarker (MarkerList::Marker (contentTopMarkerName, newArea.top), undoManager);
markersY.setMarker (MarkerList::Marker (contentBottomMarkerName, newArea.bottom), undoManager);
}
ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const
MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const
{
return state.getChildWithName (xAxis ? markerGroupTagX : markerGroupTagY);
}
ValueTree DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager)
MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager)
{
return state.getOrCreateChildWithName (xAxis ? markerGroupTagX : markerGroupTagY, undoManager);
}
int DrawableComposite::ValueTreeWrapper::getNumMarkers (bool xAxis) const
{
return getMarkerList (xAxis).getNumChildren();
}
const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, int index) const
{
return getMarkerList (xAxis).getChild (index);
}
const ValueTree DrawableComposite::ValueTreeWrapper::getMarkerState (bool xAxis, const String& name) const
{
return getMarkerList (xAxis).getChildWithProperty (nameProperty, name);
}
bool DrawableComposite::ValueTreeWrapper::containsMarker (bool xAxis, const ValueTree& state) const
{
return state.isAChildOf (getMarkerList (xAxis));
}
const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (bool xAxis, const ValueTree& state) const
{
(void) xAxis;
jassert (containsMarker (xAxis, state));
return Marker (state [nameProperty], RelativeCoordinate (state [posProperty].toString()));
}
void DrawableComposite::ValueTreeWrapper::setMarker (bool xAxis, const Marker& m, UndoManager* undoManager)
{
ValueTree markerList (getMarkerListCreating (xAxis, undoManager));
ValueTree marker (markerList.getChildWithProperty (nameProperty, m.name));
if (marker.isValid())
{
marker.setProperty (posProperty, m.position.toString(), undoManager);
}
else
{
marker = ValueTree (markerTag);
marker.setProperty (nameProperty, m.name, 0);
marker.setProperty (posProperty, m.position.toString(), 0);
markerList.addChild (marker, -1, undoManager);
}
}
void DrawableComposite::ValueTreeWrapper::removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager)
{
if (state [nameProperty].toString() != contentLeftMarkerName
&& state [nameProperty].toString() != contentRightMarkerName
&& state [nameProperty].toString() != contentTopMarkerName
&& state [nameProperty].toString() != contentBottomMarkerName)
getMarkerList (xAxis).removeChild (state, undoManager);
}
//==============================================================================
void DrawableComposite::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder)
{
@@ -447,39 +325,8 @@ void DrawableComposite::refreshFromValueTree (const ValueTree& tree, ComponentBu
if (bounds != newBounds)
bounds = newBounds;
const int numMarkersX = wrapper.getNumMarkers (true);
const int numMarkersY = wrapper.getNumMarkers (false);
// Remove deleted markers...
if (markersX.size() > numMarkersX || markersY.size() > numMarkersY)
{
markersX.removeRange (jmax (2, numMarkersX), markersX.size());
markersY.removeRange (jmax (2, numMarkersY), markersY.size());
}
// Update markers and add new ones..
int i;
for (i = 0; i < numMarkersX; ++i)
{
const Marker newMarker (wrapper.getMarker (true, wrapper.getMarkerState (true, i)));
Marker* m = markersX[i];
if (m == 0)
markersX.add (new Marker (newMarker));
else if (newMarker != *m)
*m = newMarker;
}
for (i = 0; i < numMarkersY; ++i)
{
const Marker newMarker (wrapper.getMarker (false, wrapper.getMarkerState (false, i)));
Marker* m = markersY[i];
if (m == 0)
markersY.add (new Marker (newMarker));
else if (newMarker != *m)
*m = newMarker;
}
wrapper.getMarkerList (true).applyTo (markersX);
wrapper.getMarkerList (false).applyTo (markersY);
builder.updateChildComponents (*this, wrapper.getChildList());
@@ -496,18 +343,16 @@ const ValueTree DrawableComposite::createValueTree (ComponentBuilder::ImageProvi
ValueTree childList (v.getChildListCreating (0));
int i;
for (i = getNumChildComponents(); --i >= 0;)
for (int i = getNumChildComponents(); --i >= 0;)
{
const Drawable* const d = dynamic_cast <const Drawable*> (getChildComponent(i));
jassert (d != 0); // You can't save a mix of Drawables and normal components!
childList.addChild (d->createValueTree (imageProvider), -1, 0);
}
for (i = 0; i < markersX.size(); ++i)
v.setMarker (true, *markersX.getUnchecked(i), 0);
for (i = 0; i < markersY.size(); ++i)
v.setMarker (false, *markersY.getUnchecked(i), 0);
v.getMarkerListCreating (true, 0).readFrom (markersX, 0);
v.getMarkerListCreating (false, 0).readFrom (markersY, 0);
return tree;
}


+ 8
- 33
src/gui/graphics/drawables/juce_DrawableComposite.h View File

@@ -27,6 +27,7 @@
#define __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__
#include "juce_Drawable.h"
#include "../../components/layout/juce_MarkerList.h"
//==============================================================================
@@ -85,24 +86,6 @@ public:
void resetContentAreaAndBoundingBoxToFitChildren();
//==============================================================================
/** Represents a named marker position.
@see DrawableComposite::getMarker
*/
struct Marker
{
Marker (const Marker&);
Marker (const String& name, const RelativeCoordinate& position);
bool operator!= (const Marker&) const throw();
String name;
RelativeCoordinate position;
};
int getNumMarkers (bool xAxis) const throw();
const Marker* getMarker (bool xAxis, int index) const throw();
void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position);
void removeMarker (bool xAxis, int index);
/** The name of the marker that defines the left edge of the content area. */
static const char* const contentLeftMarkerName;
/** The name of the marker that defines the right edge of the content area. */
@@ -126,13 +109,13 @@ public:
/** @internal */
const Rectangle<float> getDrawableBounds() const;
/** @internal */
void markerHasMoved();
/** @internal */
void childBoundsChanged (Component*);
/** @internal */
void childrenChanged();
/** @internal */
void parentHierarchyChanged();
/** @internal */
MarkerList* getMarkers (bool xAxis);
//==============================================================================
/** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */
@@ -151,27 +134,19 @@ public:
const RelativeRectangle getContentArea() const;
void setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager);
int getNumMarkers (bool xAxis) const;
const ValueTree getMarkerState (bool xAxis, int index) const;
const ValueTree getMarkerState (bool xAxis, const String& name) const;
bool containsMarker (bool xAxis, const ValueTree& state) const;
const Marker getMarker (bool xAxis, const ValueTree& state) const;
void setMarker (bool xAxis, const Marker& marker, UndoManager* undoManager);
void removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager);
MarkerList::ValueTreeWrapper getMarkerList (bool xAxis) const;
MarkerList::ValueTreeWrapper getMarkerListCreating (bool xAxis, UndoManager* undoManager);
static const Identifier nameProperty, posProperty, topLeft, topRight, bottomLeft;
static const Identifier topLeft, topRight, bottomLeft;
private:
static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY, markerTag;
ValueTree getMarkerList (bool xAxis) const;
ValueTree getMarkerListCreating (bool xAxis, UndoManager* undoManager);
static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY;
};
private:
//==============================================================================
RelativeParallelogram bounds;
OwnedArray <Marker> markersX, markersY;
MarkerList markersX, markersY;
bool updateBoundsReentrant;
void refreshTransformFromBounds();


+ 3
- 0
src/juce_app_includes.h View File

@@ -437,6 +437,9 @@
#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__
#include "gui/components/layout/juce_GroupComponent.h"
#endif
#ifndef __JUCE_MARKERLIST_JUCEHEADER__
#include "gui/components/layout/juce_MarkerList.h"
#endif
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
#include "gui/components/layout/juce_MultiDocumentPanel.h"
#endif


+ 2
- 2
src/native/mac/juce_mac_NativeIncludes.h View File

@@ -65,8 +65,8 @@
#import <IOKit/hid/IOHIDKeys.h>
#import <IOKit/pwr_mgt/IOPMLib.h>
#endif
#if JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \
&& ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
#if (JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU)) \
|| ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
#include <Carbon/Carbon.h>
#endif
#include <sys/dir.h>


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

@@ -2003,11 +2003,10 @@ private:
return 0;
case WM_NCPAINT:
if (wParam != 1)
handlePaintMessage();
if (hasTitleBar())
break;
else if (wParam != 1)
handlePaintMessage();
return 0;


Loading…
Cancel
Save