From b0ba2f7388d1c8a3acc205381582bde29aeca974 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Tue, 11 Jan 2011 18:12:02 +0000 Subject: [PATCH] Added a simple utility class: ScopedValueSetter. --- Builds/MacOSX/Juce.xcodeproj/project.pbxproj | 2 + Builds/VisualStudio2005/Juce.vcproj | 1 + Builds/VisualStudio2008/Juce.vcproj | 1 + Builds/VisualStudio2008_DLL/Juce.vcproj | 1 + Builds/VisualStudio2010/Juce.vcxproj | 1 + Builds/VisualStudio2010/Juce.vcxproj.filters | 3 + Builds/iPhone/Juce.xcodeproj/project.pbxproj | 2 + Juce.jucer | 2 + juce_amalgamated.cpp | 178 ++++++++---------- juce_amalgamated.h | 78 +++++++- src/containers/juce_ScopedValueSetter.h | 97 ++++++++++ src/core/juce_StandardHeader.h | 2 +- .../layout/juce_ComponentMovementWatcher.cpp | 5 +- .../components/special/juce_DropShadower.cpp | 139 +++++++------- .../drawables/juce_DrawableComposite.cpp | 14 +- src/juce_core_includes.h | 3 + src/native/windows/juce_win32_Windowing.cpp | 3 +- src/utilities/juce_UndoManager.cpp | 35 ++-- 18 files changed, 366 insertions(+), 201 deletions(-) create mode 100644 src/containers/juce_ScopedValueSetter.h diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj index 2c8df665e8..5ee14e4ba4 100644 --- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj @@ -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, diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj index 191c032138..d8147cdfa1 100644 --- a/Builds/VisualStudio2005/Juce.vcproj +++ b/Builds/VisualStudio2005/Juce.vcproj @@ -360,6 +360,7 @@ + diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj index 822203c10e..be75265fc9 100644 --- a/Builds/VisualStudio2008/Juce.vcproj +++ b/Builds/VisualStudio2008/Juce.vcproj @@ -360,6 +360,7 @@ + diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj index 5f6d4db9e2..461d28f8ec 100644 --- a/Builds/VisualStudio2008_DLL/Juce.vcproj +++ b/Builds/VisualStudio2008_DLL/Juce.vcproj @@ -362,6 +362,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj b/Builds/VisualStudio2010/Juce.vcxproj index cbf7edfb8c..bf34c05981 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj +++ b/Builds/VisualStudio2010/Juce.vcxproj @@ -519,6 +519,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj.filters b/Builds/VisualStudio2010/Juce.vcxproj.filters index 6906d196b8..0ba4ee7baa 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj.filters +++ b/Builds/VisualStudio2010/Juce.vcxproj.filters @@ -1488,6 +1488,9 @@ Juce\Source\containers + + Juce\Source\containers + Juce\Source\containers diff --git a/Builds/iPhone/Juce.xcodeproj/project.pbxproj b/Builds/iPhone/Juce.xcodeproj/project.pbxproj index 2bee968cd7..3f2effc284 100644 --- a/Builds/iPhone/Juce.xcodeproj/project.pbxproj +++ b/Builds/iPhone/Juce.xcodeproj/project.pbxproj @@ -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, diff --git a/Juce.jucer b/Juce.jucer index 53514309d6..48554a183e 100644 --- a/Juce.jucer +++ b/Juce.jucer @@ -379,6 +379,8 @@ file="src/containers/juce_PropertySet.h"/> + size(); --i >= 0;) { - if (! commandSet->getUnchecked(i)->undo()) + const ScopedValueSetter 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 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 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 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 (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 (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 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 setter (updateBoundsReentrant, true, false); Rectangle childArea; @@ -242959,7 +242946,7 @@ private: return; } - reentrant = true; + const ScopedValueSetter 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.. diff --git a/juce_amalgamated.h b/juce_amalgamated.h index c30e04a17e..8227483cb5 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -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 +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__ diff --git a/src/containers/juce_ScopedValueSetter.h b/src/containers/juce_ScopedValueSetter.h new file mode 100644 index 0000000000..9705851379 --- /dev/null +++ b/src/containers/juce_ScopedValueSetter.h @@ -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 +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__ diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index cef99ba940..5de4f910ff 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 53 -#define JUCE_BUILDNUMBER 11 +#define JUCE_BUILDNUMBER 12 /** Current Juce version number. diff --git a/src/gui/components/layout/juce_ComponentMovementWatcher.cpp b/src/gui/components/layout/juce_ComponentMovementWatcher.cpp index ce0f4d72b5..fb45a70cfb 100644 --- a/src/gui/components/layout/juce_ComponentMovementWatcher.cpp +++ b/src/gui/components/layout/juce_ComponentMovementWatcher.cpp @@ -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 setter (reentrant, true); ComponentPeer* const peer = component->getPeer(); @@ -78,8 +79,6 @@ void ComponentMovementWatcher::componentParentHierarchyChanged (Component&) if (component != 0) componentVisibilityChanged (*component); - - reentrant = false; } } diff --git a/src/gui/components/special/juce_DropShadower.cpp b/src/gui/components/special/juce_DropShadower.cpp index 438ff25ccf..c819971bfd 100644 --- a/src/gui/components/special/juce_DropShadower.cpp +++ b/src/gui/components/special/juce_DropShadower.cpp @@ -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 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 (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 (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 setter (reentrant, true, false); for (int i = shadowWindows.size(); --i >= 0;) shadowWindows.getUnchecked(i)->toBehind (owner); - - reentrant = false; } } diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.cpp b/src/gui/graphics/drawables/juce_DrawableComposite.cpp index 3caa048288..bf5d77c195 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.cpp +++ b/src/gui/graphics/drawables/juce_DrawableComposite.cpp @@ -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 setter (updateBoundsReentrant, true, false); Rectangle childArea; diff --git a/src/juce_core_includes.h b/src/juce_core_includes.h index 32f02463e1..d6d58e2d6e 100644 --- a/src/juce_core_includes.h +++ b/src/juce_core_includes.h @@ -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 diff --git a/src/native/windows/juce_win32_Windowing.cpp b/src/native/windows/juce_win32_Windowing.cpp index d6f60c7b09..182ce99c9c 100644 --- a/src/native/windows/juce_win32_Windowing.cpp +++ b/src/native/windows/juce_win32_Windowing.cpp @@ -1297,7 +1297,7 @@ private: return; } - reentrant = true; + const ScopedValueSetter 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.. diff --git a/src/utilities/juce_UndoManager.cpp b/src/utilities/juce_UndoManager.cpp index 294c12dc25..611a15b28f 100644 --- a/src/utilities/juce_UndoManager.cpp +++ b/src/utilities/juce_UndoManager.cpp @@ -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 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 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