diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 283fd2b3dd..1904f94134 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -243,6 +243,8 @@ OBJECTS := \ $(OBJDIR)/juce_DrawableComposite_4cd2d2ab.o \ $(OBJDIR)/juce_DrawableImage_53f04eff.o \ $(OBJDIR)/juce_DrawablePath_fb538a0b.o \ + $(OBJDIR)/juce_DrawableRectangle_5f2f5993.o \ + $(OBJDIR)/juce_DrawableShape_26926245.o \ $(OBJDIR)/juce_DrawableText_75eda713.o \ $(OBJDIR)/juce_SVGParser_b79416c5.o \ $(OBJDIR)/juce_DropShadowEffect_da52d75.o \ @@ -1382,6 +1384,16 @@ $(OBJDIR)/juce_DrawablePath_fb538a0b.o: ../../src/gui/graphics/drawables/juce_Dr @echo "Compiling juce_DrawablePath.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_DrawableRectangle_5f2f5993.o: ../../src/gui/graphics/drawables/juce_DrawableRectangle.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling juce_DrawableRectangle.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/juce_DrawableShape_26926245.o: ../../src/gui/graphics/drawables/juce_DrawableShape.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling juce_DrawableShape.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_DrawableText_75eda713.o: ../../src/gui/graphics/drawables/juce_DrawableText.cpp -@mkdir -p $(OBJDIR) @echo "Compiling juce_DrawableText.cpp" diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj index 5ea7c32cee..dd4191b63d 100644 --- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj @@ -212,6 +212,8 @@ 00FE118356919D0BA97AE853 = { isa = PBXBuildFile; fileRef = 85B7BCACB40E02815844F71D; }; 18D8A96CCD34E41A5E162AD5 = { isa = PBXBuildFile; fileRef = A54BC72C899A2AF82E1E37F8; }; CEB8A9B9A37EBBA79A6478D4 = { isa = PBXBuildFile; fileRef = 582DCC2F948F1DEA0D450B0D; }; + D6D48B2CC53FAE2BD126B0DE = { isa = PBXBuildFile; fileRef = E0694CD7C814AA99E5A84799; }; + C384A89F786FDE8426F657D5 = { isa = PBXBuildFile; fileRef = 62967D33232C5A86D88084B4; }; 3D324F656EEF8F1FB2B437AC = { isa = PBXBuildFile; fileRef = C17613C202D8E1C366F21D3C; }; 645AF66C048A4815F5A8ECDD = { isa = PBXBuildFile; fileRef = 2BFC199D03DEEC329D6A7CB1; }; 38EFE824E76B3BB99824C265 = { isa = PBXBuildFile; fileRef = 32EA297812F1C88B42099501; }; @@ -820,6 +822,10 @@ 849E645981CA10B8D5576462 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableImage.h; path = ../../src/gui/graphics/drawables/juce_DrawableImage.h; sourceTree = SOURCE_ROOT; }; 582DCC2F948F1DEA0D450B0D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawablePath.cpp; path = ../../src/gui/graphics/drawables/juce_DrawablePath.cpp; sourceTree = SOURCE_ROOT; }; 17EBDF689C731DA257B243C9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawablePath.h; path = ../../src/gui/graphics/drawables/juce_DrawablePath.h; sourceTree = SOURCE_ROOT; }; + E0694CD7C814AA99E5A84799 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawableRectangle.cpp; path = ../../src/gui/graphics/drawables/juce_DrawableRectangle.cpp; sourceTree = SOURCE_ROOT; }; + 0FA9E378EBD7EE63EF72124F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableRectangle.h; path = ../../src/gui/graphics/drawables/juce_DrawableRectangle.h; sourceTree = SOURCE_ROOT; }; + 62967D33232C5A86D88084B4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawableShape.cpp; path = ../../src/gui/graphics/drawables/juce_DrawableShape.cpp; sourceTree = SOURCE_ROOT; }; + 2FBD6F49349E7CC8FC2051EA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableShape.h; path = ../../src/gui/graphics/drawables/juce_DrawableShape.h; sourceTree = SOURCE_ROOT; }; C17613C202D8E1C366F21D3C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawableText.cpp; path = ../../src/gui/graphics/drawables/juce_DrawableText.cpp; sourceTree = SOURCE_ROOT; }; 1FA43B2E4244CD74B551DAD6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableText.h; path = ../../src/gui/graphics/drawables/juce_DrawableText.h; sourceTree = SOURCE_ROOT; }; 2BFC199D03DEEC329D6A7CB1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_SVGParser.cpp; path = ../../src/gui/graphics/drawables/juce_SVGParser.cpp; sourceTree = SOURCE_ROOT; }; @@ -1574,6 +1580,10 @@ 849E645981CA10B8D5576462, 582DCC2F948F1DEA0D450B0D, 17EBDF689C731DA257B243C9, + E0694CD7C814AA99E5A84799, + 0FA9E378EBD7EE63EF72124F, + 62967D33232C5A86D88084B4, + 2FBD6F49349E7CC8FC2051EA, C17613C202D8E1C366F21D3C, 1FA43B2E4244CD74B551DAD6, 2BFC199D03DEEC329D6A7CB1 ); name = drawables; sourceTree = ""; }; @@ -2127,6 +2137,8 @@ 00FE118356919D0BA97AE853, 18D8A96CCD34E41A5E162AD5, CEB8A9B9A37EBBA79A6478D4, + D6D48B2CC53FAE2BD126B0DE, + C384A89F786FDE8426F657D5, 3D324F656EEF8F1FB2B437AC, 645AF66C048A4815F5A8ECDD, 38EFE824E76B3BB99824C265, diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj index 1ca5b09e79..7b88684445 100644 --- a/Builds/VisualStudio2005/Juce.vcproj +++ b/Builds/VisualStudio2005/Juce.vcproj @@ -723,6 +723,10 @@ + + + + diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj index 886507abbd..334d3ddc7d 100644 --- a/Builds/VisualStudio2008/Juce.vcproj +++ b/Builds/VisualStudio2008/Juce.vcproj @@ -723,6 +723,10 @@ + + + + diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj index 5659a40516..55231b21f9 100644 --- a/Builds/VisualStudio2008_DLL/Juce.vcproj +++ b/Builds/VisualStudio2008_DLL/Juce.vcproj @@ -725,6 +725,10 @@ + + + + diff --git a/Builds/VisualStudio2010/Juce.vcxproj b/Builds/VisualStudio2010/Juce.vcxproj index d42dc99c6e..222f58c788 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj +++ b/Builds/VisualStudio2010/Juce.vcxproj @@ -326,6 +326,8 @@ + + @@ -692,6 +694,8 @@ + + diff --git a/Builds/VisualStudio2010/Juce.vcxproj.filters b/Builds/VisualStudio2010/Juce.vcxproj.filters index 63958eeb1c..4a9ad74e3c 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj.filters +++ b/Builds/VisualStudio2010/Juce.vcxproj.filters @@ -826,6 +826,12 @@ Juce\Source\gui\graphics\drawables + + Juce\Source\gui\graphics\drawables + + + Juce\Source\gui\graphics\drawables + Juce\Source\gui\graphics\drawables @@ -1998,6 +2004,12 @@ Juce\Source\gui\graphics\drawables + + Juce\Source\gui\graphics\drawables + + + Juce\Source\gui\graphics\drawables + Juce\Source\gui\graphics\drawables diff --git a/Builds/iPhone/Juce.xcodeproj/project.pbxproj b/Builds/iPhone/Juce.xcodeproj/project.pbxproj index 4071854ac5..4dc698cd98 100644 --- a/Builds/iPhone/Juce.xcodeproj/project.pbxproj +++ b/Builds/iPhone/Juce.xcodeproj/project.pbxproj @@ -212,6 +212,8 @@ 00FE118356919D0BA97AE853 = { isa = PBXBuildFile; fileRef = 85B7BCACB40E02815844F71D; }; 18D8A96CCD34E41A5E162AD5 = { isa = PBXBuildFile; fileRef = A54BC72C899A2AF82E1E37F8; }; CEB8A9B9A37EBBA79A6478D4 = { isa = PBXBuildFile; fileRef = 582DCC2F948F1DEA0D450B0D; }; + D6D48B2CC53FAE2BD126B0DE = { isa = PBXBuildFile; fileRef = E0694CD7C814AA99E5A84799; }; + C384A89F786FDE8426F657D5 = { isa = PBXBuildFile; fileRef = 62967D33232C5A86D88084B4; }; 3D324F656EEF8F1FB2B437AC = { isa = PBXBuildFile; fileRef = C17613C202D8E1C366F21D3C; }; 645AF66C048A4815F5A8ECDD = { isa = PBXBuildFile; fileRef = 2BFC199D03DEEC329D6A7CB1; }; 38EFE824E76B3BB99824C265 = { isa = PBXBuildFile; fileRef = 32EA297812F1C88B42099501; }; @@ -820,6 +822,10 @@ 849E645981CA10B8D5576462 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableImage.h; path = ../../src/gui/graphics/drawables/juce_DrawableImage.h; sourceTree = SOURCE_ROOT; }; 582DCC2F948F1DEA0D450B0D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawablePath.cpp; path = ../../src/gui/graphics/drawables/juce_DrawablePath.cpp; sourceTree = SOURCE_ROOT; }; 17EBDF689C731DA257B243C9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawablePath.h; path = ../../src/gui/graphics/drawables/juce_DrawablePath.h; sourceTree = SOURCE_ROOT; }; + E0694CD7C814AA99E5A84799 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawableRectangle.cpp; path = ../../src/gui/graphics/drawables/juce_DrawableRectangle.cpp; sourceTree = SOURCE_ROOT; }; + 0FA9E378EBD7EE63EF72124F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableRectangle.h; path = ../../src/gui/graphics/drawables/juce_DrawableRectangle.h; sourceTree = SOURCE_ROOT; }; + 62967D33232C5A86D88084B4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawableShape.cpp; path = ../../src/gui/graphics/drawables/juce_DrawableShape.cpp; sourceTree = SOURCE_ROOT; }; + 2FBD6F49349E7CC8FC2051EA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableShape.h; path = ../../src/gui/graphics/drawables/juce_DrawableShape.h; sourceTree = SOURCE_ROOT; }; C17613C202D8E1C366F21D3C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DrawableText.cpp; path = ../../src/gui/graphics/drawables/juce_DrawableText.cpp; sourceTree = SOURCE_ROOT; }; 1FA43B2E4244CD74B551DAD6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DrawableText.h; path = ../../src/gui/graphics/drawables/juce_DrawableText.h; sourceTree = SOURCE_ROOT; }; 2BFC199D03DEEC329D6A7CB1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_SVGParser.cpp; path = ../../src/gui/graphics/drawables/juce_SVGParser.cpp; sourceTree = SOURCE_ROOT; }; @@ -1574,6 +1580,10 @@ 849E645981CA10B8D5576462, 582DCC2F948F1DEA0D450B0D, 17EBDF689C731DA257B243C9, + E0694CD7C814AA99E5A84799, + 0FA9E378EBD7EE63EF72124F, + 62967D33232C5A86D88084B4, + 2FBD6F49349E7CC8FC2051EA, C17613C202D8E1C366F21D3C, 1FA43B2E4244CD74B551DAD6, 2BFC199D03DEEC329D6A7CB1 ); name = drawables; sourceTree = ""; }; @@ -2127,6 +2137,8 @@ 00FE118356919D0BA97AE853, 18D8A96CCD34E41A5E162AD5, CEB8A9B9A37EBBA79A6478D4, + D6D48B2CC53FAE2BD126B0DE, + C384A89F786FDE8426F657D5, 3D324F656EEF8F1FB2B437AC, 645AF66C048A4815F5A8ECDD, 38EFE824E76B3BB99824C265, diff --git a/Juce.jucer b/Juce.jucer index 0411f10826..68122c0634 100644 --- a/Juce.jucer +++ b/Juce.jucer @@ -1057,6 +1057,14 @@ file="src/gui/graphics/drawables/juce_DrawablePath.cpp"/> + + + + = 0;) + { + if (mainWindows.getUnchecked(j)->getProject() != 0 + && mainWindows.getUnchecked(j)->getProject()->getFile() == file) + { + mainWindows.getUnchecked(j)->toFront (true); + return true; + } + } + if (file.hasFileExtension (Project::projectFileExtension)) { ScopedPointer newDoc (new Project (file)); diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 3cecd5cbcd..c24b464832 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -700,7 +700,7 @@ public: ComBaseClassHelper() : refCount (1) {} virtual ~ComBaseClassHelper() {} - HRESULT __stdcall QueryInterface (REFIID refId, void __RPC_FAR* __RPC_FAR* result) + HRESULT __stdcall QueryInterface (REFIID refId, void** result) { #ifndef __MINGW32__ if (refId == __uuidof (ComClass)) { AddRef(); *result = dynamic_cast (this); return S_OK; } @@ -2232,7 +2232,7 @@ BEGIN_JUCE_NAMESPACE static bool juceInitialisedNonGUI = false; -void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() +JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() { if (! juceInitialisedNonGUI) { @@ -2258,7 +2258,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() static_jassert (sizeof (uint64) == 8); } -void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI() +JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() { if (juceInitialisedNonGUI) { @@ -2285,7 +2285,7 @@ void juce_setCurrentThreadName (const String& name); static bool juceInitialisedGUI = false; -void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI() +JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI() { if (! juceInitialisedGUI) { @@ -2318,7 +2318,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI() } } -void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI() +JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI() { if (juceInitialisedGUI) { @@ -12147,52 +12147,52 @@ int64 String::hashCode64() const throw() return result; } -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const String& string2) throw() +JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const String& string2) throw() { return string1.compare (string2) == 0; } -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const char* string2) throw() +JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const char* string2) throw() { return string1.compare (string2) == 0; } -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const juce_wchar* string2) throw() +JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const juce_wchar* string2) throw() { return string1.compare (string2) == 0; } -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const String& string2) throw() +JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const String& string2) throw() { return string1.compare (string2) != 0; } -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const char* string2) throw() +JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const char* string2) throw() { return string1.compare (string2) != 0; } -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const juce_wchar* string2) throw() +JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const juce_wchar* string2) throw() { return string1.compare (string2) != 0; } -bool JUCE_PUBLIC_FUNCTION operator> (const String& string1, const String& string2) throw() +JUCE_API bool JUCE_CALLTYPE operator> (const String& string1, const String& string2) throw() { return string1.compare (string2) > 0; } -bool JUCE_PUBLIC_FUNCTION operator< (const String& string1, const String& string2) throw() +JUCE_API bool JUCE_CALLTYPE operator< (const String& string1, const String& string2) throw() { return string1.compare (string2) < 0; } -bool JUCE_PUBLIC_FUNCTION operator>= (const String& string1, const String& string2) throw() +JUCE_API bool JUCE_CALLTYPE operator>= (const String& string1, const String& string2) throw() { return string1.compare (string2) >= 0; } -bool JUCE_PUBLIC_FUNCTION operator<= (const String& string1, const String& string2) throw() +JUCE_API bool JUCE_CALLTYPE operator<= (const String& string1, const String& string2) throw() { return string1.compare (string2) <= 0; } @@ -12309,114 +12309,114 @@ void String::append (const juce_wchar* const other, const int howMany) } } -const String JUCE_PUBLIC_FUNCTION operator+ (const char* const string1, const String& string2) +JUCE_API const String JUCE_CALLTYPE operator+ (const char* const string1, const String& string2) { String s (string1); return s += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar* const string1, const String& string2) +JUCE_API const String JUCE_CALLTYPE operator+ (const juce_wchar* const string1, const String& string2) { String s (string1); return s += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (const char string1, const String& string2) +JUCE_API const String JUCE_CALLTYPE operator+ (const char string1, const String& string2) { return String::charToString (string1) + string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar string1, const String& string2) +JUCE_API const String JUCE_CALLTYPE operator+ (const juce_wchar string1, const String& string2) { return String::charToString (string1) + string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const String& string2) +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const String& string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const char* const string2) +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const char* const string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const juce_wchar* const string2) +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar* const string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const char string2) +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const char string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const juce_wchar string2) +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char characterToAppend) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char characterToAppend) { return string1 += characterToAppend; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const juce_wchar characterToAppend) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const juce_wchar characterToAppend) { return string1 += characterToAppend; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char* const string2) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char* const string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const juce_wchar* const string2) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const juce_wchar* const string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const String& string2) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const String& string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const short number) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const short number) { return string1 += (int) number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const int number) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const int number) { return string1 += number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const unsigned int number) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const unsigned int number) { return string1 += number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const long number) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const long number) { return string1 += (int) number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const unsigned long number) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const unsigned long number) { return string1 += (unsigned int) number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const float number) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const float number) { return string1 += String (number); } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const double number) +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const double number) { return string1 += String (number); } -OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text) +JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text) { // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind // if lots of large, persistent strings were to be written to streams). @@ -19394,14 +19394,12 @@ bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::Invocati // manager first.. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - ApplicationCommandTarget* const target = getFirstCommandTarget (info_.commandID); + ApplicationCommandInfo commandInfo (0); + ApplicationCommandTarget* const target = getTargetForCommand (info_.commandID, commandInfo); if (target == 0) return false; - ApplicationCommandInfo commandInfo (0); - target->getCommandInfo (info_.commandID, commandInfo); - ApplicationCommandTarget::InvocationInfo info (info_); info.commandFlags = commandInfo.flags; @@ -30875,35 +30873,38 @@ bool PluginDirectoryScanner::scanNextFile (const bool dontRescanIfAlreadyInList) { String file (filesOrIdentifiersToScan [nextIndex]); - if (file.isNotEmpty()) + if (file.isNotEmpty() && ! list.isListingUpToDate (file)) { - if (! list.isListingUpToDate (file)) - { - OwnedArray typesFound; + OwnedArray typesFound; - // Add this plugin to the end of the dead-man's pedal list in case it crashes... - StringArray crashedPlugins (getDeadMansPedalFile()); - crashedPlugins.removeString (file); - crashedPlugins.add (file); - setDeadMansPedalFile (crashedPlugins); + // Add this plugin to the end of the dead-man's pedal list in case it crashes... + StringArray crashedPlugins (getDeadMansPedalFile()); + crashedPlugins.removeString (file); + crashedPlugins.add (file); + setDeadMansPedalFile (crashedPlugins); - list.scanAndAddFile (file, - dontRescanIfAlreadyInList, - typesFound, - format); + list.scanAndAddFile (file, + dontRescanIfAlreadyInList, + typesFound, + format); - // Managed to load without crashing, so remove it from the dead-man's-pedal.. - crashedPlugins.removeString (file); - setDeadMansPedalFile (crashedPlugins); + // Managed to load without crashing, so remove it from the dead-man's-pedal.. + crashedPlugins.removeString (file); + setDeadMansPedalFile (crashedPlugins); - if (typesFound.size() == 0) - failedFiles.add (file); - } - - ++nextIndex; - progress = nextIndex / (float) filesOrIdentifiersToScan.size(); + if (typesFound.size() == 0) + failedFiles.add (file); } + return skipNextFile(); +} + +bool PluginDirectoryScanner::skipNextFile() +{ + if (nextIndex >= filesOrIdentifiersToScan.size()) + return false; + + progress = ++nextIndex / (float) filesOrIdentifiersToScan.size(); return nextIndex < filesOrIdentifiersToScan.size(); } @@ -80519,6 +80520,11 @@ RelativeParallelogram::RelativeParallelogram() { } +RelativeParallelogram::RelativeParallelogram (const Rectangle& r) + : topLeft (r.getTopLeft()), topRight (r.getTopRight()), bottomLeft (r.getBottomLeft()) +{ +} + RelativeParallelogram::RelativeParallelogram (const RelativePoint& topLeft_, const RelativePoint& topRight_, const RelativePoint& bottomLeft_) : topLeft (topLeft_), topRight (topRight_), bottomLeft (bottomLeft_) { @@ -86101,6 +86107,8 @@ Drawable* Drawable::createChildFromValueTree (DrawableComposite* parent, const V d = new DrawablePath(); else if (type == DrawableComposite::valueTreeType) d = new DrawableComposite(); + else if (type == DrawableRectangle::valueTreeType) + d = new DrawableRectangle(); else if (type == DrawableImage::valueTreeType) d = new DrawableImage(); else if (type == DrawableText::valueTreeType) @@ -86116,15 +86124,6 @@ Drawable* Drawable::createChildFromValueTree (DrawableComposite* parent, const V } const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id"); -const Identifier Drawable::ValueTreeWrapperBase::type ("type"); -const Identifier Drawable::ValueTreeWrapperBase::gradientPoint1 ("point1"); -const Identifier Drawable::ValueTreeWrapperBase::gradientPoint2 ("point2"); -const Identifier Drawable::ValueTreeWrapperBase::gradientPoint3 ("point3"); -const Identifier Drawable::ValueTreeWrapperBase::colour ("colour"); -const Identifier Drawable::ValueTreeWrapperBase::radial ("radial"); -const Identifier Drawable::ValueTreeWrapperBase::colours ("colours"); -const Identifier Drawable::ValueTreeWrapperBase::imageId ("imageId"); -const Identifier Drawable::ValueTreeWrapperBase::imageOpacity ("imageOpacity"); Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_) : state (state_) @@ -86148,8 +86147,268 @@ void Drawable::ValueTreeWrapperBase::setID (const String& newID, UndoManager* co state.setProperty (idProperty, newID, undoManager); } -const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v, RelativePoint* const gp1, RelativePoint* const gp2, RelativePoint* const gp3, - Expression::EvaluationContext* const nameFinder, ImageProvider* imageProvider) +END_JUCE_NAMESPACE +/*** End of inlined file: juce_Drawable.cpp ***/ + + +/*** Start of inlined file: juce_DrawableShape.cpp ***/ +BEGIN_JUCE_NAMESPACE + +DrawableShape::DrawableShape() + : strokeType (0.0f), + mainFill (Colours::black), + strokeFill (Colours::black), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) +{ +} + +DrawableShape::DrawableShape (const DrawableShape& other) + : strokeType (other.strokeType), + mainFill (other.mainFill), + strokeFill (other.strokeFill), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) +{ +} + +DrawableShape::~DrawableShape() +{ +} + +void DrawableShape::setFill (const FillType& newFill) +{ + mainFill = newFill; +} + +void DrawableShape::setStrokeFill (const FillType& newFill) +{ + strokeFill = newFill; +} + +void DrawableShape::setStrokeType (const PathStrokeType& newStrokeType) +{ + strokeType = newStrokeType; + strokeNeedsUpdating = true; +} + +void DrawableShape::setStrokeThickness (const float newThickness) +{ + setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); +} + +bool DrawableShape::isStrokeVisible() const throw() +{ + return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); +} + +void DrawableShape::setBrush (const Drawable::RenderingContext& context, const FillType& type) +{ + FillType f (type); + if (f.isGradient()) + f.gradient->multiplyOpacity (context.opacity); + else + f.setOpacity (f.getOpacity() * context.opacity); + + f.transform = f.transform.followedBy (context.transform); + context.g.setFillType (f); +} + +bool DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, + Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) +{ + bool hasChanged = false; + + { + const FillType f (newState.getMainFill (parent, imageProvider)); + + if (mainFill != f) + { + hasChanged = true; + mainFill = f; + } + } + + { + const FillType f (newState.getStrokeFill (parent, imageProvider)); + + if (strokeFill != f) + { + hasChanged = true; + strokeFill = f; + } + } + + return hasChanged; +} + +void DrawableShape::writeTo (FillAndStrokeState& state, ImageProvider* imageProvider, UndoManager* undoManager) const +{ + state.setMainFill (mainFill, 0, 0, 0, imageProvider, undoManager); + state.setStrokeFill (strokeFill, 0, 0, 0, imageProvider, undoManager); + state.setStrokeType (strokeType, undoManager); +} + +void DrawableShape::render (const Drawable::RenderingContext& context) const +{ + setBrush (context, mainFill); + context.g.fillPath (getCachedPath(), context.transform); + + if (isStrokeVisible()) + { + setBrush (context, strokeFill); + context.g.fillPath (getCachedStrokePath(), context.transform); + } +} + +void DrawableShape::pathChanged() +{ + pathNeedsUpdating = true; +} + +void DrawableShape::strokeChanged() +{ + strokeNeedsUpdating = true; +} + +void DrawableShape::invalidatePoints() +{ + pathNeedsUpdating = true; + strokeNeedsUpdating = true; +} + +const Path& DrawableShape::getCachedPath() const +{ + if (pathNeedsUpdating) + { + pathNeedsUpdating = false; + + if (rebuildPath (cachedPath)) + strokeNeedsUpdating = true; + } + + return cachedPath; +} + +const Path& DrawableShape::getCachedStrokePath() const +{ + if (strokeNeedsUpdating) + { + cachedStroke.clear(); + strokeType.createStrokedPath (cachedStroke, getCachedPath(), AffineTransform::identity, 4.0f); + strokeNeedsUpdating = false; // (must be called after getCachedPath) + } + + return cachedStroke; +} + +const Rectangle DrawableShape::getBounds() const +{ + if (isStrokeVisible()) + return getCachedStrokePath().getBounds(); + else + return getCachedPath().getBounds(); +} + +bool DrawableShape::hitTest (float x, float y) const +{ + return getCachedPath().contains (x, y) + || (isStrokeVisible() && getCachedStrokePath().contains (x, y)); +} + +const Identifier DrawableShape::FillAndStrokeState::type ("type"); +const Identifier DrawableShape::FillAndStrokeState::colour ("colour"); +const Identifier DrawableShape::FillAndStrokeState::colours ("colours"); +const Identifier DrawableShape::FillAndStrokeState::fill ("Fill"); +const Identifier DrawableShape::FillAndStrokeState::stroke ("Stroke"); +const Identifier DrawableShape::FillAndStrokeState::path ("Path"); +const Identifier DrawableShape::FillAndStrokeState::jointStyle ("jointStyle"); +const Identifier DrawableShape::FillAndStrokeState::capStyle ("capStyle"); +const Identifier DrawableShape::FillAndStrokeState::strokeWidth ("strokeWidth"); +const Identifier DrawableShape::FillAndStrokeState::gradientPoint1 ("point1"); +const Identifier DrawableShape::FillAndStrokeState::gradientPoint2 ("point2"); +const Identifier DrawableShape::FillAndStrokeState::gradientPoint3 ("point3"); +const Identifier DrawableShape::FillAndStrokeState::radial ("radial"); +const Identifier DrawableShape::FillAndStrokeState::imageId ("imageId"); +const Identifier DrawableShape::FillAndStrokeState::imageOpacity ("imageOpacity"); + +DrawableShape::FillAndStrokeState::FillAndStrokeState (const ValueTree& state_) + : Drawable::ValueTreeWrapperBase (state_) +{ +} + +const FillType DrawableShape::FillAndStrokeState::getMainFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const +{ + return readFillType (state.getChildWithName (fill), 0, 0, 0, nameFinder, imageProvider); +} + +ValueTree DrawableShape::FillAndStrokeState::getMainFillState() +{ + ValueTree v (state.getChildWithName (fill)); + if (v.isValid()) + return v; + + setMainFill (Colours::black, 0, 0, 0, 0, 0); + return getMainFillState(); +} + +void DrawableShape::FillAndStrokeState::setMainFill (const FillType& newFill, const RelativePoint* gp1, const RelativePoint* gp2, + const RelativePoint* gp3, ImageProvider* imageProvider, UndoManager* undoManager) +{ + ValueTree v (state.getOrCreateChildWithName (fill, undoManager)); + writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); +} + +const FillType DrawableShape::FillAndStrokeState::getStrokeFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const +{ + return readFillType (state.getChildWithName (stroke), 0, 0, 0, nameFinder, imageProvider); +} + +ValueTree DrawableShape::FillAndStrokeState::getStrokeFillState() +{ + ValueTree v (state.getChildWithName (stroke)); + if (v.isValid()) + return v; + + setStrokeFill (Colours::black, 0, 0, 0, 0, 0); + return getStrokeFillState(); +} + +void DrawableShape::FillAndStrokeState::setStrokeFill (const FillType& newFill, const RelativePoint* gp1, const RelativePoint* gp2, + const RelativePoint* gp3, ImageProvider* imageProvider, UndoManager* undoManager) +{ + ValueTree v (state.getOrCreateChildWithName (stroke, undoManager)); + writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); +} + +const PathStrokeType DrawableShape::FillAndStrokeState::getStrokeType() const +{ + const String jointStyleString (state [jointStyle].toString()); + const String capStyleString (state [capStyle].toString()); + + return PathStrokeType (state [strokeWidth], + jointStyleString == "curved" ? PathStrokeType::curved + : (jointStyleString == "bevel" ? PathStrokeType::beveled + : PathStrokeType::mitered), + capStyleString == "square" ? PathStrokeType::square + : (capStyleString == "round" ? PathStrokeType::rounded + : PathStrokeType::butt)); +} + +void DrawableShape::FillAndStrokeState::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) +{ + state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); + state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered + ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); + state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt + ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); +} + +const FillType DrawableShape::FillAndStrokeState::readFillType (const ValueTree& v, RelativePoint* const gp1, RelativePoint* const gp2, RelativePoint* const gp3, + Expression::EvaluationContext* const nameFinder, ImageProvider* imageProvider) { const String newType (v[type].toString()); @@ -86206,7 +86465,7 @@ const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v, return f; } - jassertfalse; + jassert (! v.isValid()); return FillType(); } @@ -86219,9 +86478,9 @@ static const Point calcThirdGradientPoint (const FillType& fillType) return point3Source.transformedBy (fillType.transform); } -void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType, - const RelativePoint* const gp1, const RelativePoint* const gp2, const RelativePoint* gp3, - ImageProvider* imageProvider, UndoManager* const undoManager) +void DrawableShape::FillAndStrokeState::writeFillType (ValueTree& v, const FillType& fillType, + const RelativePoint* const gp1, const RelativePoint* const gp2, const RelativePoint* gp3, + ImageProvider* imageProvider, UndoManager* const undoManager) { if (fillType.isColour()) { @@ -86263,7 +86522,7 @@ void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType } END_JUCE_NAMESPACE -/*** End of inlined file: juce_Drawable.cpp ***/ +/*** End of inlined file: juce_DrawableShape.cpp ***/ /*** Start of inlined file: juce_DrawableComposite.cpp ***/ @@ -87210,169 +87469,64 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE DrawablePath::DrawablePath() - : mainFill (Colours::black), - strokeFill (Colours::black), - strokeType (0.0f), - pathNeedsUpdating (true), - strokeNeedsUpdating (true) { } DrawablePath::DrawablePath (const DrawablePath& other) - : mainFill (other.mainFill), - strokeFill (other.strokeFill), - strokeType (other.strokeType), - pathNeedsUpdating (true), - strokeNeedsUpdating (true) + : DrawableShape (other) { if (other.relativePath != 0) relativePath = new RelativePointPath (*other.relativePath); else - path = other.path; + cachedPath = other.cachedPath; } DrawablePath::~DrawablePath() { } -void DrawablePath::setPath (const Path& newPath) -{ - path = newPath; - strokeNeedsUpdating = true; -} - -void DrawablePath::setFill (const FillType& newFill) -{ - mainFill = newFill; -} - -void DrawablePath::setStrokeFill (const FillType& newFill) -{ - strokeFill = newFill; -} - -void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) -{ - strokeType = newStrokeType; - strokeNeedsUpdating = true; -} - -void DrawablePath::setStrokeThickness (const float newThickness) -{ - setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); -} - -void DrawablePath::updatePath() const +Drawable* DrawablePath::createCopy() const { - if (pathNeedsUpdating) - { - pathNeedsUpdating = false; - - if (relativePath != 0) - { - path.clear(); - relativePath->createPath (path, parent); - strokeNeedsUpdating = true; - } - } + return new DrawablePath (*this); } -void DrawablePath::updateStroke() const +void DrawablePath::setPath (const Path& newPath) { - if (strokeNeedsUpdating) - { - strokeNeedsUpdating = false; - updatePath(); - stroke.clear(); - strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); - } + cachedPath = newPath; + strokeChanged(); } const Path& DrawablePath::getPath() const { - updatePath(); - return path; + return getCachedPath(); } const Path& DrawablePath::getStrokePath() const { - updateStroke(); - return stroke; -} - -bool DrawablePath::isStrokeVisible() const throw() -{ - return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); + return getCachedStrokePath(); } -void DrawablePath::invalidatePoints() +bool DrawablePath::rebuildPath (Path& path) const { - pathNeedsUpdating = true; - strokeNeedsUpdating = true; -} - -void DrawablePath::render (const Drawable::RenderingContext& context) const -{ - { - FillType f (mainFill); - if (f.isGradient()) - f.gradient->multiplyOpacity (context.opacity); - else - f.setOpacity (f.getOpacity() * context.opacity); - - f.transform = f.transform.followedBy (context.transform); - context.g.setFillType (f); - context.g.fillPath (getPath(), context.transform); - } - - if (isStrokeVisible()) + if (relativePath != 0) { - FillType f (strokeFill); - if (f.isGradient()) - f.gradient->multiplyOpacity (context.opacity); - else - f.setOpacity (f.getOpacity() * context.opacity); - - f.transform = f.transform.followedBy (context.transform); - context.g.setFillType (f); - context.g.fillPath (getStrokePath(), context.transform); + path.clear(); + relativePath->createPath (path, parent); + return true; } -} - -const Rectangle DrawablePath::getBounds() const -{ - if (isStrokeVisible()) - return getStrokePath().getBounds(); - else - return getPath().getBounds(); -} -bool DrawablePath::hitTest (float x, float y) const -{ - return getPath().contains (x, y) - || (isStrokeVisible() && getStrokePath().contains (x, y)); -} - -Drawable* DrawablePath::createCopy() const -{ - return new DrawablePath (*this); + return false; } const Identifier DrawablePath::valueTreeType ("Path"); -const Identifier DrawablePath::ValueTreeWrapper::fill ("Fill"); -const Identifier DrawablePath::ValueTreeWrapper::stroke ("Stroke"); -const Identifier DrawablePath::ValueTreeWrapper::path ("Path"); -const Identifier DrawablePath::ValueTreeWrapper::jointStyle ("jointStyle"); -const Identifier DrawablePath::ValueTreeWrapper::capStyle ("capStyle"); -const Identifier DrawablePath::ValueTreeWrapper::strokeWidth ("strokeWidth"); const Identifier DrawablePath::ValueTreeWrapper::nonZeroWinding ("nonZeroWinding"); const Identifier DrawablePath::ValueTreeWrapper::point1 ("p1"); const Identifier DrawablePath::ValueTreeWrapper::point2 ("p2"); const Identifier DrawablePath::ValueTreeWrapper::point3 ("p3"); DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) + : FillAndStrokeState (state_) { jassert (state.hasType (valueTreeType)); } @@ -87382,77 +87536,6 @@ ValueTree DrawablePath::ValueTreeWrapper::getPathState() return state.getOrCreateChildWithName (path, 0); } -ValueTree DrawablePath::ValueTreeWrapper::getMainFillState() -{ - ValueTree v (state.getChildWithName (fill)); - if (v.isValid()) - return v; - - setMainFill (Colours::black, 0, 0, 0, 0, 0); - return getMainFillState(); -} - -ValueTree DrawablePath::ValueTreeWrapper::getStrokeFillState() -{ - ValueTree v (state.getChildWithName (stroke)); - if (v.isValid()) - return v; - - setStrokeFill (Colours::black, 0, 0, 0, 0, 0); - return getStrokeFillState(); -} - -const FillType DrawablePath::ValueTreeWrapper::getMainFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const -{ - return readFillType (state.getChildWithName (fill), 0, 0, 0, nameFinder, imageProvider); -} - -void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, const RelativePoint* gp1, - const RelativePoint* gp2, const RelativePoint* gp3, - ImageProvider* imageProvider, UndoManager* undoManager) -{ - ValueTree v (state.getOrCreateChildWithName (fill, undoManager)); - writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); -} - -const FillType DrawablePath::ValueTreeWrapper::getStrokeFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const -{ - return readFillType (state.getChildWithName (stroke), 0, 0, 0, nameFinder, imageProvider); -} - -void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, const RelativePoint* gp1, - const RelativePoint* gp2, const RelativePoint* gp3, - ImageProvider* imageProvider, UndoManager* undoManager) -{ - ValueTree v (state.getOrCreateChildWithName (stroke, undoManager)); - writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); -} - -const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const -{ - const String jointStyleString (state [jointStyle].toString()); - const String capStyleString (state [capStyle].toString()); - - return PathStrokeType (state [strokeWidth], - jointStyleString == "curved" ? PathStrokeType::curved - : (jointStyleString == "bevel" ? PathStrokeType::beveled - : PathStrokeType::mitered), - capStyleString == "square" ? PathStrokeType::square - : (capStyleString == "round" ? PathStrokeType::rounded - : PathStrokeType::butt)); -} - -void DrawablePath::ValueTreeWrapper::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) -{ - state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); - state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered - ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); - state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt - ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); -} - bool DrawablePath::ValueTreeWrapper::usesNonZeroWinding() const { return state [nonZeroWinding]; @@ -87790,24 +87873,7 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree ValueTreeWrapper v (tree); setName (v.getID()); - bool needsRedraw = false; - const FillType newFill (v.getMainFill (parent, imageProvider)); - - if (mainFill != newFill) - { - needsRedraw = true; - mainFill = newFill; - } - - const FillType newStrokeFill (v.getStrokeFill (parent, imageProvider)); - - if (strokeFill != newStrokeFill) - { - needsRedraw = true; - strokeFill = newStrokeFill; - } - - const PathStrokeType newStroke (v.getStrokeType()); + bool needsRedraw = refreshFillTypes (v, parent, imageProvider); ScopedPointer newRelativePath (new RelativePointPath (tree)); @@ -87817,11 +87883,12 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree if (! newRelativePath->containsAnyDynamicPoints()) newRelativePath = 0; - if (strokeType != newStroke || path != newPath) + const PathStrokeType newStroke (v.getStrokeType()); + if (strokeType != newStroke || cachedPath != newPath) { damageRect = getBounds(); - path.swapWithPath (newPath); - strokeNeedsUpdating = true; + cachedPath.swapWithPath (newPath); + strokeChanged(); strokeType = newStroke; needsRedraw = true; } @@ -87840,9 +87907,7 @@ const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) con ValueTreeWrapper v (tree); v.setID (getName(), 0); - v.setMainFill (mainFill, 0, 0, 0, imageProvider, 0); - v.setStrokeFill (strokeFill, 0, 0, 0, imageProvider, 0); - v.setStrokeType (strokeType, 0); + writeTo (v, imageProvider, 0); if (relativePath != 0) { @@ -87850,7 +87915,7 @@ const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) con } else { - RelativePointPath rp (path); + RelativePointPath rp (getCachedPath()); rp.writeTo (tree, 0); } @@ -87861,6 +87926,163 @@ END_JUCE_NAMESPACE /*** End of inlined file: juce_DrawablePath.cpp ***/ +/*** Start of inlined file: juce_DrawableRectangle.cpp ***/ +BEGIN_JUCE_NAMESPACE + +DrawableRectangle::DrawableRectangle() +{ +} + +DrawableRectangle::DrawableRectangle (const DrawableRectangle& other) + : DrawableShape (other) +{ +} + +DrawableRectangle::~DrawableRectangle() +{ +} + +Drawable* DrawableRectangle::createCopy() const +{ + return new DrawableRectangle (*this); +} + +void DrawableRectangle::setRectangle (const RelativeParallelogram& newBounds) +{ + bounds = newBounds; + pathChanged(); + strokeChanged(); +} + +void DrawableRectangle::setCornerSize (const RelativePoint& newSize) +{ + cornerSize = newSize; + pathChanged(); + strokeChanged(); +} + +bool DrawableRectangle::rebuildPath (Path& path) const +{ + Point points[3]; + bounds.resolveThreePoints (points, parent); + + const float w = Line (points[0], points[1]).getLength(); + const float h = Line (points[0], points[2]).getLength(); + + const float cornerSizeX = cornerSize.x.resolve (parent); + const float cornerSizeY = cornerSize.y.resolve (parent); + + path.clear(); + + if (cornerSizeX > 0 && cornerSizeY > 0) + path.addRoundedRectangle (0, 0, w, h, cornerSizeX, cornerSizeY); + else + path.addRectangle (0, 0, w, h); + + path.applyTransform (AffineTransform::fromTargetPoints (0, 0, points[0].getX(), points[0].getY(), + w, 0, points[1].getX(), points[1].getY(), + 0, h, points[2].getX(), points[2].getY())); + return true; +} + +const AffineTransform DrawableRectangle::calculateTransform() const +{ + Point resolved[3]; + bounds.resolveThreePoints (resolved, parent); + + return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), + resolved[1].getX(), resolved[1].getY(), + resolved[2].getX(), resolved[2].getY()); +} + +const Identifier DrawableRectangle::valueTreeType ("Rectangle"); +const Identifier DrawableRectangle::ValueTreeWrapper::topLeft ("topLeft"); +const Identifier DrawableRectangle::ValueTreeWrapper::topRight ("topRight"); +const Identifier DrawableRectangle::ValueTreeWrapper::bottomLeft ("bottomLeft"); +const Identifier DrawableRectangle::ValueTreeWrapper::cornerSize ("cornerSize"); + +DrawableRectangle::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : FillAndStrokeState (state_) +{ + jassert (state.hasType (valueTreeType)); +} + +const RelativeParallelogram DrawableRectangle::ValueTreeWrapper::getRectangle() const +{ + return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), + state.getProperty (topRight, "100, 0"), + state.getProperty (bottomLeft, "0, 100")); +} + +void DrawableRectangle::ValueTreeWrapper::setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager) +{ + state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); + state.setProperty (topRight, newBounds.topRight.toString(), undoManager); + state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); +} + +void DrawableRectangle::ValueTreeWrapper::setCornerSize (const RelativePoint& newSize, UndoManager* undoManager) +{ + state.setProperty (cornerSize, newSize.toString(), undoManager); +} + +const RelativePoint DrawableRectangle::ValueTreeWrapper::getCornerSize() const +{ + return RelativePoint (state [cornerSize]); +} + +Value DrawableRectangle::ValueTreeWrapper::getCornerSizeValue (UndoManager* undoManager) const +{ + return state.getPropertyAsValue (cornerSize, undoManager); +} + +const Rectangle DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +{ + Rectangle damageRect; + ValueTreeWrapper v (tree); + setName (v.getID()); + + bool needsRedraw = refreshFillTypes (v, parent, imageProvider); + + RelativeParallelogram newBounds (v.getRectangle()); + + const PathStrokeType newStroke (v.getStrokeType()); + const RelativePoint newCornerSize (v.getCornerSize()); + + if (strokeType != newStroke || newBounds != bounds || newCornerSize != cornerSize) + { + damageRect = getBounds(); + bounds = newBounds; + strokeType = newStroke; + cornerSize = newCornerSize; + pathChanged(); + strokeChanged(); + needsRedraw = true; + } + + if (needsRedraw) + damageRect = damageRect.getUnion (getBounds()); + + return damageRect; +} + +const ValueTree DrawableRectangle::createValueTree (ImageProvider* imageProvider) const +{ + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); + + v.setID (getName(), 0); + writeTo (v, imageProvider, 0); + v.setRectangle (bounds, 0); + v.setCornerSize (cornerSize, 0); + + return tree; +} + +END_JUCE_NAMESPACE +/*** End of inlined file: juce_DrawableRectangle.cpp ***/ + + /*** Start of inlined file: juce_DrawableText.cpp ***/ BEGIN_JUCE_NAMESPACE @@ -87936,8 +88158,8 @@ void DrawableText::render (const Drawable::RenderingContext& context) const const float h = Line (points[0], points[2]).getLength(); const Point fontCoords (bounds.getInternalCoordForPoint (points, fontSizeControlPoint.resolve (parent))); - const float fontHeight = jlimit (1.0f, h, fontCoords.getY()); - const float fontWidth = jlimit (0.01f, w, fontCoords.getX()); + const float fontHeight = jlimit (0.01f, jmax (0.01f, h), fontCoords.getY()); + const float fontWidth = jlimit (0.01f, jmax (0.01f, w), fontCoords.getX()); Font f (font); f.setHeight (fontHeight); @@ -92186,15 +92408,15 @@ void Path::addEllipse (const float x, const float y, const float hw = w * 0.5f; const float hw55 = hw * 0.55f; const float hh = h * 0.5f; - const float hh45 = hh * 0.55f; + const float hh55 = hh * 0.55f; const float cx = x + hw; const float cy = y + hh; startNewSubPath (cx, cy - hh); - cubicTo (cx + hw55, cy - hh, cx + hw, cy - hh45, cx + hw, cy); - cubicTo (cx + hw, cy + hh45, cx + hw55, cy + hh, cx, cy + hh); - cubicTo (cx - hw55, cy + hh, cx - hw, cy + hh45, cx - hw, cy); - cubicTo (cx - hw, cy - hh45, cx - hw55, cy - hh, cx, cy - hh); + cubicTo (cx + hw55, cy - hh, cx + hw, cy - hh55, cx + hw, cy); + cubicTo (cx + hw, cy + hh55, cx + hw55, cy + hh, cx, cy + hh); + cubicTo (cx - hw55, cy + hh, cx - hw, cy + hh55, cx - hw, cy); + cubicTo (cx - hw, cy - hh55, cx - hw55, cy - hh, cx, cy - hh); closeSubPath(); } @@ -238370,7 +238592,7 @@ void Process::setPriority (ProcessPriority prior) } } -bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger() +JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() { return IsDebuggerPresent() != FALSE; } @@ -243299,36 +243521,48 @@ private: doMouseWheel (getCurrentMousePos(), wParam, false); return 0; + case WM_SIZING: + if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable)) + { + RECT* const r = (RECT*) lParam; + Rectangle pos (r->left, r->top, r->right - r->left, r->bottom - r->top); + + constrainer->checkBounds (pos, windowBorder.addedTo (component->getBounds()), + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT, + wParam == WMSZ_LEFT || wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT, + wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT, + wParam == WMSZ_RIGHT || wParam == WMSZ_TOPRIGHT || wParam == WMSZ_BOTTOMRIGHT); + r->left = pos.getX(); + r->top = pos.getY(); + r->right = pos.getRight(); + r->bottom = pos.getBottom(); + } + return TRUE; + case WM_WINDOWPOSCHANGING: - if ((styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable)) + if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable)) { WINDOWPOS* const wp = (WINDOWPOS*) lParam; - if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)) + if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE) + && ! Component::isMouseButtonDownAnywhere()) { - if (constrainer != 0) - { - const Rectangle current (component->getX() - windowBorder.getLeft(), - component->getY() - windowBorder.getTop(), - component->getWidth() + windowBorder.getLeftAndRight(), - component->getHeight() + windowBorder.getTopAndBottom()); - - Rectangle pos (wp->x, wp->y, wp->cx, wp->cy); - - constrainer->checkBounds (pos, current, - Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), - pos.getY() != current.getY() && pos.getBottom() == current.getBottom(), - pos.getX() != current.getX() && pos.getRight() == current.getRight(), - pos.getY() == current.getY() && pos.getBottom() != current.getBottom(), - pos.getX() == current.getX() && pos.getRight() != current.getRight()); - wp->x = pos.getX(); - wp->y = pos.getY(); - wp->cx = pos.getWidth(); - wp->cy = pos.getHeight(); - } + Rectangle pos (wp->x, wp->y, wp->cx, wp->cy); + const Rectangle current (windowBorder.addedTo (component->getBounds())); + + constrainer->checkBounds (pos, current, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + pos.getY() != current.getY() && pos.getBottom() == current.getBottom(), + pos.getX() != current.getX() && pos.getRight() == current.getRight(), + pos.getY() == current.getY() && pos.getBottom() != current.getBottom(), + pos.getX() == current.getX() && pos.getRight() != current.getRight()); + wp->x = pos.getX(); + wp->y = pos.getY(); + wp->cx = pos.getWidth(); + wp->cy = pos.getHeight(); } } - return 0; case WM_WINDOWPOSCHANGED: @@ -244198,12 +244432,12 @@ public: { } - virtual ~JuceDataObject() + ~JuceDataObject() { jassert (refCount == 0); } - HRESULT __stdcall GetData (FORMATETC __RPC_FAR* pFormatEtc, STGMEDIUM __RPC_FAR* pMedium) + HRESULT __stdcall GetData (FORMATETC* pFormatEtc, STGMEDIUM* pMedium) { if ((pFormatEtc->tymed & format->tymed) != 0 && pFormatEtc->cfFormat == format->cfFormat @@ -244230,7 +244464,7 @@ public: return DV_E_FORMATETC; } - HRESULT __stdcall QueryGetData (FORMATETC __RPC_FAR* f) + HRESULT __stdcall QueryGetData (FORMATETC* f) { if (f == 0) return E_INVALIDARG; @@ -244243,13 +244477,13 @@ public: return DV_E_FORMATETC; } - HRESULT __stdcall GetCanonicalFormatEtc (FORMATETC __RPC_FAR*, FORMATETC __RPC_FAR* pFormatEtcOut) + HRESULT __stdcall GetCanonicalFormatEtc (FORMATETC*, FORMATETC* pFormatEtcOut) { pFormatEtcOut->ptd = 0; return E_NOTIMPL; } - HRESULT __stdcall EnumFormatEtc (DWORD direction, IEnumFORMATETC __RPC_FAR *__RPC_FAR *result) + HRESULT __stdcall EnumFormatEtc (DWORD direction, IEnumFORMATETC** result) { if (result == 0) return E_POINTER; @@ -244264,11 +244498,11 @@ public: return E_NOTIMPL; } - HRESULT __stdcall GetDataHere (FORMATETC __RPC_FAR*, STGMEDIUM __RPC_FAR*) { return DATA_E_FORMATETC; } - HRESULT __stdcall SetData (FORMATETC __RPC_FAR*, STGMEDIUM __RPC_FAR*, BOOL) { return E_NOTIMPL; } - HRESULT __stdcall DAdvise (FORMATETC __RPC_FAR*, DWORD, IAdviseSink __RPC_FAR*, DWORD __RPC_FAR*) { return OLE_E_ADVISENOTSUPPORTED; } - HRESULT __stdcall DUnadvise (DWORD) { return E_NOTIMPL; } - HRESULT __stdcall EnumDAdvise (IEnumSTATDATA __RPC_FAR *__RPC_FAR *) { return OLE_E_ADVISENOTSUPPORTED; } + HRESULT __stdcall GetDataHere (FORMATETC*, STGMEDIUM*) { return DATA_E_FORMATETC; } + HRESULT __stdcall SetData (FORMATETC*, STGMEDIUM*, BOOL) { return E_NOTIMPL; } + HRESULT __stdcall DAdvise (FORMATETC*, DWORD, IAdviseSink*, DWORD*) { return OLE_E_ADVISENOTSUPPORTED; } + HRESULT __stdcall DUnadvise (DWORD) { return E_NOTIMPL; } + HRESULT __stdcall EnumDAdvise (IEnumSTATDATA**) { return OLE_E_ADVISENOTSUPPORTED; } private: JuceDropSource* const dropSource; @@ -244798,7 +245032,7 @@ namespace ActiveXHelpers inplaceSite->Release(); } - HRESULT __stdcall QueryInterface (REFIID type, void __RPC_FAR* __RPC_FAR* result) + HRESULT __stdcall QueryInterface (REFIID type, void** result) { if (type == IID_IOleInPlaceSite) { @@ -245691,14 +245925,14 @@ private: { } - HRESULT __stdcall GetTypeInfoCount (UINT __RPC_FAR*) { return E_NOTIMPL; } - HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo __RPC_FAR *__RPC_FAR*) { return E_NOTIMPL; } - HRESULT __stdcall GetIDsOfNames (REFIID, LPOLESTR __RPC_FAR*, UINT, LCID, DISPID __RPC_FAR*) { return E_NOTIMPL; } + HRESULT __stdcall GetTypeInfoCount (UINT*) { return E_NOTIMPL; } + HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo**) { return E_NOTIMPL; } + HRESULT __stdcall GetIDsOfNames (REFIID, LPOLESTR*, UINT, LCID, DISPID*) { return E_NOTIMPL; } HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID /*riid*/, LCID /*lcid*/, - WORD /*wFlags*/, DISPPARAMS __RPC_FAR* pDispParams, - VARIANT __RPC_FAR* /*pVarResult*/, EXCEPINFO __RPC_FAR* /*pExcepInfo*/, - UINT __RPC_FAR* /*puArgErr*/) + WORD /*wFlags*/, DISPPARAMS* pDispParams, + VARIANT* /*pVarResult*/, EXCEPINFO* /*pExcepInfo*/, + UINT* /*puArgErr*/) { switch (dispIdMember) { @@ -249251,6 +249485,11 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) #define log(a) {} #endif +/* The ASIO SDK *should* declare its callback functions as being __cdecl, but different versions seem + to be pretty random about whether or not they do this. If you hit an error using these functions + it'll be because you're trying to build using __stdcall, in which case you'd need to either get hold of + an ASIO SDK which correctly specifies __cdecl, or add the __cdecl keyword to its functions yourself. +*/ #define JUCE_ASIOCALLBACK __cdecl #if ASIO_DEBUGGING @@ -256466,7 +256705,7 @@ void Process::terminate() exit (0); } -bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger() +JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() { static char testResult = 0; @@ -256484,7 +256723,7 @@ bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger() return testResult < 0; } -bool JUCE_CALLTYPE Process::isRunningUnderDebugger() +JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() { return juce_isRunningUnderDebugger(); } @@ -266025,7 +266264,7 @@ void Logger::outputDebugString (const String& text) std::cerr << text << std::endl; } -bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger() +JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() { static char testResult = 0; @@ -266041,7 +266280,7 @@ bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger() return testResult > 0; } -bool JUCE_CALLTYPE Process::isRunningUnderDebugger() +JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() { return juce_isRunningUnderDebugger(); } @@ -273069,12 +273308,21 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) Rectangle pos (convertToRectInt (r)); Rectangle original (convertToRectInt (current)); - constrainer->checkBounds (pos, original, - Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), - pos.getY() != original.getY() && pos.getBottom() == original.getBottom(), - pos.getX() != original.getX() && pos.getRight() == original.getRight(), - pos.getY() == original.getY() && pos.getBottom() != original.getBottom(), - pos.getX() == original.getX() && pos.getRight() != original.getRight()); + if ([window inLiveResize]) + { + constrainer->checkBounds (pos, original, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + false, false, true, true); + } + else + { + constrainer->checkBounds (pos, original, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + pos.getY() != original.getY() && pos.getBottom() == original.getBottom(), + pos.getX() != original.getX() && pos.getRight() == original.getRight(), + pos.getY() == original.getY() && pos.getBottom() != original.getBottom(), + pos.getX() == original.getX() && pos.getRight() != original.getRight()); + } r.origin.x = pos.getX(); r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.size.height - pos.getY(); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index a077296519..3c06bccbd3 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -64,7 +64,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 78 +#define JUCE_BUILDNUMBER 79 /** Current Juce version number. @@ -777,10 +777,10 @@ // Now include some basics that are needed by most of the Juce classes... BEGIN_JUCE_NAMESPACE -extern bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger(); +extern JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger(); #if JUCE_LOG_ASSERTIONS - extern void JUCE_API juce_LogAssertion (const char* filename, int lineNum) throw(); + extern JUCE_API void juce_LogAssertion (const char* filename, int lineNum) throw(); #endif @@ -2605,83 +2605,83 @@ private: }; /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (const char* string1, const String& string2); +JUCE_API const String JUCE_CALLTYPE operator+ (const char* string1, const String& string2); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar* string1, const String& string2); +JUCE_API const String JUCE_CALLTYPE operator+ (const juce_wchar* string1, const String& string2); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (char string1, const String& string2); +JUCE_API const String JUCE_CALLTYPE operator+ (char string1, const String& string2); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (juce_wchar string1, const String& string2); +JUCE_API const String JUCE_CALLTYPE operator+ (juce_wchar string1, const String& string2); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const String& string2); +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const String& string2); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const char* string2); +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const char* string2); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const juce_wchar* string2); +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar* string2); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, char characterToAppend); +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); /** Concatenates two strings. */ -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, juce_wchar characterToAppend); +JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); /** Appends a character at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, char characterToAppend); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, char characterToAppend); /** Appends a character at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, juce_wchar characterToAppend); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, juce_wchar characterToAppend); /** Appends a string to the end of the first one. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char* string2); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char* string2); /** Appends a string to the end of the first one. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const juce_wchar* string2); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const juce_wchar* string2); /** Appends a string to the end of the first one. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const String& string2); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const String& string2); /** Appends a decimal number at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, short number); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, short number); /** Appends a decimal number at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, int number); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int number); /** Appends a decimal number at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, unsigned int number); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, unsigned int number); /** Appends a decimal number at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, long number); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, long number); /** Appends a decimal number at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, unsigned long number); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, unsigned long number); /** Appends a decimal number at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, float number); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, float number); /** Appends a decimal number at the end of a string. */ -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, double number); +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, double number); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const String& string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const String& string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const char* string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const char* string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const juce_wchar* string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const juce_wchar* string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const String& string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const String& string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const char* string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const char* string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const juce_wchar* string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const juce_wchar* string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator> (const String& string1, const String& string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator> (const String& string1, const String& string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator< (const String& string1, const String& string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator< (const String& string1, const String& string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator>= (const String& string1, const String& string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator>= (const String& string1, const String& string2) throw(); /** Case-sensitive comparison of two strings. */ -bool JUCE_PUBLIC_FUNCTION operator<= (const String& string1, const String& string2) throw(); +JUCE_API bool JUCE_CALLTYPE operator<= (const String& string1, const String& string2) throw(); /** This streaming override allows you to pass a juce String directly into std output streams. This is very handy for writing strings to std::cout, std::cerr, etc. */ template -std::basic_ostream & JUCE_PUBLIC_FUNCTION operator<< (std::basic_ostream & stream, const String& stringToWrite) +JUCE_API std::basic_ostream & JUCE_CALLTYPE operator<< (std::basic_ostream & stream, const String& stringToWrite) { return stream << stringToWrite.toUTF8(); } /** Writes a string to an OutputStream as UTF8. */ -OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text); +JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text); #endif // __JUCE_STRING_JUCEHEADER__ /*** End of inlined file: juce_String.h ***/ @@ -14107,7 +14107,7 @@ private: @see shutdownJuce_GUI(), initialiseJuce_NonGUI() */ -void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI(); +JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI(); /** Clears up any static data being used by Juce's GUI classes. @@ -14117,7 +14117,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI(); @see initialiseJuce_GUI(), initialiseJuce_NonGUI() */ -void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI(); +JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI(); /** Initialises the core parts of Juce. @@ -14129,7 +14129,7 @@ void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI(); @see shutdownJuce_NonGUI, initialiseJuce_GUI */ -void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI(); +JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI(); /** Clears up any static data being used by Juce's non-gui core classes. @@ -14139,7 +14139,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI(); @see initialiseJuce_NonGUI, initialiseJuce_GUI */ -void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI(); +JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI(); /** A utility object that helps you initialise and shutdown Juce correctly using an RAII pattern. @@ -41008,6 +41008,11 @@ public: */ bool scanNextFile (bool dontRescanIfAlreadyInList); + /** Skips over the next file without scanning it. + Returns false when there are no more files to try. + */ + bool skipNextFile(); + /** Returns the description of the plugin that will be scanned during the next call to scanNextFile(). @@ -44439,6 +44444,7 @@ class JUCE_API RelativeParallelogram public: RelativeParallelogram(); + RelativeParallelogram (const Rectangle& simpleRectangle); RelativeParallelogram (const RelativePoint& topLeft, const RelativePoint& topRight, const RelativePoint& bottomLeft); RelativeParallelogram (const String& topLeft, const String& topRight, const String& bottomLeft); ~RelativeParallelogram(); @@ -44662,28 +44668,18 @@ public: void setID (const String& newID, UndoManager* undoManager); static const Identifier idProperty; - static const FillType readFillType (const ValueTree& v, RelativePoint* gradientPoint1, - RelativePoint* gradientPoint2, RelativePoint* gradientPoint3, - Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider); - - static void writeFillType (ValueTree& v, const FillType& fillType, - const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2, - const RelativePoint* gradientPoint3, ImageProvider* imageProvider, - UndoManager* undoManager); - ValueTree state; - static const Identifier type, gradientPoint1, gradientPoint2, gradientPoint3, - colour, radial, colours, imageId, imageOpacity; }; juce_UseDebuggingNewOperator protected: friend class DrawableComposite; + /** @internal */ DrawableComposite* parent; + /** @internal */ virtual void invalidatePoints() = 0; - + /** @internal */ static Drawable* createChildFromValueTree (DrawableComposite* parent, const ValueTree& tree, ImageProvider* imageProvider); private: @@ -55377,7 +55373,7 @@ public: juce_UseDebuggingNewOperator private: - friend void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI(); + friend JUCE_API void JUCE_CALLTYPE shutdownJuce_GUI(); static void clearDefaultLookAndFeel() throw(); // called at shutdown Array colourIds; @@ -60271,16 +60267,16 @@ public: */ void bringToFront (int index); - /** Changes the main content area. + /** Returns the main content rectangle. The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that sets them all at once. + "bottom", but this method is a shortcut that returns them all at once. @see contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName */ const RelativeRectangle getContentArea() const; - /** Returns the main content rectangle. + /** Changes the main content area. The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that returns them all at once. + "bottom", but this method is a shortcut that sets them all at once. @see setBoundingBox, contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName */ void setContentArea (const RelativeRectangle& newArea); @@ -60382,11 +60378,10 @@ public: void setMarker (bool xAxis, const Marker& marker, UndoManager* undoManager); void removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager); - static const Identifier nameProperty, posProperty; + static const Identifier nameProperty, posProperty, topLeft, topRight, bottomLeft; private: - static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTagX, - markerGroupTagY, markerTag; + static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY, markerTag; ValueTree getChildList() const; ValueTree getChildListCreating (UndoManager* undoManager); @@ -60535,30 +60530,29 @@ private: #ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ #define __JUCE_DRAWABLEPATH_JUCEHEADER__ + +/*** Start of inlined file: juce_DrawableShape.h ***/ +#ifndef __JUCE_DRAWABLESHAPE_JUCEHEADER__ +#define __JUCE_DRAWABLESHAPE_JUCEHEADER__ + /** - A drawable object which renders a filled or outlined shape. + A base class implementing common functionality for Drawable classes which + consist of some kind of filled and stroked outline. - @see Drawable + @see DrawablePath, DrawableRectangle */ -class JUCE_API DrawablePath : public Drawable +class JUCE_API DrawableShape : public Drawable { -public: +protected: - /** Creates a DrawablePath. */ - DrawablePath(); - DrawablePath (const DrawablePath& other); + DrawableShape(); + DrawableShape (const DrawableShape&); +public: /** Destructor. */ - ~DrawablePath(); - - /** Changes the path that will be drawn. - - @see setFillColour, setStrokeType - */ - void setPath (const Path& newPath); + ~DrawableShape(); /** Sets a fill type for the path. - This colour is used to fill the path - if you don't want the path to be filled (e.g. if you're just drawing an outline), set this to a transparent colour. @@ -60596,23 +60590,125 @@ public: /** Returns the current outline style. */ const PathStrokeType& getStrokeType() const throw() { return strokeType; } - /** Returns the current path. */ - const Path& getPath() const; + /** @internal */ + class FillAndStrokeState : public ValueTreeWrapperBase + { + public: + FillAndStrokeState (const ValueTree& state); - /** Returns the current path for the outline. */ - const Path& getStrokePath() const; + const FillType getMainFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const; + ValueTree getMainFillState(); + void setMainFill (const FillType& newFill, const RelativePoint* gradientPoint1, + const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, + ImageProvider* imageProvider, UndoManager* undoManager); + + const FillType getStrokeFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const; + ValueTree getStrokeFillState(); + void setStrokeFill (const FillType& newFill, const RelativePoint* gradientPoint1, + const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, + ImageProvider* imageProvider, UndoManager* undoManager); + + const PathStrokeType getStrokeType() const; + void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); + + static const FillType readFillType (const ValueTree& v, RelativePoint* gradientPoint1, + RelativePoint* gradientPoint2, RelativePoint* gradientPoint3, + Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider); + + static void writeFillType (ValueTree& v, const FillType& fillType, + const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2, + const RelativePoint* gradientPoint3, ImageProvider* imageProvider, + UndoManager* undoManager); + + static const Identifier type, colour, colours, fill, stroke, path, jointStyle, capStyle, strokeWidth, + gradientPoint1, gradientPoint2, gradientPoint3, radial, imageId, imageOpacity; + }; + /** @internal */ + void invalidatePoints(); /** @internal */ void render (const Drawable::RenderingContext& context) const; /** @internal */ const Rectangle getBounds() const; /** @internal */ bool hitTest (float x, float y) const; + +protected: + + /** Called when the cached path should be updated. */ + void pathChanged(); + /** Called when the cached stroke should be updated. */ + void strokeChanged(); + + /** Implemented by subclasses to regenerate the path. */ + virtual bool rebuildPath (Path& path) const = 0; + + /** True if there's a stroke with a non-zero thickness and non-transparent colour. */ + bool isStrokeVisible() const throw(); + + /** Updates the details from a FillAndStrokeState object, returning true if something changed. */ + bool refreshFillTypes (const FillAndStrokeState& newState, + Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider); + + /** Writes the stroke and fill details to a FillAndStrokeState object. */ + void writeTo (FillAndStrokeState& state, ImageProvider* imageProvider, UndoManager* undoManager) const; + + /** Returns the current cached path outline. */ + const Path& getCachedPath() const; + /** Returns the current cached stroke outline. */ + const Path& getCachedStrokePath() const; + + PathStrokeType strokeType; + mutable Path cachedPath, cachedStroke; + +private: + FillType mainFill, strokeFill; + mutable bool pathNeedsUpdating, strokeNeedsUpdating; + + static void setBrush (const Drawable::RenderingContext& context, const FillType& type); + + DrawableShape& operator= (const DrawableShape&); +}; + +#endif // __JUCE_DRAWABLESHAPE_JUCEHEADER__ +/*** End of inlined file: juce_DrawableShape.h ***/ + +/** + A drawable object which renders a filled or outlined shape. + + For details on how to change the fill and stroke, see the DrawableShape class. + + @see Drawable, DrawableShape +*/ +class JUCE_API DrawablePath : public DrawableShape +{ +public: + + /** Creates a DrawablePath. */ + DrawablePath(); + DrawablePath (const DrawablePath& other); + + /** Destructor. */ + ~DrawablePath(); + + /** Changes the path that will be drawn. + @see setFillColour, setStrokeType + */ + void setPath (const Path& newPath); + + /** Returns the current path. */ + const Path& getPath() const; + + /** Returns the current path for the outline. */ + const Path& getStrokePath() const; + /** @internal */ Drawable* createCopy() const; /** @internal */ - void invalidatePoints(); - /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -60622,28 +60718,11 @@ public: const Identifier getValueTreeType() const { return valueTreeType; } /** Internally-used class for wrapping a DrawablePath's state into a ValueTree. */ - class ValueTreeWrapper : public ValueTreeWrapperBase + class ValueTreeWrapper : public FillAndStrokeState { public: ValueTreeWrapper (const ValueTree& state); - const FillType getMainFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const; - ValueTree getMainFillState(); - void setMainFill (const FillType& newFill, const RelativePoint* gradientPoint1, - const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, - ImageProvider* imageProvider, UndoManager* undoManager); - - const FillType getStrokeFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const; - ValueTree getStrokeFillState(); - void setStrokeFill (const FillType& newFill, const RelativePoint* gradientPoint1, - const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, - ImageProvider* imageProvider, UndoManager* undoManager); - - const PathStrokeType getStrokeType() const; - void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); - bool usesNonZeroWinding() const; void setUsesNonZeroWinding (bool b, UndoManager* undoManager); @@ -60687,22 +60766,16 @@ public: ValueTree getPathState(); - static const Identifier fill, stroke, path, jointStyle, capStyle, strokeWidth, - nonZeroWinding, point1, point2, point3; + static const Identifier nonZeroWinding, point1, point2, point3; }; juce_UseDebuggingNewOperator +protected: + bool rebuildPath (Path& path) const; + private: - FillType mainFill, strokeFill; - PathStrokeType strokeType; ScopedPointer relativePath; - mutable Path path, stroke; - mutable bool pathNeedsUpdating, strokeNeedsUpdating; - - void updatePath() const; - void updateStroke() const; - bool isStrokeVisible() const throw(); DrawablePath& operator= (const DrawablePath&); }; @@ -60711,6 +60784,91 @@ private: /*** End of inlined file: juce_DrawablePath.h ***/ +#endif +#ifndef __JUCE_DRAWABLERECTANGLE_JUCEHEADER__ + +/*** Start of inlined file: juce_DrawableRectangle.h ***/ +#ifndef __JUCE_DRAWABLERECTANGLE_JUCEHEADER__ +#define __JUCE_DRAWABLERECTANGLE_JUCEHEADER__ + +/** + A Drawable object which draws a rectangle. + + For details on how to change the fill and stroke, see the DrawableShape class. + + @see Drawable, DrawableShape +*/ +class JUCE_API DrawableRectangle : public DrawableShape +{ +public: + + DrawableRectangle(); + DrawableRectangle (const DrawableRectangle& other); + + /** Destructor. */ + ~DrawableRectangle(); + + /** Sets the rectangle's bounds. */ + void setRectangle (const RelativeParallelogram& newBounds); + + /** Returns the rectangle's bounds. */ + const RelativeParallelogram& getRectangle() const throw() { return bounds; } + + /** Returns the corner size to be used. */ + const RelativePoint getCornerSize() const { return cornerSize; } + + /** Sets a new corner size for the rectangle */ + void setCornerSize (const RelativePoint& newSize); + + /** @internal */ + Drawable* createCopy() const; + /** @internal */ + const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); + /** @internal */ + const ValueTree createValueTree (ImageProvider* imageProvider) const; + /** @internal */ + static const Identifier valueTreeType; + /** @internal */ + const Identifier getValueTreeType() const { return valueTreeType; } + + /** Internally-used class for wrapping a DrawableRectangle's state into a ValueTree. */ + class ValueTreeWrapper : public FillAndStrokeState + { + public: + ValueTreeWrapper (const ValueTree& state); + + const RelativeParallelogram getRectangle() const; + void setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager); + + void setCornerSize (const RelativePoint& cornerSize, UndoManager* undoManager); + const RelativePoint getCornerSize() const; + Value getCornerSizeValue (UndoManager* undoManager) const; + + static const Identifier topLeft, topRight, bottomLeft, cornerSize; + }; + + juce_UseDebuggingNewOperator + +protected: + /** @internal */ + bool rebuildPath (Path& path) const; + +private: + RelativeParallelogram bounds; + RelativePoint cornerSize; + + const AffineTransform calculateTransform() const; + + DrawableRectangle& operator= (const DrawableRectangle&); +}; + +#endif // __JUCE_DRAWABLERECTANGLE_JUCEHEADER__ +/*** End of inlined file: juce_DrawableRectangle.h ***/ + + +#endif +#ifndef __JUCE_DRAWABLESHAPE_JUCEHEADER__ + #endif #ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ diff --git a/src/application/juce_ApplicationCommandManager.cpp b/src/application/juce_ApplicationCommandManager.cpp index fc7fd853bf..1b56943195 100644 --- a/src/application/juce_ApplicationCommandManager.cpp +++ b/src/application/juce_ApplicationCommandManager.cpp @@ -190,14 +190,12 @@ bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::Invocati // manager first.. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - ApplicationCommandTarget* const target = getFirstCommandTarget (info_.commandID); + ApplicationCommandInfo commandInfo (0); + ApplicationCommandTarget* const target = getTargetForCommand (info_.commandID, commandInfo); if (target == 0) return false; - ApplicationCommandInfo commandInfo (0); - target->getCommandInfo (info_.commandID, commandInfo); - ApplicationCommandTarget::InvocationInfo info (info_); info.commandFlags = commandInfo.flags; diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index a1129234d4..21e3161f22 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 78 +#define JUCE_BUILDNUMBER 79 /** Current Juce version number. diff --git a/src/gui/graphics/drawables/juce_Drawable.cpp b/src/gui/graphics/drawables/juce_Drawable.cpp index 3a4307e475..9d3c45029e 100644 --- a/src/gui/graphics/drawables/juce_Drawable.cpp +++ b/src/gui/graphics/drawables/juce_Drawable.cpp @@ -30,6 +30,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_Drawable.h" #include "juce_DrawableComposite.h" #include "juce_DrawablePath.h" +#include "juce_DrawableRectangle.h" #include "juce_DrawableImage.h" #include "juce_DrawableText.h" #include "../imaging/juce_ImageFileFormat.h" @@ -139,6 +140,8 @@ Drawable* Drawable::createChildFromValueTree (DrawableComposite* parent, const V d = new DrawablePath(); else if (type == DrawableComposite::valueTreeType) d = new DrawableComposite(); + else if (type == DrawableRectangle::valueTreeType) + d = new DrawableRectangle(); else if (type == DrawableImage::valueTreeType) d = new DrawableImage(); else if (type == DrawableText::valueTreeType) @@ -156,15 +159,6 @@ Drawable* Drawable::createChildFromValueTree (DrawableComposite* parent, const V //============================================================================== const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id"); -const Identifier Drawable::ValueTreeWrapperBase::type ("type"); -const Identifier Drawable::ValueTreeWrapperBase::gradientPoint1 ("point1"); -const Identifier Drawable::ValueTreeWrapperBase::gradientPoint2 ("point2"); -const Identifier Drawable::ValueTreeWrapperBase::gradientPoint3 ("point3"); -const Identifier Drawable::ValueTreeWrapperBase::colour ("colour"); -const Identifier Drawable::ValueTreeWrapperBase::radial ("radial"); -const Identifier Drawable::ValueTreeWrapperBase::colours ("colours"); -const Identifier Drawable::ValueTreeWrapperBase::imageId ("imageId"); -const Identifier Drawable::ValueTreeWrapperBase::imageOpacity ("imageOpacity"); Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_) : state (state_) @@ -188,119 +182,5 @@ void Drawable::ValueTreeWrapperBase::setID (const String& newID, UndoManager* co state.setProperty (idProperty, newID, undoManager); } -const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v, RelativePoint* const gp1, RelativePoint* const gp2, RelativePoint* const gp3, - Expression::EvaluationContext* const nameFinder, ImageProvider* imageProvider) -{ - const String newType (v[type].toString()); - - if (newType == "solid") - { - const String colourString (v [colour].toString()); - return FillType (Colour (colourString.isEmpty() ? (uint32) 0xff000000 - : (uint32) colourString.getHexValue32())); - } - else if (newType == "gradient") - { - RelativePoint p1 (v [gradientPoint1]), p2 (v [gradientPoint2]), p3 (v [gradientPoint3]); - - ColourGradient g; - - if (gp1 != 0) *gp1 = p1; - if (gp2 != 0) *gp2 = p2; - if (gp3 != 0) *gp3 = p3; - - g.point1 = p1.resolve (nameFinder); - g.point2 = p2.resolve (nameFinder); - g.isRadial = v[radial]; - - StringArray colourSteps; - colourSteps.addTokens (v[colours].toString(), false); - - for (int i = 0; i < colourSteps.size() / 2; ++i) - g.addColour (colourSteps[i * 2].getDoubleValue(), - Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); - - FillType fillType (g); - - if (g.isRadial) - { - const Point point3 (p3.resolve (nameFinder)); - const Point point3Source (g.point1.getX() + g.point2.getY() - g.point1.getY(), - g.point1.getY() + g.point1.getX() - g.point2.getX()); - - fillType.transform = AffineTransform::fromTargetPoints (g.point1.getX(), g.point1.getY(), g.point1.getX(), g.point1.getY(), - g.point2.getX(), g.point2.getY(), g.point2.getX(), g.point2.getY(), - point3Source.getX(), point3Source.getY(), point3.getX(), point3.getY()); - } - - return fillType; - } - else if (newType == "image") - { - Image im; - if (imageProvider != 0) - im = imageProvider->getImageForIdentifier (v[imageId]); - - FillType f (im, AffineTransform::identity); - f.setOpacity ((float) v.getProperty (imageOpacity, 1.0f)); - return f; - } - - jassertfalse; - return FillType(); -} - -static const Point calcThirdGradientPoint (const FillType& fillType) -{ - const ColourGradient& g = *fillType.gradient; - const Point point3Source (g.point1.getX() + g.point2.getY() - g.point1.getY(), - g.point1.getY() + g.point1.getX() - g.point2.getX()); - - return point3Source.transformedBy (fillType.transform); -} - -void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType, - const RelativePoint* const gp1, const RelativePoint* const gp2, const RelativePoint* gp3, - ImageProvider* imageProvider, UndoManager* const undoManager) -{ - if (fillType.isColour()) - { - v.setProperty (type, "solid", undoManager); - v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager); - } - else if (fillType.isGradient()) - { - v.setProperty (type, "gradient", undoManager); - v.setProperty (gradientPoint1, gp1 != 0 ? gp1->toString() : fillType.gradient->point1.toString(), undoManager); - v.setProperty (gradientPoint2, gp2 != 0 ? gp2->toString() : fillType.gradient->point2.toString(), undoManager); - v.setProperty (gradientPoint3, gp3 != 0 ? gp3->toString() : calcThirdGradientPoint (fillType).toString(), undoManager); - - v.setProperty (radial, fillType.gradient->isRadial, undoManager); - - String s; - for (int i = 0; i < fillType.gradient->getNumColours(); ++i) - s << ' ' << fillType.gradient->getColourPosition (i) - << ' ' << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); - - v.setProperty (colours, s.trimStart(), undoManager); - } - else if (fillType.isTiledImage()) - { - v.setProperty (type, "image", undoManager); - - if (imageProvider != 0) - v.setProperty (imageId, imageProvider->getIdentifierForImage (fillType.image), undoManager); - - if (fillType.getOpacity() < 1.0f) - v.setProperty (imageOpacity, fillType.getOpacity(), undoManager); - else - v.removeProperty (imageOpacity, undoManager); - } - else - { - jassertfalse; - } -} - END_JUCE_NAMESPACE diff --git a/src/gui/graphics/drawables/juce_Drawable.h b/src/gui/graphics/drawables/juce_Drawable.h index f159b13d84..3527b5e921 100644 --- a/src/gui/graphics/drawables/juce_Drawable.h +++ b/src/gui/graphics/drawables/juce_Drawable.h @@ -242,19 +242,7 @@ public: void setID (const String& newID, UndoManager* undoManager); static const Identifier idProperty; - static const FillType readFillType (const ValueTree& v, RelativePoint* gradientPoint1, - RelativePoint* gradientPoint2, RelativePoint* gradientPoint3, - Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider); - - static void writeFillType (ValueTree& v, const FillType& fillType, - const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2, - const RelativePoint* gradientPoint3, ImageProvider* imageProvider, - UndoManager* undoManager); - ValueTree state; - static const Identifier type, gradientPoint1, gradientPoint2, gradientPoint3, - colour, radial, colours, imageId, imageOpacity; }; //============================================================================== @@ -262,9 +250,11 @@ public: protected: friend class DrawableComposite; + /** @internal */ DrawableComposite* parent; + /** @internal */ virtual void invalidatePoints() = 0; - + /** @internal */ static Drawable* createChildFromValueTree (DrawableComposite* parent, const ValueTree& tree, ImageProvider* imageProvider); private: diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.h b/src/gui/graphics/drawables/juce_DrawableComposite.h index d99ab5eacf..b76db87f0e 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.h +++ b/src/gui/graphics/drawables/juce_DrawableComposite.h @@ -119,16 +119,16 @@ public: void bringToFront (int index); //============================================================================== - /** Changes the main content area. + /** Returns the main content rectangle. The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that sets them all at once. + "bottom", but this method is a shortcut that returns them all at once. @see contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName */ const RelativeRectangle getContentArea() const; - /** Returns the main content rectangle. + /** Changes the main content area. The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that returns them all at once. + "bottom", but this method is a shortcut that sets them all at once. @see setBoundingBox, contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName */ void setContentArea (const RelativeRectangle& newArea); @@ -233,11 +233,10 @@ public: void setMarker (bool xAxis, const Marker& marker, UndoManager* undoManager); void removeMarker (bool xAxis, const ValueTree& state, UndoManager* undoManager); - static const Identifier nameProperty, posProperty; + static const Identifier nameProperty, posProperty, topLeft, topRight, bottomLeft; private: - static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTagX, - markerGroupTagY, markerTag; + static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY, markerTag; ValueTree getChildList() const; ValueTree getChildListCreating (UndoManager* undoManager); diff --git a/src/gui/graphics/drawables/juce_DrawablePath.cpp b/src/gui/graphics/drawables/juce_DrawablePath.cpp index a700a0f949..7cda83b7a0 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.cpp +++ b/src/gui/graphics/drawables/juce_DrawablePath.cpp @@ -29,170 +29,63 @@ BEGIN_JUCE_NAMESPACE #include "juce_DrawablePath.h" #include "juce_DrawableComposite.h" -#include "../../../io/streams/juce_MemoryOutputStream.h" //============================================================================== DrawablePath::DrawablePath() - : mainFill (Colours::black), - strokeFill (Colours::black), - strokeType (0.0f), - pathNeedsUpdating (true), - strokeNeedsUpdating (true) { } DrawablePath::DrawablePath (const DrawablePath& other) - : mainFill (other.mainFill), - strokeFill (other.strokeFill), - strokeType (other.strokeType), - pathNeedsUpdating (true), - strokeNeedsUpdating (true) + : DrawableShape (other) { if (other.relativePath != 0) relativePath = new RelativePointPath (*other.relativePath); else - path = other.path; + cachedPath = other.cachedPath; } DrawablePath::~DrawablePath() { } -//============================================================================== -void DrawablePath::setPath (const Path& newPath) -{ - path = newPath; - strokeNeedsUpdating = true; -} - -void DrawablePath::setFill (const FillType& newFill) -{ - mainFill = newFill; -} - -void DrawablePath::setStrokeFill (const FillType& newFill) -{ - strokeFill = newFill; -} - -void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) -{ - strokeType = newStrokeType; - strokeNeedsUpdating = true; -} - -void DrawablePath::setStrokeThickness (const float newThickness) -{ - setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); -} - -void DrawablePath::updatePath() const +Drawable* DrawablePath::createCopy() const { - if (pathNeedsUpdating) - { - pathNeedsUpdating = false; - - if (relativePath != 0) - { - path.clear(); - relativePath->createPath (path, parent); - strokeNeedsUpdating = true; - } - } + return new DrawablePath (*this); } -void DrawablePath::updateStroke() const +//============================================================================== +void DrawablePath::setPath (const Path& newPath) { - if (strokeNeedsUpdating) - { - strokeNeedsUpdating = false; - updatePath(); - stroke.clear(); - strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); - } + cachedPath = newPath; + strokeChanged(); } const Path& DrawablePath::getPath() const { - updatePath(); - return path; + return getCachedPath(); } const Path& DrawablePath::getStrokePath() const { - updateStroke(); - return stroke; -} - -bool DrawablePath::isStrokeVisible() const throw() -{ - return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); -} - -void DrawablePath::invalidatePoints() -{ - pathNeedsUpdating = true; - strokeNeedsUpdating = true; + return getCachedStrokePath(); } -//============================================================================== -void DrawablePath::render (const Drawable::RenderingContext& context) const +bool DrawablePath::rebuildPath (Path& path) const { + if (relativePath != 0) { - FillType f (mainFill); - if (f.isGradient()) - f.gradient->multiplyOpacity (context.opacity); - else - f.setOpacity (f.getOpacity() * context.opacity); - - f.transform = f.transform.followedBy (context.transform); - context.g.setFillType (f); - context.g.fillPath (getPath(), context.transform); - } - - if (isStrokeVisible()) - { - FillType f (strokeFill); - if (f.isGradient()) - f.gradient->multiplyOpacity (context.opacity); - else - f.setOpacity (f.getOpacity() * context.opacity); - - f.transform = f.transform.followedBy (context.transform); - context.g.setFillType (f); - context.g.fillPath (getStrokePath(), context.transform); + path.clear(); + relativePath->createPath (path, parent); + return true; } -} -const Rectangle DrawablePath::getBounds() const -{ - if (isStrokeVisible()) - return getStrokePath().getBounds(); - else - return getPath().getBounds(); -} - -bool DrawablePath::hitTest (float x, float y) const -{ - return getPath().contains (x, y) - || (isStrokeVisible() && getStrokePath().contains (x, y)); -} - -Drawable* DrawablePath::createCopy() const -{ - return new DrawablePath (*this); + return false; } //============================================================================== const Identifier DrawablePath::valueTreeType ("Path"); -const Identifier DrawablePath::ValueTreeWrapper::fill ("Fill"); -const Identifier DrawablePath::ValueTreeWrapper::stroke ("Stroke"); -const Identifier DrawablePath::ValueTreeWrapper::path ("Path"); -const Identifier DrawablePath::ValueTreeWrapper::jointStyle ("jointStyle"); -const Identifier DrawablePath::ValueTreeWrapper::capStyle ("capStyle"); -const Identifier DrawablePath::ValueTreeWrapper::strokeWidth ("strokeWidth"); const Identifier DrawablePath::ValueTreeWrapper::nonZeroWinding ("nonZeroWinding"); const Identifier DrawablePath::ValueTreeWrapper::point1 ("p1"); const Identifier DrawablePath::ValueTreeWrapper::point2 ("p2"); @@ -200,7 +93,7 @@ const Identifier DrawablePath::ValueTreeWrapper::point3 ("p3"); //============================================================================== DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) + : FillAndStrokeState (state_) { jassert (state.hasType (valueTreeType)); } @@ -210,77 +103,6 @@ ValueTree DrawablePath::ValueTreeWrapper::getPathState() return state.getOrCreateChildWithName (path, 0); } -ValueTree DrawablePath::ValueTreeWrapper::getMainFillState() -{ - ValueTree v (state.getChildWithName (fill)); - if (v.isValid()) - return v; - - setMainFill (Colours::black, 0, 0, 0, 0, 0); - return getMainFillState(); -} - -ValueTree DrawablePath::ValueTreeWrapper::getStrokeFillState() -{ - ValueTree v (state.getChildWithName (stroke)); - if (v.isValid()) - return v; - - setStrokeFill (Colours::black, 0, 0, 0, 0, 0); - return getStrokeFillState(); -} - -const FillType DrawablePath::ValueTreeWrapper::getMainFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const -{ - return readFillType (state.getChildWithName (fill), 0, 0, 0, nameFinder, imageProvider); -} - -void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, const RelativePoint* gp1, - const RelativePoint* gp2, const RelativePoint* gp3, - ImageProvider* imageProvider, UndoManager* undoManager) -{ - ValueTree v (state.getOrCreateChildWithName (fill, undoManager)); - writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); -} - -const FillType DrawablePath::ValueTreeWrapper::getStrokeFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const -{ - return readFillType (state.getChildWithName (stroke), 0, 0, 0, nameFinder, imageProvider); -} - -void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, const RelativePoint* gp1, - const RelativePoint* gp2, const RelativePoint* gp3, - ImageProvider* imageProvider, UndoManager* undoManager) -{ - ValueTree v (state.getOrCreateChildWithName (stroke, undoManager)); - writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); -} - -const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const -{ - const String jointStyleString (state [jointStyle].toString()); - const String capStyleString (state [capStyle].toString()); - - return PathStrokeType (state [strokeWidth], - jointStyleString == "curved" ? PathStrokeType::curved - : (jointStyleString == "bevel" ? PathStrokeType::beveled - : PathStrokeType::mitered), - capStyleString == "square" ? PathStrokeType::square - : (capStyleString == "round" ? PathStrokeType::rounded - : PathStrokeType::butt)); -} - -void DrawablePath::ValueTreeWrapper::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) -{ - state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); - state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered - ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); - state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt - ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); -} - bool DrawablePath::ValueTreeWrapper::usesNonZeroWinding() const { return state [nonZeroWinding]; @@ -620,24 +442,7 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree ValueTreeWrapper v (tree); setName (v.getID()); - bool needsRedraw = false; - const FillType newFill (v.getMainFill (parent, imageProvider)); - - if (mainFill != newFill) - { - needsRedraw = true; - mainFill = newFill; - } - - const FillType newStrokeFill (v.getStrokeFill (parent, imageProvider)); - - if (strokeFill != newStrokeFill) - { - needsRedraw = true; - strokeFill = newStrokeFill; - } - - const PathStrokeType newStroke (v.getStrokeType()); + bool needsRedraw = refreshFillTypes (v, parent, imageProvider); ScopedPointer newRelativePath (new RelativePointPath (tree)); @@ -647,11 +452,12 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree if (! newRelativePath->containsAnyDynamicPoints()) newRelativePath = 0; - if (strokeType != newStroke || path != newPath) + const PathStrokeType newStroke (v.getStrokeType()); + if (strokeType != newStroke || cachedPath != newPath) { damageRect = getBounds(); - path.swapWithPath (newPath); - strokeNeedsUpdating = true; + cachedPath.swapWithPath (newPath); + strokeChanged(); strokeType = newStroke; needsRedraw = true; } @@ -670,9 +476,7 @@ const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) con ValueTreeWrapper v (tree); v.setID (getName(), 0); - v.setMainFill (mainFill, 0, 0, 0, imageProvider, 0); - v.setStrokeFill (strokeFill, 0, 0, 0, imageProvider, 0); - v.setStrokeType (strokeType, 0); + writeTo (v, imageProvider, 0); if (relativePath != 0) { @@ -680,7 +484,7 @@ const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) con } else { - RelativePointPath rp (path); + RelativePointPath rp (getCachedPath()); rp.writeTo (tree, 0); } diff --git a/src/gui/graphics/drawables/juce_DrawablePath.h b/src/gui/graphics/drawables/juce_DrawablePath.h index 21d874a603..c7e5b0d47e 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.h +++ b/src/gui/graphics/drawables/juce_DrawablePath.h @@ -26,18 +26,18 @@ #ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ #define __JUCE_DRAWABLEPATH_JUCEHEADER__ -#include "juce_Drawable.h" -#include "../colour/juce_ColourGradient.h" -#include "../contexts/juce_FillType.h" +#include "juce_DrawableShape.h" //============================================================================== /** A drawable object which renders a filled or outlined shape. - @see Drawable + For details on how to change the fill and stroke, see the DrawableShape class. + + @see Drawable, DrawableShape */ -class JUCE_API DrawablePath : public Drawable +class JUCE_API DrawablePath : public DrawableShape { public: //============================================================================== @@ -50,52 +50,10 @@ public: //============================================================================== /** Changes the path that will be drawn. - @see setFillColour, setStrokeType */ void setPath (const Path& newPath); - /** Sets a fill type for the path. - - This colour is used to fill the path - if you don't want the path to be - filled (e.g. if you're just drawing an outline), set this to a transparent - colour. - - @see setPath, setStrokeFill - */ - void setFill (const FillType& newFill); - - /** Returns the current fill type. - @see setFill - */ - const FillType& getFill() const throw() { return mainFill; } - - /** Sets the fill type with which the outline will be drawn. - @see setFill - */ - void setStrokeFill (const FillType& newStrokeFill); - - /** Returns the current stroke fill. - @see setStrokeFill - */ - const FillType& getStrokeFill() const throw() { return strokeFill; } - - /** Changes the properties of the outline that will be drawn around the path. - If the stroke has 0 thickness, no stroke will be drawn. - @see setStrokeThickness, setStrokeColour - */ - void setStrokeType (const PathStrokeType& newStrokeType); - - /** Changes the stroke thickness. - This is a shortcut for calling setStrokeType. - */ - void setStrokeThickness (float newThickness); - - /** Returns the current outline style. */ - const PathStrokeType& getStrokeType() const throw() { return strokeType; } - - - //============================================================================== /** Returns the current path. */ const Path& getPath() const; @@ -104,16 +62,8 @@ public: //============================================================================== /** @internal */ - void render (const Drawable::RenderingContext& context) const; - /** @internal */ - const Rectangle getBounds() const; - /** @internal */ - bool hitTest (float x, float y) const; - /** @internal */ Drawable* createCopy() const; /** @internal */ - void invalidatePoints(); - /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -124,28 +74,11 @@ public: //============================================================================== /** Internally-used class for wrapping a DrawablePath's state into a ValueTree. */ - class ValueTreeWrapper : public ValueTreeWrapperBase + class ValueTreeWrapper : public FillAndStrokeState { public: ValueTreeWrapper (const ValueTree& state); - const FillType getMainFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const; - ValueTree getMainFillState(); - void setMainFill (const FillType& newFill, const RelativePoint* gradientPoint1, - const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, - ImageProvider* imageProvider, UndoManager* undoManager); - - const FillType getStrokeFill (Expression::EvaluationContext* nameFinder, - ImageProvider* imageProvider) const; - ValueTree getStrokeFillState(); - void setStrokeFill (const FillType& newFill, const RelativePoint* gradientPoint1, - const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, - ImageProvider* imageProvider, UndoManager* undoManager); - - const PathStrokeType getStrokeType() const; - void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); - bool usesNonZeroWinding() const; void setUsesNonZeroWinding (bool b, UndoManager* undoManager); @@ -189,23 +122,17 @@ public: ValueTree getPathState(); - static const Identifier fill, stroke, path, jointStyle, capStyle, strokeWidth, - nonZeroWinding, point1, point2, point3; + static const Identifier nonZeroWinding, point1, point2, point3; }; //============================================================================== juce_UseDebuggingNewOperator +protected: + bool rebuildPath (Path& path) const; + private: - FillType mainFill, strokeFill; - PathStrokeType strokeType; ScopedPointer relativePath; - mutable Path path, stroke; - mutable bool pathNeedsUpdating, strokeNeedsUpdating; - - void updatePath() const; - void updateStroke() const; - bool isStrokeVisible() const throw(); DrawablePath& operator= (const DrawablePath&); }; diff --git a/src/gui/graphics/drawables/juce_DrawableRectangle.cpp b/src/gui/graphics/drawables/juce_DrawableRectangle.cpp new file mode 100644 index 0000000000..4eb0522d9c --- /dev/null +++ b/src/gui/graphics/drawables/juce_DrawableRectangle.cpp @@ -0,0 +1,189 @@ +/* + ============================================================================== + + 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_DrawableRectangle.h" +#include "juce_DrawableComposite.h" + +//============================================================================== +DrawableRectangle::DrawableRectangle() +{ +} + +DrawableRectangle::DrawableRectangle (const DrawableRectangle& other) + : DrawableShape (other) +{ +} + +DrawableRectangle::~DrawableRectangle() +{ +} + +Drawable* DrawableRectangle::createCopy() const +{ + return new DrawableRectangle (*this); +} + +//============================================================================== +void DrawableRectangle::setRectangle (const RelativeParallelogram& newBounds) +{ + bounds = newBounds; + pathChanged(); + strokeChanged(); +} + +void DrawableRectangle::setCornerSize (const RelativePoint& newSize) +{ + cornerSize = newSize; + pathChanged(); + strokeChanged(); +} + +//============================================================================== +bool DrawableRectangle::rebuildPath (Path& path) const +{ + Point points[3]; + bounds.resolveThreePoints (points, parent); + + const float w = Line (points[0], points[1]).getLength(); + const float h = Line (points[0], points[2]).getLength(); + + const float cornerSizeX = cornerSize.x.resolve (parent); + const float cornerSizeY = cornerSize.y.resolve (parent); + + path.clear(); + + if (cornerSizeX > 0 && cornerSizeY > 0) + path.addRoundedRectangle (0, 0, w, h, cornerSizeX, cornerSizeY); + else + path.addRectangle (0, 0, w, h); + + path.applyTransform (AffineTransform::fromTargetPoints (0, 0, points[0].getX(), points[0].getY(), + w, 0, points[1].getX(), points[1].getY(), + 0, h, points[2].getX(), points[2].getY())); + return true; +} + +const AffineTransform DrawableRectangle::calculateTransform() const +{ + Point resolved[3]; + bounds.resolveThreePoints (resolved, parent); + + return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), + resolved[1].getX(), resolved[1].getY(), + resolved[2].getX(), resolved[2].getY()); +} + +//============================================================================== +const Identifier DrawableRectangle::valueTreeType ("Rectangle"); +const Identifier DrawableRectangle::ValueTreeWrapper::topLeft ("topLeft"); +const Identifier DrawableRectangle::ValueTreeWrapper::topRight ("topRight"); +const Identifier DrawableRectangle::ValueTreeWrapper::bottomLeft ("bottomLeft"); +const Identifier DrawableRectangle::ValueTreeWrapper::cornerSize ("cornerSize"); + +//============================================================================== +DrawableRectangle::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : FillAndStrokeState (state_) +{ + jassert (state.hasType (valueTreeType)); +} + +const RelativeParallelogram DrawableRectangle::ValueTreeWrapper::getRectangle() const +{ + return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), + state.getProperty (topRight, "100, 0"), + state.getProperty (bottomLeft, "0, 100")); +} + +void DrawableRectangle::ValueTreeWrapper::setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager) +{ + state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); + state.setProperty (topRight, newBounds.topRight.toString(), undoManager); + state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); +} + +void DrawableRectangle::ValueTreeWrapper::setCornerSize (const RelativePoint& newSize, UndoManager* undoManager) +{ + state.setProperty (cornerSize, newSize.toString(), undoManager); +} + +const RelativePoint DrawableRectangle::ValueTreeWrapper::getCornerSize() const +{ + return RelativePoint (state [cornerSize]); +} + +Value DrawableRectangle::ValueTreeWrapper::getCornerSizeValue (UndoManager* undoManager) const +{ + return state.getPropertyAsValue (cornerSize, undoManager); +} + +//============================================================================== +const Rectangle DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +{ + Rectangle damageRect; + ValueTreeWrapper v (tree); + setName (v.getID()); + + bool needsRedraw = refreshFillTypes (v, parent, imageProvider); + + RelativeParallelogram newBounds (v.getRectangle()); + + const PathStrokeType newStroke (v.getStrokeType()); + const RelativePoint newCornerSize (v.getCornerSize()); + + if (strokeType != newStroke || newBounds != bounds || newCornerSize != cornerSize) + { + damageRect = getBounds(); + bounds = newBounds; + strokeType = newStroke; + cornerSize = newCornerSize; + pathChanged(); + strokeChanged(); + needsRedraw = true; + } + + if (needsRedraw) + damageRect = damageRect.getUnion (getBounds()); + + return damageRect; +} + +const ValueTree DrawableRectangle::createValueTree (ImageProvider* imageProvider) const +{ + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); + + v.setID (getName(), 0); + writeTo (v, imageProvider, 0); + v.setRectangle (bounds, 0); + v.setCornerSize (cornerSize, 0); + + return tree; +} + +END_JUCE_NAMESPACE diff --git a/src/gui/graphics/drawables/juce_DrawableRectangle.h b/src/gui/graphics/drawables/juce_DrawableRectangle.h new file mode 100644 index 0000000000..c8e067920d --- /dev/null +++ b/src/gui/graphics/drawables/juce_DrawableRectangle.h @@ -0,0 +1,109 @@ +/* + ============================================================================== + + 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_DRAWABLERECTANGLE_JUCEHEADER__ +#define __JUCE_DRAWABLERECTANGLE_JUCEHEADER__ + +#include "juce_DrawableShape.h" + + +//============================================================================== +/** + A Drawable object which draws a rectangle. + + For details on how to change the fill and stroke, see the DrawableShape class. + + @see Drawable, DrawableShape +*/ +class JUCE_API DrawableRectangle : public DrawableShape +{ +public: + //============================================================================== + DrawableRectangle(); + DrawableRectangle (const DrawableRectangle& other); + + /** Destructor. */ + ~DrawableRectangle(); + + //============================================================================== + /** Sets the rectangle's bounds. */ + void setRectangle (const RelativeParallelogram& newBounds); + + /** Returns the rectangle's bounds. */ + const RelativeParallelogram& getRectangle() const throw() { return bounds; } + + /** Returns the corner size to be used. */ + const RelativePoint getCornerSize() const { return cornerSize; } + + /** Sets a new corner size for the rectangle */ + void setCornerSize (const RelativePoint& newSize); + + //============================================================================== + /** @internal */ + Drawable* createCopy() const; + /** @internal */ + const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); + /** @internal */ + const ValueTree createValueTree (ImageProvider* imageProvider) const; + /** @internal */ + static const Identifier valueTreeType; + /** @internal */ + const Identifier getValueTreeType() const { return valueTreeType; } + + //============================================================================== + /** Internally-used class for wrapping a DrawableRectangle's state into a ValueTree. */ + class ValueTreeWrapper : public FillAndStrokeState + { + public: + ValueTreeWrapper (const ValueTree& state); + + const RelativeParallelogram getRectangle() const; + void setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager); + + void setCornerSize (const RelativePoint& cornerSize, UndoManager* undoManager); + const RelativePoint getCornerSize() const; + Value getCornerSizeValue (UndoManager* undoManager) const; + + static const Identifier topLeft, topRight, bottomLeft, cornerSize; + }; + + //============================================================================== + juce_UseDebuggingNewOperator + +protected: + /** @internal */ + bool rebuildPath (Path& path) const; + +private: + RelativeParallelogram bounds; + RelativePoint cornerSize; + + const AffineTransform calculateTransform() const; + + DrawableRectangle& operator= (const DrawableRectangle&); +}; + + +#endif // __JUCE_DRAWABLERECTANGLE_JUCEHEADER__ diff --git a/src/gui/graphics/drawables/juce_DrawableShape.cpp b/src/gui/graphics/drawables/juce_DrawableShape.cpp new file mode 100644 index 0000000000..381851839d --- /dev/null +++ b/src/gui/graphics/drawables/juce_DrawableShape.cpp @@ -0,0 +1,405 @@ +/* + ============================================================================== + + 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_DrawableShape.h" +#include "juce_DrawableComposite.h" + + +//============================================================================== +DrawableShape::DrawableShape() + : strokeType (0.0f), + mainFill (Colours::black), + strokeFill (Colours::black), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) +{ +} + +DrawableShape::DrawableShape (const DrawableShape& other) + : strokeType (other.strokeType), + mainFill (other.mainFill), + strokeFill (other.strokeFill), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) +{ +} + +DrawableShape::~DrawableShape() +{ +} + +void DrawableShape::setFill (const FillType& newFill) +{ + mainFill = newFill; +} + +void DrawableShape::setStrokeFill (const FillType& newFill) +{ + strokeFill = newFill; +} + +void DrawableShape::setStrokeType (const PathStrokeType& newStrokeType) +{ + strokeType = newStrokeType; + strokeNeedsUpdating = true; +} + +void DrawableShape::setStrokeThickness (const float newThickness) +{ + setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); +} + +bool DrawableShape::isStrokeVisible() const throw() +{ + return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); +} + +void DrawableShape::setBrush (const Drawable::RenderingContext& context, const FillType& type) +{ + FillType f (type); + if (f.isGradient()) + f.gradient->multiplyOpacity (context.opacity); + else + f.setOpacity (f.getOpacity() * context.opacity); + + f.transform = f.transform.followedBy (context.transform); + context.g.setFillType (f); +} + +bool DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, + Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) +{ + bool hasChanged = false; + + { + const FillType f (newState.getMainFill (parent, imageProvider)); + + if (mainFill != f) + { + hasChanged = true; + mainFill = f; + } + } + + { + const FillType f (newState.getStrokeFill (parent, imageProvider)); + + if (strokeFill != f) + { + hasChanged = true; + strokeFill = f; + } + } + + return hasChanged; +} + +void DrawableShape::writeTo (FillAndStrokeState& state, ImageProvider* imageProvider, UndoManager* undoManager) const +{ + state.setMainFill (mainFill, 0, 0, 0, imageProvider, undoManager); + state.setStrokeFill (strokeFill, 0, 0, 0, imageProvider, undoManager); + state.setStrokeType (strokeType, undoManager); +} + +//============================================================================== +void DrawableShape::render (const Drawable::RenderingContext& context) const +{ + setBrush (context, mainFill); + context.g.fillPath (getCachedPath(), context.transform); + + if (isStrokeVisible()) + { + setBrush (context, strokeFill); + context.g.fillPath (getCachedStrokePath(), context.transform); + } +} + +void DrawableShape::pathChanged() +{ + pathNeedsUpdating = true; +} + +void DrawableShape::strokeChanged() +{ + strokeNeedsUpdating = true; +} + +void DrawableShape::invalidatePoints() +{ + pathNeedsUpdating = true; + strokeNeedsUpdating = true; +} + +const Path& DrawableShape::getCachedPath() const +{ + if (pathNeedsUpdating) + { + pathNeedsUpdating = false; + + if (rebuildPath (cachedPath)) + strokeNeedsUpdating = true; + } + + return cachedPath; +} + +const Path& DrawableShape::getCachedStrokePath() const +{ + if (strokeNeedsUpdating) + { + cachedStroke.clear(); + strokeType.createStrokedPath (cachedStroke, getCachedPath(), AffineTransform::identity, 4.0f); + strokeNeedsUpdating = false; // (must be called after getCachedPath) + } + + return cachedStroke; +} + +const Rectangle DrawableShape::getBounds() const +{ + if (isStrokeVisible()) + return getCachedStrokePath().getBounds(); + else + return getCachedPath().getBounds(); +} + +bool DrawableShape::hitTest (float x, float y) const +{ + return getCachedPath().contains (x, y) + || (isStrokeVisible() && getCachedStrokePath().contains (x, y)); +} + + +//============================================================================== +const Identifier DrawableShape::FillAndStrokeState::type ("type"); +const Identifier DrawableShape::FillAndStrokeState::colour ("colour"); +const Identifier DrawableShape::FillAndStrokeState::colours ("colours"); +const Identifier DrawableShape::FillAndStrokeState::fill ("Fill"); +const Identifier DrawableShape::FillAndStrokeState::stroke ("Stroke"); +const Identifier DrawableShape::FillAndStrokeState::path ("Path"); +const Identifier DrawableShape::FillAndStrokeState::jointStyle ("jointStyle"); +const Identifier DrawableShape::FillAndStrokeState::capStyle ("capStyle"); +const Identifier DrawableShape::FillAndStrokeState::strokeWidth ("strokeWidth"); +const Identifier DrawableShape::FillAndStrokeState::gradientPoint1 ("point1"); +const Identifier DrawableShape::FillAndStrokeState::gradientPoint2 ("point2"); +const Identifier DrawableShape::FillAndStrokeState::gradientPoint3 ("point3"); +const Identifier DrawableShape::FillAndStrokeState::radial ("radial"); +const Identifier DrawableShape::FillAndStrokeState::imageId ("imageId"); +const Identifier DrawableShape::FillAndStrokeState::imageOpacity ("imageOpacity"); + +DrawableShape::FillAndStrokeState::FillAndStrokeState (const ValueTree& state_) + : Drawable::ValueTreeWrapperBase (state_) +{ +} + +const FillType DrawableShape::FillAndStrokeState::getMainFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const +{ + return readFillType (state.getChildWithName (fill), 0, 0, 0, nameFinder, imageProvider); +} + +ValueTree DrawableShape::FillAndStrokeState::getMainFillState() +{ + ValueTree v (state.getChildWithName (fill)); + if (v.isValid()) + return v; + + setMainFill (Colours::black, 0, 0, 0, 0, 0); + return getMainFillState(); +} + +void DrawableShape::FillAndStrokeState::setMainFill (const FillType& newFill, const RelativePoint* gp1, const RelativePoint* gp2, + const RelativePoint* gp3, ImageProvider* imageProvider, UndoManager* undoManager) +{ + ValueTree v (state.getOrCreateChildWithName (fill, undoManager)); + writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); +} + +const FillType DrawableShape::FillAndStrokeState::getStrokeFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const +{ + return readFillType (state.getChildWithName (stroke), 0, 0, 0, nameFinder, imageProvider); +} + +ValueTree DrawableShape::FillAndStrokeState::getStrokeFillState() +{ + ValueTree v (state.getChildWithName (stroke)); + if (v.isValid()) + return v; + + setStrokeFill (Colours::black, 0, 0, 0, 0, 0); + return getStrokeFillState(); +} + +void DrawableShape::FillAndStrokeState::setStrokeFill (const FillType& newFill, const RelativePoint* gp1, const RelativePoint* gp2, + const RelativePoint* gp3, ImageProvider* imageProvider, UndoManager* undoManager) +{ + ValueTree v (state.getOrCreateChildWithName (stroke, undoManager)); + writeFillType (v, newFill, gp1, gp2, gp3, imageProvider, undoManager); +} + +const PathStrokeType DrawableShape::FillAndStrokeState::getStrokeType() const +{ + const String jointStyleString (state [jointStyle].toString()); + const String capStyleString (state [capStyle].toString()); + + return PathStrokeType (state [strokeWidth], + jointStyleString == "curved" ? PathStrokeType::curved + : (jointStyleString == "bevel" ? PathStrokeType::beveled + : PathStrokeType::mitered), + capStyleString == "square" ? PathStrokeType::square + : (capStyleString == "round" ? PathStrokeType::rounded + : PathStrokeType::butt)); +} + +void DrawableShape::FillAndStrokeState::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) +{ + state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); + state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered + ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); + state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt + ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); +} + +const FillType DrawableShape::FillAndStrokeState::readFillType (const ValueTree& v, RelativePoint* const gp1, RelativePoint* const gp2, RelativePoint* const gp3, + Expression::EvaluationContext* const nameFinder, ImageProvider* imageProvider) +{ + const String newType (v[type].toString()); + + if (newType == "solid") + { + const String colourString (v [colour].toString()); + return FillType (Colour (colourString.isEmpty() ? (uint32) 0xff000000 + : (uint32) colourString.getHexValue32())); + } + else if (newType == "gradient") + { + RelativePoint p1 (v [gradientPoint1]), p2 (v [gradientPoint2]), p3 (v [gradientPoint3]); + + ColourGradient g; + + if (gp1 != 0) *gp1 = p1; + if (gp2 != 0) *gp2 = p2; + if (gp3 != 0) *gp3 = p3; + + g.point1 = p1.resolve (nameFinder); + g.point2 = p2.resolve (nameFinder); + g.isRadial = v[radial]; + + StringArray colourSteps; + colourSteps.addTokens (v[colours].toString(), false); + + for (int i = 0; i < colourSteps.size() / 2; ++i) + g.addColour (colourSteps[i * 2].getDoubleValue(), + Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); + + FillType fillType (g); + + if (g.isRadial) + { + const Point point3 (p3.resolve (nameFinder)); + const Point point3Source (g.point1.getX() + g.point2.getY() - g.point1.getY(), + g.point1.getY() + g.point1.getX() - g.point2.getX()); + + fillType.transform = AffineTransform::fromTargetPoints (g.point1.getX(), g.point1.getY(), g.point1.getX(), g.point1.getY(), + g.point2.getX(), g.point2.getY(), g.point2.getX(), g.point2.getY(), + point3Source.getX(), point3Source.getY(), point3.getX(), point3.getY()); + } + + return fillType; + } + else if (newType == "image") + { + Image im; + if (imageProvider != 0) + im = imageProvider->getImageForIdentifier (v[imageId]); + + FillType f (im, AffineTransform::identity); + f.setOpacity ((float) v.getProperty (imageOpacity, 1.0f)); + return f; + } + + jassert (! v.isValid()); + return FillType(); +} + +static const Point calcThirdGradientPoint (const FillType& fillType) +{ + const ColourGradient& g = *fillType.gradient; + const Point point3Source (g.point1.getX() + g.point2.getY() - g.point1.getY(), + g.point1.getY() + g.point1.getX() - g.point2.getX()); + + return point3Source.transformedBy (fillType.transform); +} + +void DrawableShape::FillAndStrokeState::writeFillType (ValueTree& v, const FillType& fillType, + const RelativePoint* const gp1, const RelativePoint* const gp2, const RelativePoint* gp3, + ImageProvider* imageProvider, UndoManager* const undoManager) +{ + if (fillType.isColour()) + { + v.setProperty (type, "solid", undoManager); + v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager); + } + else if (fillType.isGradient()) + { + v.setProperty (type, "gradient", undoManager); + v.setProperty (gradientPoint1, gp1 != 0 ? gp1->toString() : fillType.gradient->point1.toString(), undoManager); + v.setProperty (gradientPoint2, gp2 != 0 ? gp2->toString() : fillType.gradient->point2.toString(), undoManager); + v.setProperty (gradientPoint3, gp3 != 0 ? gp3->toString() : calcThirdGradientPoint (fillType).toString(), undoManager); + + v.setProperty (radial, fillType.gradient->isRadial, undoManager); + + String s; + for (int i = 0; i < fillType.gradient->getNumColours(); ++i) + s << ' ' << fillType.gradient->getColourPosition (i) + << ' ' << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); + + v.setProperty (colours, s.trimStart(), undoManager); + } + else if (fillType.isTiledImage()) + { + v.setProperty (type, "image", undoManager); + + if (imageProvider != 0) + v.setProperty (imageId, imageProvider->getIdentifierForImage (fillType.image), undoManager); + + if (fillType.getOpacity() < 1.0f) + v.setProperty (imageOpacity, fillType.getOpacity(), undoManager); + else + v.removeProperty (imageOpacity, undoManager); + } + else + { + jassertfalse; + } +} + +END_JUCE_NAMESPACE diff --git a/src/gui/graphics/drawables/juce_DrawableShape.h b/src/gui/graphics/drawables/juce_DrawableShape.h new file mode 100644 index 0000000000..9ea8667b8b --- /dev/null +++ b/src/gui/graphics/drawables/juce_DrawableShape.h @@ -0,0 +1,178 @@ +/* + ============================================================================== + + 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_DRAWABLESHAPE_JUCEHEADER__ +#define __JUCE_DRAWABLESHAPE_JUCEHEADER__ + +#include "juce_Drawable.h" +#include "../contexts/juce_FillType.h" +#include "../colour/juce_ColourGradient.h" + + +//============================================================================== +/** + A base class implementing common functionality for Drawable classes which + consist of some kind of filled and stroked outline. + + @see DrawablePath, DrawableRectangle +*/ +class JUCE_API DrawableShape : public Drawable +{ +protected: + //============================================================================== + DrawableShape(); + DrawableShape (const DrawableShape&); + +public: + /** Destructor. */ + ~DrawableShape(); + + //============================================================================== + /** Sets a fill type for the path. + This colour is used to fill the path - if you don't want the path to be + filled (e.g. if you're just drawing an outline), set this to a transparent + colour. + + @see setPath, setStrokeFill + */ + void setFill (const FillType& newFill); + + /** Returns the current fill type. + @see setFill + */ + const FillType& getFill() const throw() { return mainFill; } + + /** Sets the fill type with which the outline will be drawn. + @see setFill + */ + void setStrokeFill (const FillType& newStrokeFill); + + /** Returns the current stroke fill. + @see setStrokeFill + */ + const FillType& getStrokeFill() const throw() { return strokeFill; } + + /** Changes the properties of the outline that will be drawn around the path. + If the stroke has 0 thickness, no stroke will be drawn. + @see setStrokeThickness, setStrokeColour + */ + void setStrokeType (const PathStrokeType& newStrokeType); + + /** Changes the stroke thickness. + This is a shortcut for calling setStrokeType. + */ + void setStrokeThickness (float newThickness); + + /** Returns the current outline style. */ + const PathStrokeType& getStrokeType() const throw() { return strokeType; } + + //============================================================================== + /** @internal */ + class FillAndStrokeState : public ValueTreeWrapperBase + { + public: + FillAndStrokeState (const ValueTree& state); + + const FillType getMainFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const; + ValueTree getMainFillState(); + void setMainFill (const FillType& newFill, const RelativePoint* gradientPoint1, + const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, + ImageProvider* imageProvider, UndoManager* undoManager); + + const FillType getStrokeFill (Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider) const; + ValueTree getStrokeFillState(); + void setStrokeFill (const FillType& newFill, const RelativePoint* gradientPoint1, + const RelativePoint* gradientPoint2, const RelativePoint* gradientPoint3, + ImageProvider* imageProvider, UndoManager* undoManager); + + const PathStrokeType getStrokeType() const; + void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); + + static const FillType readFillType (const ValueTree& v, RelativePoint* gradientPoint1, + RelativePoint* gradientPoint2, RelativePoint* gradientPoint3, + Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider); + + static void writeFillType (ValueTree& v, const FillType& fillType, + const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2, + const RelativePoint* gradientPoint3, ImageProvider* imageProvider, + UndoManager* undoManager); + + static const Identifier type, colour, colours, fill, stroke, path, jointStyle, capStyle, strokeWidth, + gradientPoint1, gradientPoint2, gradientPoint3, radial, imageId, imageOpacity; + }; + + /** @internal */ + void invalidatePoints(); + /** @internal */ + void render (const Drawable::RenderingContext& context) const; + /** @internal */ + const Rectangle getBounds() const; + /** @internal */ + bool hitTest (float x, float y) const; + +protected: + //============================================================================== + /** Called when the cached path should be updated. */ + void pathChanged(); + /** Called when the cached stroke should be updated. */ + void strokeChanged(); + + /** Implemented by subclasses to regenerate the path. */ + virtual bool rebuildPath (Path& path) const = 0; + + /** True if there's a stroke with a non-zero thickness and non-transparent colour. */ + bool isStrokeVisible() const throw(); + + /** Updates the details from a FillAndStrokeState object, returning true if something changed. */ + bool refreshFillTypes (const FillAndStrokeState& newState, + Expression::EvaluationContext* nameFinder, + ImageProvider* imageProvider); + + /** Writes the stroke and fill details to a FillAndStrokeState object. */ + void writeTo (FillAndStrokeState& state, ImageProvider* imageProvider, UndoManager* undoManager) const; + + /** Returns the current cached path outline. */ + const Path& getCachedPath() const; + /** Returns the current cached stroke outline. */ + const Path& getCachedStrokePath() const; + + //============================================================================== + PathStrokeType strokeType; + mutable Path cachedPath, cachedStroke; + +private: + FillType mainFill, strokeFill; + mutable bool pathNeedsUpdating, strokeNeedsUpdating; + + static void setBrush (const Drawable::RenderingContext& context, const FillType& type); + + DrawableShape& operator= (const DrawableShape&); +}; + + +#endif // __JUCE_DRAWABLESHAPE_JUCEHEADER__ diff --git a/src/gui/graphics/drawables/juce_DrawableText.cpp b/src/gui/graphics/drawables/juce_DrawableText.cpp index b713abb3d5..36abfcca4c 100644 --- a/src/gui/graphics/drawables/juce_DrawableText.cpp +++ b/src/gui/graphics/drawables/juce_DrawableText.cpp @@ -106,8 +106,8 @@ void DrawableText::render (const Drawable::RenderingContext& context) const const float h = Line (points[0], points[2]).getLength(); const Point fontCoords (bounds.getInternalCoordForPoint (points, fontSizeControlPoint.resolve (parent))); - const float fontHeight = jlimit (1.0f, h, fontCoords.getY()); - const float fontWidth = jlimit (0.01f, w, fontCoords.getX()); + const float fontHeight = jlimit (0.01f, jmax (0.01f, h), fontCoords.getY()); + const float fontWidth = jlimit (0.01f, jmax (0.01f, w), fontCoords.getX()); Font f (font); f.setHeight (fontHeight); diff --git a/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp b/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp index 73edc2ba2f..322feac881 100644 --- a/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp +++ b/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp @@ -578,6 +578,11 @@ RelativeParallelogram::RelativeParallelogram() { } +RelativeParallelogram::RelativeParallelogram (const Rectangle& r) + : topLeft (r.getTopLeft()), topRight (r.getTopRight()), bottomLeft (r.getBottomLeft()) +{ +} + RelativeParallelogram::RelativeParallelogram (const RelativePoint& topLeft_, const RelativePoint& topRight_, const RelativePoint& bottomLeft_) : topLeft (topLeft_), topRight (topRight_), bottomLeft (bottomLeft_) { diff --git a/src/gui/graphics/geometry/juce_RelativeCoordinate.h b/src/gui/graphics/geometry/juce_RelativeCoordinate.h index da97322c9e..761180dfb1 100644 --- a/src/gui/graphics/geometry/juce_RelativeCoordinate.h +++ b/src/gui/graphics/geometry/juce_RelativeCoordinate.h @@ -438,6 +438,7 @@ class JUCE_API RelativeParallelogram public: //============================================================================== RelativeParallelogram(); + RelativeParallelogram (const Rectangle& simpleRectangle); RelativeParallelogram (const RelativePoint& topLeft, const RelativePoint& topRight, const RelativePoint& bottomLeft); RelativeParallelogram (const String& topLeft, const String& topRight, const String& bottomLeft); ~RelativeParallelogram(); diff --git a/src/juce_app_includes.h b/src/juce_app_includes.h index 506012918a..e2bc9766b3 100644 --- a/src/juce_app_includes.h +++ b/src/juce_app_includes.h @@ -659,6 +659,12 @@ #ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ #include "gui/graphics/drawables/juce_DrawablePath.h" #endif +#ifndef __JUCE_DRAWABLERECTANGLE_JUCEHEADER__ + #include "gui/graphics/drawables/juce_DrawableRectangle.h" +#endif +#ifndef __JUCE_DRAWABLESHAPE_JUCEHEADER__ + #include "gui/graphics/drawables/juce_DrawableShape.h" +#endif #ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ #include "gui/graphics/drawables/juce_DrawableText.h" #endif