| @@ -502,6 +502,7 @@ | |||
| 9BD379D2F7995BFE0B3E5369 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_PropertySet.cpp; path = ../../src/containers/juce_PropertySet.cpp; sourceTree = SOURCE_ROOT; }; | |||
| C8F0F54CA3D913E7B8D559CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_PropertySet.h; path = ../../src/containers/juce_PropertySet.h; sourceTree = SOURCE_ROOT; }; | |||
| D7612CE51ED4F9D3F960F922 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ReferenceCountedArray.h; path = ../../src/containers/juce_ReferenceCountedArray.h; sourceTree = SOURCE_ROOT; }; | |||
| F95BC2FA7861CFF968D661ED = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedValueSetter.h; path = ../../src/containers/juce_ScopedValueSetter.h; sourceTree = SOURCE_ROOT; }; | |||
| 2F5FD1DEFAE549553A8BE3B1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_SortedSet.h; path = ../../src/containers/juce_SortedSet.h; sourceTree = SOURCE_ROOT; }; | |||
| 989E03031D341649B4A296F5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_SparseSet.h; path = ../../src/containers/juce_SparseSet.h; sourceTree = SOURCE_ROOT; }; | |||
| 1809284DD05B56309D7EA24F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Value.cpp; path = ../../src/containers/juce_Value.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1239,6 +1240,7 @@ | |||
| 9BD379D2F7995BFE0B3E5369, | |||
| C8F0F54CA3D913E7B8D559CF, | |||
| D7612CE51ED4F9D3F960F922, | |||
| F95BC2FA7861CFF968D661ED, | |||
| 2F5FD1DEFAE549553A8BE3B1, | |||
| 989E03031D341649B4A296F5, | |||
| 1809284DD05B56309D7EA24F, | |||
| @@ -360,6 +360,7 @@ | |||
| <File RelativePath="..\..\src\containers\juce_PropertySet.cpp"/> | |||
| <File RelativePath="..\..\src\containers\juce_PropertySet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_ReferenceCountedArray.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_ScopedValueSetter.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_SortedSet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_SparseSet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_Value.cpp"/> | |||
| @@ -360,6 +360,7 @@ | |||
| <File RelativePath="..\..\src\containers\juce_PropertySet.cpp"/> | |||
| <File RelativePath="..\..\src\containers\juce_PropertySet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_ReferenceCountedArray.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_ScopedValueSetter.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_SortedSet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_SparseSet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_Value.cpp"/> | |||
| @@ -362,6 +362,7 @@ | |||
| <File RelativePath="..\..\src\containers\juce_PropertySet.cpp"/> | |||
| <File RelativePath="..\..\src\containers\juce_PropertySet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_ReferenceCountedArray.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_ScopedValueSetter.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_SortedSet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_SparseSet.h"/> | |||
| <File RelativePath="..\..\src\containers\juce_Value.cpp"/> | |||
| @@ -519,6 +519,7 @@ | |||
| <ClInclude Include="..\..\src\containers\juce_OwnedArray.h"/> | |||
| <ClInclude Include="..\..\src\containers\juce_PropertySet.h"/> | |||
| <ClInclude Include="..\..\src\containers\juce_ReferenceCountedArray.h"/> | |||
| <ClInclude Include="..\..\src\containers\juce_ScopedValueSetter.h"/> | |||
| <ClInclude Include="..\..\src\containers\juce_SortedSet.h"/> | |||
| <ClInclude Include="..\..\src\containers\juce_SparseSet.h"/> | |||
| <ClInclude Include="..\..\src\containers\juce_Value.h"/> | |||
| @@ -1488,6 +1488,9 @@ | |||
| <ClInclude Include="..\..\src\containers\juce_ReferenceCountedArray.h"> | |||
| <Filter>Juce\Source\containers</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\containers\juce_ScopedValueSetter.h"> | |||
| <Filter>Juce\Source\containers</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\containers\juce_SortedSet.h"> | |||
| <Filter>Juce\Source\containers</Filter> | |||
| </ClInclude> | |||
| @@ -502,6 +502,7 @@ | |||
| 9BD379D2F7995BFE0B3E5369 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_PropertySet.cpp; path = ../../src/containers/juce_PropertySet.cpp; sourceTree = SOURCE_ROOT; }; | |||
| C8F0F54CA3D913E7B8D559CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_PropertySet.h; path = ../../src/containers/juce_PropertySet.h; sourceTree = SOURCE_ROOT; }; | |||
| D7612CE51ED4F9D3F960F922 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ReferenceCountedArray.h; path = ../../src/containers/juce_ReferenceCountedArray.h; sourceTree = SOURCE_ROOT; }; | |||
| F95BC2FA7861CFF968D661ED = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ScopedValueSetter.h; path = ../../src/containers/juce_ScopedValueSetter.h; sourceTree = SOURCE_ROOT; }; | |||
| 2F5FD1DEFAE549553A8BE3B1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_SortedSet.h; path = ../../src/containers/juce_SortedSet.h; sourceTree = SOURCE_ROOT; }; | |||
| 989E03031D341649B4A296F5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_SparseSet.h; path = ../../src/containers/juce_SparseSet.h; sourceTree = SOURCE_ROOT; }; | |||
| 1809284DD05B56309D7EA24F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Value.cpp; path = ../../src/containers/juce_Value.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1239,6 +1240,7 @@ | |||
| 9BD379D2F7995BFE0B3E5369, | |||
| C8F0F54CA3D913E7B8D559CF, | |||
| D7612CE51ED4F9D3F960F922, | |||
| F95BC2FA7861CFF968D661ED, | |||
| 2F5FD1DEFAE549553A8BE3B1, | |||
| 989E03031D341649B4A296F5, | |||
| 1809284DD05B56309D7EA24F, | |||
| @@ -379,6 +379,8 @@ | |||
| file="src/containers/juce_PropertySet.h"/> | |||
| <FILE id="q1WQH39S3" name="juce_ReferenceCountedArray.h" compile="0" | |||
| resource="0" file="src/containers/juce_ReferenceCountedArray.h"/> | |||
| <FILE id="YcflQG" name="juce_ScopedValueSetter.h" compile="0" resource="0" | |||
| file="src/containers/juce_ScopedValueSetter.h"/> | |||
| <FILE id="CPW4LfoeP" name="juce_SortedSet.h" compile="0" resource="0" | |||
| file="src/containers/juce_SortedSet.h"/> | |||
| <FILE id="jo9VOycN5" name="juce_SparseSet.h" compile="0" resource="0" | |||
| @@ -20356,21 +20356,22 @@ bool UndoManager::undo() | |||
| if (commandSet == 0) | |||
| return false; | |||
| reentrancyCheck = true; | |||
| bool failed = false; | |||
| for (int i = commandSet->size(); --i >= 0;) | |||
| { | |||
| if (! commandSet->getUnchecked(i)->undo()) | |||
| const ScopedValueSetter<bool> setter (reentrancyCheck, true); | |||
| for (int i = commandSet->size(); --i >= 0;) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| if (! commandSet->getUnchecked(i)->undo()) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| reentrancyCheck = false; | |||
| if (failed) | |||
| clearUndoHistory(); | |||
| else | |||
| @@ -20389,21 +20390,22 @@ bool UndoManager::redo() | |||
| if (commandSet == 0) | |||
| return false; | |||
| reentrancyCheck = true; | |||
| bool failed = false; | |||
| for (int i = 0; i < commandSet->size(); ++i) | |||
| { | |||
| if (! commandSet->getUnchecked(i)->perform()) | |||
| const ScopedValueSetter<bool> setter (reentrancyCheck, true); | |||
| for (int i = 0; i < commandSet->size(); ++i) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| if (! commandSet->getUnchecked(i)->perform()) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| reentrancyCheck = false; | |||
| if (failed) | |||
| clearUndoHistory(); | |||
| else | |||
| @@ -61891,7 +61893,7 @@ void ComponentMovementWatcher::componentParentHierarchyChanged (Component&) | |||
| { | |||
| if (component != 0 && ! reentrant) | |||
| { | |||
| reentrant = true; | |||
| const ScopedValueSetter<bool> setter (reentrant, true); | |||
| ComponentPeer* const peer = component->getPeer(); | |||
| @@ -61912,8 +61914,6 @@ void ComponentMovementWatcher::componentParentHierarchyChanged (Component&) | |||
| if (component != 0) | |||
| componentVisibilityChanged (*component); | |||
| reentrant = false; | |||
| } | |||
| } | |||
| @@ -74576,8 +74576,6 @@ void DropShadower::updateShadows() | |||
| if (reentrant || owner == 0) | |||
| return; | |||
| reentrant = true; | |||
| ComponentPeer* const peer = owner->getPeer(); | |||
| const bool isOwnerVisible = owner->isVisible() && (peer == 0 || ! peer->isMinimised()); | |||
| @@ -74588,81 +74586,83 @@ void DropShadower::updateShadows() | |||
| && (Desktop::canUseSemiTransparentWindows() | |||
| || owner->getParentComponent() != 0); | |||
| const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius; | |||
| if (createShadowWindows) | |||
| { | |||
| // keep a cached version of the image to save doing the gaussian too often | |||
| String imageId; | |||
| imageId << shadowEdge << ',' << xOffset << ',' << yOffset << ',' << alpha; | |||
| const int hash = imageId.hashCode(); | |||
| const ScopedValueSetter<bool> setter (reentrant, true, false); | |||
| Image bigIm (ImageCache::getFromHashCode (hash)); | |||
| const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius; | |||
| if (bigIm.isNull()) | |||
| if (createShadowWindows) | |||
| { | |||
| bigIm = Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true, Image::NativeImage); | |||
| // keep a cached version of the image to save doing the gaussian too often | |||
| String imageId; | |||
| imageId << shadowEdge << ',' << xOffset << ',' << yOffset << ',' << alpha; | |||
| Graphics bigG (bigIm); | |||
| bigG.setColour (Colours::black.withAlpha (alpha)); | |||
| bigG.fillRect (shadowEdge + xOffset, | |||
| shadowEdge + yOffset, | |||
| bigIm.getWidth() - (shadowEdge * 2), | |||
| bigIm.getHeight() - (shadowEdge * 2)); | |||
| const int hash = imageId.hashCode(); | |||
| ImageConvolutionKernel blurKernel (roundToInt (blurRadius * 2.0f)); | |||
| blurKernel.createGaussianBlur (blurRadius); | |||
| Image bigIm (ImageCache::getFromHashCode (hash)); | |||
| blurKernel.applyToImage (bigIm, bigIm, | |||
| Rectangle<int> (xOffset, yOffset, | |||
| bigIm.getWidth(), bigIm.getHeight())); | |||
| if (bigIm.isNull()) | |||
| { | |||
| bigIm = Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true, Image::NativeImage); | |||
| ImageCache::addImageToCache (bigIm, hash); | |||
| } | |||
| Graphics bigG (bigIm); | |||
| bigG.setColour (Colours::black.withAlpha (alpha)); | |||
| bigG.fillRect (shadowEdge + xOffset, | |||
| shadowEdge + yOffset, | |||
| bigIm.getWidth() - (shadowEdge * 2), | |||
| bigIm.getHeight() - (shadowEdge * 2)); | |||
| const int iw = bigIm.getWidth(); | |||
| const int ih = bigIm.getHeight(); | |||
| const int shadowEdge2 = shadowEdge * 2; | |||
| ImageConvolutionKernel blurKernel (roundToInt (blurRadius * 2.0f)); | |||
| blurKernel.createGaussianBlur (blurRadius); | |||
| setShadowImage (bigIm, 0, shadowEdge, shadowEdge2, 0, 0); | |||
| setShadowImage (bigIm, 1, shadowEdge, shadowEdge2, 0, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 2, shadowEdge, shadowEdge, 0, shadowEdge2); | |||
| setShadowImage (bigIm, 3, shadowEdge, shadowEdge2, iw - shadowEdge, 0); | |||
| setShadowImage (bigIm, 4, shadowEdge, shadowEdge2, iw - shadowEdge, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 5, shadowEdge, shadowEdge, iw - shadowEdge, shadowEdge2); | |||
| setShadowImage (bigIm, 6, shadowEdge, shadowEdge, shadowEdge, 0); | |||
| setShadowImage (bigIm, 7, shadowEdge, shadowEdge, iw - shadowEdge2, 0); | |||
| setShadowImage (bigIm, 8, shadowEdge, shadowEdge, shadowEdge2, 0); | |||
| setShadowImage (bigIm, 9, shadowEdge, shadowEdge, shadowEdge, ih - shadowEdge); | |||
| setShadowImage (bigIm, 10, shadowEdge, shadowEdge, iw - shadowEdge2, ih - shadowEdge); | |||
| setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge); | |||
| blurKernel.applyToImage (bigIm, bigIm, | |||
| Rectangle<int> (xOffset, yOffset, | |||
| bigIm.getWidth(), bigIm.getHeight())); | |||
| for (int i = 0; i < 4; ++i) | |||
| shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections)); | |||
| } | |||
| ImageCache::addImageToCache (bigIm, hash); | |||
| } | |||
| if (shadowWindows.size() >= 4) | |||
| { | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| { | |||
| shadowWindows.getUnchecked(i)->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows.getUnchecked(i)->setVisible (isOwnerVisible); | |||
| const int iw = bigIm.getWidth(); | |||
| const int ih = bigIm.getHeight(); | |||
| const int shadowEdge2 = shadowEdge * 2; | |||
| setShadowImage (bigIm, 0, shadowEdge, shadowEdge2, 0, 0); | |||
| setShadowImage (bigIm, 1, shadowEdge, shadowEdge2, 0, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 2, shadowEdge, shadowEdge, 0, shadowEdge2); | |||
| setShadowImage (bigIm, 3, shadowEdge, shadowEdge2, iw - shadowEdge, 0); | |||
| setShadowImage (bigIm, 4, shadowEdge, shadowEdge2, iw - shadowEdge, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 5, shadowEdge, shadowEdge, iw - shadowEdge, shadowEdge2); | |||
| setShadowImage (bigIm, 6, shadowEdge, shadowEdge, shadowEdge, 0); | |||
| setShadowImage (bigIm, 7, shadowEdge, shadowEdge, iw - shadowEdge2, 0); | |||
| setShadowImage (bigIm, 8, shadowEdge, shadowEdge, shadowEdge2, 0); | |||
| setShadowImage (bigIm, 9, shadowEdge, shadowEdge, shadowEdge, ih - shadowEdge); | |||
| setShadowImage (bigIm, 10, shadowEdge, shadowEdge, iw - shadowEdge2, ih - shadowEdge); | |||
| setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge); | |||
| for (int i = 0; i < 4; ++i) | |||
| shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections)); | |||
| } | |||
| const int x = owner->getX(); | |||
| const int y = owner->getY() - shadowEdge; | |||
| const int w = owner->getWidth(); | |||
| const int h = owner->getHeight() + shadowEdge + shadowEdge; | |||
| if (shadowWindows.size() >= 4) | |||
| { | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| { | |||
| shadowWindows.getUnchecked(i)->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows.getUnchecked(i)->setVisible (isOwnerVisible); | |||
| } | |||
| const int x = owner->getX(); | |||
| const int y = owner->getY() - shadowEdge; | |||
| const int w = owner->getWidth(); | |||
| const int h = owner->getHeight() + shadowEdge + shadowEdge; | |||
| shadowWindows.getUnchecked(0)->setBounds (x - shadowEdge, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(1)->setBounds (x + w, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(2)->setBounds (x, y, w, shadowEdge); | |||
| shadowWindows.getUnchecked(3)->setBounds (x, owner->getBottom(), w, shadowEdge); | |||
| shadowWindows.getUnchecked(0)->setBounds (x - shadowEdge, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(1)->setBounds (x + w, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(2)->setBounds (x, y, w, shadowEdge); | |||
| shadowWindows.getUnchecked(3)->setBounds (x, owner->getBottom(), w, shadowEdge); | |||
| } | |||
| } | |||
| reentrant = false; | |||
| if (createShadowWindows) | |||
| bringShadowWindowsToFront(); | |||
| } | |||
| @@ -74682,12 +74682,10 @@ void DropShadower::bringShadowWindowsToFront() | |||
| { | |||
| updateShadows(); | |||
| reentrant = true; | |||
| const ScopedValueSetter<bool> setter (reentrant, true, false); | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| shadowWindows.getUnchecked(i)->toBehind (owner); | |||
| reentrant = false; | |||
| } | |||
| } | |||
| @@ -86790,22 +86788,11 @@ void DrawableComposite::childrenChanged() | |||
| updateBoundsToFitChildren(); | |||
| } | |||
| struct RentrancyCheckSetter | |||
| { | |||
| RentrancyCheckSetter (bool& b_) : b (b_) { b_ = true; } | |||
| ~RentrancyCheckSetter() { b = false; } | |||
| private: | |||
| bool& b; | |||
| JUCE_DECLARE_NON_COPYABLE (RentrancyCheckSetter); | |||
| }; | |||
| void DrawableComposite::updateBoundsToFitChildren() | |||
| { | |||
| if (! updateBoundsReentrant) | |||
| { | |||
| const RentrancyCheckSetter checkSetter (updateBoundsReentrant); | |||
| const ScopedValueSetter<bool> setter (updateBoundsReentrant, true, false); | |||
| Rectangle<int> childArea; | |||
| @@ -242959,7 +242946,7 @@ private: | |||
| return; | |||
| } | |||
| reentrant = true; | |||
| const ScopedValueSetter<bool> setter (reentrant, true, false); | |||
| // this is the rectangle to update.. | |||
| int x = paintStruct.rcPaint.left; | |||
| @@ -243063,7 +243050,6 @@ private: | |||
| DeleteObject (rgn); | |||
| EndPaint (hwnd, &paintStruct); | |||
| reentrant = false; | |||
| } | |||
| #ifndef JUCE_GCC //xxx should add this fn for gcc.. | |||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 53 | |||
| #define JUCE_BUILDNUMBER 11 | |||
| #define JUCE_BUILDNUMBER 12 | |||
| /** Current Juce version number. | |||
| @@ -11332,6 +11332,82 @@ private: | |||
| /*** End of inlined file: juce_ReferenceCountedArray.h ***/ | |||
| #endif | |||
| #ifndef __JUCE_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| /*** Start of inlined file: juce_ScopedValueSetter.h ***/ | |||
| #ifndef __JUCE_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| #define __JUCE_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| /** | |||
| Helper class providing an RAII-based mechanism for temporarily setting and | |||
| then re-setting a value. | |||
| E.g. @code | |||
| int x = 1; | |||
| { | |||
| ScopedValueSetter setter (x, 2); | |||
| // x is now 2 | |||
| } | |||
| // x is now 1 again | |||
| { | |||
| ScopedValueSetter setter (x, 3, 4); | |||
| // x is now 3 | |||
| } | |||
| // x is now 4 | |||
| @endcode | |||
| */ | |||
| template <typename ValueType> | |||
| class ScopedValueSetter | |||
| { | |||
| public: | |||
| /** Creates a ScopedValueSetter that will immediately change the specified value to the | |||
| given new value, and will then reset it to its original value when this object is deleted. | |||
| */ | |||
| ScopedValueSetter (ValueType& valueToSet, | |||
| const ValueType& newValue) | |||
| : value (valueToSet), | |||
| originalValue (valueToSet) | |||
| { | |||
| valueToSet = newValue; | |||
| } | |||
| /** Creates a ScopedValueSetter that will immediately change the specified value to the | |||
| given new value, and will then reset it to be valueWhenDeleted when this object is deleted. | |||
| */ | |||
| ScopedValueSetter (ValueType& valueToSet, | |||
| const ValueType& newValue, | |||
| const ValueType& valueWhenDeleted) | |||
| : value (valueToSet), | |||
| originalValue (valueWhenDeleted) | |||
| { | |||
| valueToSet = newValue; | |||
| } | |||
| ~ScopedValueSetter() | |||
| { | |||
| value = originalValue; | |||
| } | |||
| private: | |||
| ValueType& value; | |||
| const ValueType originalValue; | |||
| JUCE_DECLARE_NON_COPYABLE (ScopedValueSetter); | |||
| }; | |||
| #endif // __JUCE_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| /*** End of inlined file: juce_ScopedValueSetter.h ***/ | |||
| #endif | |||
| #ifndef __JUCE_SORTEDSET_JUCEHEADER__ | |||
| @@ -0,0 +1,97 @@ | |||
| /* | |||
| ============================================================================== | |||
| 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_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| #define __JUCE_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| //============================================================================== | |||
| /** | |||
| Helper class providing an RAII-based mechanism for temporarily setting and | |||
| then re-setting a value. | |||
| E.g. @code | |||
| int x = 1; | |||
| { | |||
| ScopedValueSetter setter (x, 2); | |||
| // x is now 2 | |||
| } | |||
| // x is now 1 again | |||
| { | |||
| ScopedValueSetter setter (x, 3, 4); | |||
| // x is now 3 | |||
| } | |||
| // x is now 4 | |||
| @endcode | |||
| */ | |||
| template <typename ValueType> | |||
| class ScopedValueSetter | |||
| { | |||
| public: | |||
| /** Creates a ScopedValueSetter that will immediately change the specified value to the | |||
| given new value, and will then reset it to its original value when this object is deleted. | |||
| */ | |||
| ScopedValueSetter (ValueType& valueToSet, | |||
| const ValueType& newValue) | |||
| : value (valueToSet), | |||
| originalValue (valueToSet) | |||
| { | |||
| valueToSet = newValue; | |||
| } | |||
| /** Creates a ScopedValueSetter that will immediately change the specified value to the | |||
| given new value, and will then reset it to be valueWhenDeleted when this object is deleted. | |||
| */ | |||
| ScopedValueSetter (ValueType& valueToSet, | |||
| const ValueType& newValue, | |||
| const ValueType& valueWhenDeleted) | |||
| : value (valueToSet), | |||
| originalValue (valueWhenDeleted) | |||
| { | |||
| valueToSet = newValue; | |||
| } | |||
| ~ScopedValueSetter() | |||
| { | |||
| value = originalValue; | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| ValueType& value; | |||
| const ValueType originalValue; | |||
| JUCE_DECLARE_NON_COPYABLE (ScopedValueSetter); | |||
| }; | |||
| #endif // __JUCE_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 53 | |||
| #define JUCE_BUILDNUMBER 11 | |||
| #define JUCE_BUILDNUMBER 12 | |||
| /** Current Juce version number. | |||
| @@ -28,6 +28,7 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "juce_ComponentMovementWatcher.h" | |||
| #include "../../../containers/juce_ScopedValueSetter.h" | |||
| //============================================================================== | |||
| @@ -57,7 +58,7 @@ void ComponentMovementWatcher::componentParentHierarchyChanged (Component&) | |||
| { | |||
| if (component != 0 && ! reentrant) | |||
| { | |||
| reentrant = true; | |||
| const ScopedValueSetter<bool> setter (reentrant, true); | |||
| ComponentPeer* const peer = component->getPeer(); | |||
| @@ -78,8 +79,6 @@ void ComponentMovementWatcher::componentParentHierarchyChanged (Component&) | |||
| if (component != 0) | |||
| componentVisibilityChanged (*component); | |||
| reentrant = false; | |||
| } | |||
| } | |||
| @@ -33,6 +33,7 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "../../graphics/imaging/juce_Image.h" | |||
| #include "../juce_Desktop.h" | |||
| #include "../windows/juce_ComponentPeer.h" | |||
| #include "../../../containers/juce_ScopedValueSetter.h" | |||
| //============================================================================== | |||
| @@ -179,8 +180,6 @@ void DropShadower::updateShadows() | |||
| if (reentrant || owner == 0) | |||
| return; | |||
| reentrant = true; | |||
| ComponentPeer* const peer = owner->getPeer(); | |||
| const bool isOwnerVisible = owner->isVisible() && (peer == 0 || ! peer->isMinimised()); | |||
| @@ -191,81 +190,83 @@ void DropShadower::updateShadows() | |||
| && (Desktop::canUseSemiTransparentWindows() | |||
| || owner->getParentComponent() != 0); | |||
| const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius; | |||
| if (createShadowWindows) | |||
| { | |||
| // keep a cached version of the image to save doing the gaussian too often | |||
| String imageId; | |||
| imageId << shadowEdge << ',' << xOffset << ',' << yOffset << ',' << alpha; | |||
| const int hash = imageId.hashCode(); | |||
| const ScopedValueSetter<bool> setter (reentrant, true, false); | |||
| Image bigIm (ImageCache::getFromHashCode (hash)); | |||
| const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius; | |||
| if (bigIm.isNull()) | |||
| if (createShadowWindows) | |||
| { | |||
| bigIm = Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true, Image::NativeImage); | |||
| Graphics bigG (bigIm); | |||
| bigG.setColour (Colours::black.withAlpha (alpha)); | |||
| bigG.fillRect (shadowEdge + xOffset, | |||
| shadowEdge + yOffset, | |||
| bigIm.getWidth() - (shadowEdge * 2), | |||
| bigIm.getHeight() - (shadowEdge * 2)); | |||
| ImageConvolutionKernel blurKernel (roundToInt (blurRadius * 2.0f)); | |||
| blurKernel.createGaussianBlur (blurRadius); | |||
| blurKernel.applyToImage (bigIm, bigIm, | |||
| Rectangle<int> (xOffset, yOffset, | |||
| bigIm.getWidth(), bigIm.getHeight())); | |||
| ImageCache::addImageToCache (bigIm, hash); | |||
| // keep a cached version of the image to save doing the gaussian too often | |||
| String imageId; | |||
| imageId << shadowEdge << ',' << xOffset << ',' << yOffset << ',' << alpha; | |||
| const int hash = imageId.hashCode(); | |||
| Image bigIm (ImageCache::getFromHashCode (hash)); | |||
| if (bigIm.isNull()) | |||
| { | |||
| bigIm = Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true, Image::NativeImage); | |||
| Graphics bigG (bigIm); | |||
| bigG.setColour (Colours::black.withAlpha (alpha)); | |||
| bigG.fillRect (shadowEdge + xOffset, | |||
| shadowEdge + yOffset, | |||
| bigIm.getWidth() - (shadowEdge * 2), | |||
| bigIm.getHeight() - (shadowEdge * 2)); | |||
| ImageConvolutionKernel blurKernel (roundToInt (blurRadius * 2.0f)); | |||
| blurKernel.createGaussianBlur (blurRadius); | |||
| blurKernel.applyToImage (bigIm, bigIm, | |||
| Rectangle<int> (xOffset, yOffset, | |||
| bigIm.getWidth(), bigIm.getHeight())); | |||
| ImageCache::addImageToCache (bigIm, hash); | |||
| } | |||
| const int iw = bigIm.getWidth(); | |||
| const int ih = bigIm.getHeight(); | |||
| const int shadowEdge2 = shadowEdge * 2; | |||
| setShadowImage (bigIm, 0, shadowEdge, shadowEdge2, 0, 0); | |||
| setShadowImage (bigIm, 1, shadowEdge, shadowEdge2, 0, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 2, shadowEdge, shadowEdge, 0, shadowEdge2); | |||
| setShadowImage (bigIm, 3, shadowEdge, shadowEdge2, iw - shadowEdge, 0); | |||
| setShadowImage (bigIm, 4, shadowEdge, shadowEdge2, iw - shadowEdge, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 5, shadowEdge, shadowEdge, iw - shadowEdge, shadowEdge2); | |||
| setShadowImage (bigIm, 6, shadowEdge, shadowEdge, shadowEdge, 0); | |||
| setShadowImage (bigIm, 7, shadowEdge, shadowEdge, iw - shadowEdge2, 0); | |||
| setShadowImage (bigIm, 8, shadowEdge, shadowEdge, shadowEdge2, 0); | |||
| setShadowImage (bigIm, 9, shadowEdge, shadowEdge, shadowEdge, ih - shadowEdge); | |||
| setShadowImage (bigIm, 10, shadowEdge, shadowEdge, iw - shadowEdge2, ih - shadowEdge); | |||
| setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge); | |||
| for (int i = 0; i < 4; ++i) | |||
| shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections)); | |||
| } | |||
| const int iw = bigIm.getWidth(); | |||
| const int ih = bigIm.getHeight(); | |||
| const int shadowEdge2 = shadowEdge * 2; | |||
| setShadowImage (bigIm, 0, shadowEdge, shadowEdge2, 0, 0); | |||
| setShadowImage (bigIm, 1, shadowEdge, shadowEdge2, 0, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 2, shadowEdge, shadowEdge, 0, shadowEdge2); | |||
| setShadowImage (bigIm, 3, shadowEdge, shadowEdge2, iw - shadowEdge, 0); | |||
| setShadowImage (bigIm, 4, shadowEdge, shadowEdge2, iw - shadowEdge, ih - shadowEdge2); | |||
| setShadowImage (bigIm, 5, shadowEdge, shadowEdge, iw - shadowEdge, shadowEdge2); | |||
| setShadowImage (bigIm, 6, shadowEdge, shadowEdge, shadowEdge, 0); | |||
| setShadowImage (bigIm, 7, shadowEdge, shadowEdge, iw - shadowEdge2, 0); | |||
| setShadowImage (bigIm, 8, shadowEdge, shadowEdge, shadowEdge2, 0); | |||
| setShadowImage (bigIm, 9, shadowEdge, shadowEdge, shadowEdge, ih - shadowEdge); | |||
| setShadowImage (bigIm, 10, shadowEdge, shadowEdge, iw - shadowEdge2, ih - shadowEdge); | |||
| setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge); | |||
| for (int i = 0; i < 4; ++i) | |||
| shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections)); | |||
| } | |||
| if (shadowWindows.size() >= 4) | |||
| { | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| if (shadowWindows.size() >= 4) | |||
| { | |||
| shadowWindows.getUnchecked(i)->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows.getUnchecked(i)->setVisible (isOwnerVisible); | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| { | |||
| shadowWindows.getUnchecked(i)->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows.getUnchecked(i)->setVisible (isOwnerVisible); | |||
| } | |||
| const int x = owner->getX(); | |||
| const int y = owner->getY() - shadowEdge; | |||
| const int w = owner->getWidth(); | |||
| const int h = owner->getHeight() + shadowEdge + shadowEdge; | |||
| shadowWindows.getUnchecked(0)->setBounds (x - shadowEdge, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(1)->setBounds (x + w, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(2)->setBounds (x, y, w, shadowEdge); | |||
| shadowWindows.getUnchecked(3)->setBounds (x, owner->getBottom(), w, shadowEdge); | |||
| } | |||
| const int x = owner->getX(); | |||
| const int y = owner->getY() - shadowEdge; | |||
| const int w = owner->getWidth(); | |||
| const int h = owner->getHeight() + shadowEdge + shadowEdge; | |||
| shadowWindows.getUnchecked(0)->setBounds (x - shadowEdge, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(1)->setBounds (x + w, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(2)->setBounds (x, y, w, shadowEdge); | |||
| shadowWindows.getUnchecked(3)->setBounds (x, owner->getBottom(), w, shadowEdge); | |||
| } | |||
| reentrant = false; | |||
| if (createShadowWindows) | |||
| bringShadowWindowsToFront(); | |||
| } | |||
| @@ -285,12 +286,10 @@ void DropShadower::bringShadowWindowsToFront() | |||
| { | |||
| updateShadows(); | |||
| reentrant = true; | |||
| const ScopedValueSetter<bool> setter (reentrant, true, false); | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| shadowWindows.getUnchecked(i)->toBehind (owner); | |||
| reentrant = false; | |||
| } | |||
| } | |||
| @@ -28,6 +28,7 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "juce_DrawableComposite.h" | |||
| #include "../../../containers/juce_ScopedValueSetter.h" | |||
| //============================================================================== | |||
| @@ -186,22 +187,11 @@ void DrawableComposite::childrenChanged() | |||
| updateBoundsToFitChildren(); | |||
| } | |||
| struct RentrancyCheckSetter | |||
| { | |||
| RentrancyCheckSetter (bool& b_) : b (b_) { b_ = true; } | |||
| ~RentrancyCheckSetter() { b = false; } | |||
| private: | |||
| bool& b; | |||
| JUCE_DECLARE_NON_COPYABLE (RentrancyCheckSetter); | |||
| }; | |||
| void DrawableComposite::updateBoundsToFitChildren() | |||
| { | |||
| if (! updateBoundsReentrant) | |||
| { | |||
| const RentrancyCheckSetter checkSetter (updateBoundsReentrant); | |||
| const ScopedValueSetter<bool> setter (updateBoundsReentrant, true, false); | |||
| Rectangle<int> childArea; | |||
| @@ -56,6 +56,9 @@ | |||
| #ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__ | |||
| #include "containers/juce_ReferenceCountedArray.h" | |||
| #endif | |||
| #ifndef __JUCE_SCOPEDVALUESETTER_JUCEHEADER__ | |||
| #include "containers/juce_ScopedValueSetter.h" | |||
| #endif | |||
| #ifndef __JUCE_SORTEDSET_JUCEHEADER__ | |||
| #include "containers/juce_SortedSet.h" | |||
| #endif | |||
| @@ -1297,7 +1297,7 @@ private: | |||
| return; | |||
| } | |||
| reentrant = true; | |||
| const ScopedValueSetter<bool> setter (reentrant, true, false); | |||
| // this is the rectangle to update.. | |||
| int x = paintStruct.rcPaint.left; | |||
| @@ -1401,7 +1401,6 @@ private: | |||
| DeleteObject (rgn); | |||
| EndPaint (hwnd, &paintStruct); | |||
| reentrant = false; | |||
| } | |||
| #ifndef JUCE_GCC //xxx should add this fn for gcc.. | |||
| @@ -29,6 +29,7 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "juce_UndoManager.h" | |||
| #include "../application/juce_Application.h" | |||
| #include "../containers/juce_ScopedValueSetter.h" | |||
| //============================================================================== | |||
| @@ -194,21 +195,22 @@ bool UndoManager::undo() | |||
| if (commandSet == 0) | |||
| return false; | |||
| reentrancyCheck = true; | |||
| bool failed = false; | |||
| for (int i = commandSet->size(); --i >= 0;) | |||
| { | |||
| if (! commandSet->getUnchecked(i)->undo()) | |||
| const ScopedValueSetter<bool> setter (reentrancyCheck, true); | |||
| for (int i = commandSet->size(); --i >= 0;) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| if (! commandSet->getUnchecked(i)->undo()) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| reentrancyCheck = false; | |||
| if (failed) | |||
| clearUndoHistory(); | |||
| else | |||
| @@ -227,21 +229,22 @@ bool UndoManager::redo() | |||
| if (commandSet == 0) | |||
| return false; | |||
| reentrancyCheck = true; | |||
| bool failed = false; | |||
| for (int i = 0; i < commandSet->size(); ++i) | |||
| { | |||
| if (! commandSet->getUnchecked(i)->perform()) | |||
| const ScopedValueSetter<bool> setter (reentrancyCheck, true); | |||
| for (int i = 0; i < commandSet->size(); ++i) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| if (! commandSet->getUnchecked(i)->perform()) | |||
| { | |||
| jassertfalse; | |||
| failed = true; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| reentrancyCheck = false; | |||
| if (failed) | |||
| clearUndoHistory(); | |||
| else | |||