| @@ -249,7 +249,6 @@ OBJECTS := \ | |||
| $(OBJDIR)/juce_SVGParser_b79416c5.o \ | |||
| $(OBJDIR)/juce_DropShadowEffect_da52d75.o \ | |||
| $(OBJDIR)/juce_GlowEffect_c0959893.o \ | |||
| $(OBJDIR)/juce_ReduceOpacityEffect_e8e7a60b.o \ | |||
| $(OBJDIR)/juce_Font_fa88db26.o \ | |||
| $(OBJDIR)/juce_GlyphArrangement_f0797295.o \ | |||
| $(OBJDIR)/juce_TextLayout_d18f700e.o \ | |||
| @@ -1414,11 +1413,6 @@ $(OBJDIR)/juce_GlowEffect_c0959893.o: ../../src/gui/graphics/effects/juce_GlowEf | |||
| @echo "Compiling juce_GlowEffect.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_ReduceOpacityEffect_e8e7a60b.o: ../../src/gui/graphics/effects/juce_ReduceOpacityEffect.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_ReduceOpacityEffect.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_Font_fa88db26.o: ../../src/gui/graphics/fonts/juce_Font.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_Font.cpp" | |||
| @@ -218,7 +218,6 @@ | |||
| 645AF66C048A4815F5A8ECDD = { isa = PBXBuildFile; fileRef = 2BFC199D03DEEC329D6A7CB1; }; | |||
| 38EFE824E76B3BB99824C265 = { isa = PBXBuildFile; fileRef = 32EA297812F1C88B42099501; }; | |||
| E23C5C51305DC7CE30E4DAB7 = { isa = PBXBuildFile; fileRef = CB649686575473223C859482; }; | |||
| 89C96A721F3B54CF3F33848C = { isa = PBXBuildFile; fileRef = 7EBBC368FA350F786EF446B7; }; | |||
| B92F53BABB6A9AC8348B001E = { isa = PBXBuildFile; fileRef = 78068AA59A5DCFCCAAEA79D0; }; | |||
| EBC3AA015D24C62FA0307F51 = { isa = PBXBuildFile; fileRef = 61D06B694603F608CDA0703B; }; | |||
| 803FFCA3DAC0C004A80143B4 = { isa = PBXBuildFile; fileRef = 91CB423DBC5F3CBEDD9CF2EF; }; | |||
| @@ -834,8 +833,6 @@ | |||
| CB649686575473223C859482 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlowEffect.cpp; path = ../../src/gui/graphics/effects/juce_GlowEffect.cpp; sourceTree = SOURCE_ROOT; }; | |||
| FD1FA4ABB4226372235643E4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GlowEffect.h; path = ../../src/gui/graphics/effects/juce_GlowEffect.h; sourceTree = SOURCE_ROOT; }; | |||
| 18DB9BD10F140F132A3279C3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ImageEffectFilter.h; path = ../../src/gui/graphics/effects/juce_ImageEffectFilter.h; sourceTree = SOURCE_ROOT; }; | |||
| 7EBBC368FA350F786EF446B7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ReduceOpacityEffect.cpp; path = ../../src/gui/graphics/effects/juce_ReduceOpacityEffect.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 8D18743ECC1BF12381811FD6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ReduceOpacityEffect.h; path = ../../src/gui/graphics/effects/juce_ReduceOpacityEffect.h; sourceTree = SOURCE_ROOT; }; | |||
| 78068AA59A5DCFCCAAEA79D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Font.cpp; path = ../../src/gui/graphics/fonts/juce_Font.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 0401EA0E883CCAAAC6960A27 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Font.h; path = ../../src/gui/graphics/fonts/juce_Font.h; sourceTree = SOURCE_ROOT; }; | |||
| 61D06B694603F608CDA0703B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlyphArrangement.cpp; path = ../../src/gui/graphics/fonts/juce_GlyphArrangement.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1592,9 +1589,7 @@ | |||
| 85D4043F9E25047E07496DAC, | |||
| CB649686575473223C859482, | |||
| FD1FA4ABB4226372235643E4, | |||
| 18DB9BD10F140F132A3279C3, | |||
| 7EBBC368FA350F786EF446B7, | |||
| 8D18743ECC1BF12381811FD6 ); name = effects; sourceTree = "<group>"; }; | |||
| 18DB9BD10F140F132A3279C3 ); name = effects; sourceTree = "<group>"; }; | |||
| 58FE42C578BFFD1F8F545B39 = { isa = PBXGroup; children = ( | |||
| 78068AA59A5DCFCCAAEA79D0, | |||
| 0401EA0E883CCAAAC6960A27, | |||
| @@ -2143,7 +2138,6 @@ | |||
| 645AF66C048A4815F5A8ECDD, | |||
| 38EFE824E76B3BB99824C265, | |||
| E23C5C51305DC7CE30E4DAB7, | |||
| 89C96A721F3B54CF3F33848C, | |||
| B92F53BABB6A9AC8348B001E, | |||
| EBC3AA015D24C62FA0307F51, | |||
| 803FFCA3DAC0C004A80143B4, | |||
| @@ -737,8 +737,6 @@ | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_GlowEffect.cpp"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_GlowEffect.h"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ImageEffectFilter.h"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.cpp"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.h"/> | |||
| </Filter> | |||
| <Filter Name="fonts"> | |||
| <File RelativePath="..\..\src\gui\graphics\fonts\juce_Font.cpp"/> | |||
| @@ -737,8 +737,6 @@ | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_GlowEffect.cpp"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_GlowEffect.h"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ImageEffectFilter.h"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.cpp"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.h"/> | |||
| </Filter> | |||
| <Filter Name="fonts"> | |||
| <File RelativePath="..\..\src\gui\graphics\fonts\juce_Font.cpp"/> | |||
| @@ -739,8 +739,6 @@ | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_GlowEffect.cpp"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_GlowEffect.h"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ImageEffectFilter.h"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.cpp"/> | |||
| <File RelativePath="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.h"/> | |||
| </Filter> | |||
| <Filter Name="fonts"> | |||
| <File RelativePath="..\..\src\gui\graphics\fonts\juce_Font.cpp"/> | |||
| @@ -332,7 +332,6 @@ | |||
| <ClCompile Include="..\..\src\gui\graphics\drawables\juce_SVGParser.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\graphics\effects\juce_DropShadowEffect.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\graphics\effects\juce_GlowEffect.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\graphics\fonts\juce_Font.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\graphics\fonts\juce_GlyphArrangement.cpp"/> | |||
| <ClCompile Include="..\..\src\gui\graphics\fonts\juce_TextLayout.cpp"/> | |||
| @@ -700,7 +699,6 @@ | |||
| <ClInclude Include="..\..\src\gui\graphics\effects\juce_DropShadowEffect.h"/> | |||
| <ClInclude Include="..\..\src\gui\graphics\effects\juce_GlowEffect.h"/> | |||
| <ClInclude Include="..\..\src\gui\graphics\effects\juce_ImageEffectFilter.h"/> | |||
| <ClInclude Include="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.h"/> | |||
| <ClInclude Include="..\..\src\gui\graphics\fonts\juce_Font.h"/> | |||
| <ClInclude Include="..\..\src\gui\graphics\fonts\juce_GlyphArrangement.h"/> | |||
| <ClInclude Include="..\..\src\gui\graphics\fonts\juce_TextLayout.h"/> | |||
| @@ -844,9 +844,6 @@ | |||
| <ClCompile Include="..\..\src\gui\graphics\effects\juce_GlowEffect.cpp"> | |||
| <Filter>Juce\Source\gui\graphics\effects</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.cpp"> | |||
| <Filter>Juce\Source\gui\graphics\effects</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\src\gui\graphics\fonts\juce_Font.cpp"> | |||
| <Filter>Juce\Source\gui\graphics\fonts</Filter> | |||
| </ClCompile> | |||
| @@ -2022,9 +2019,6 @@ | |||
| <ClInclude Include="..\..\src\gui\graphics\effects\juce_ImageEffectFilter.h"> | |||
| <Filter>Juce\Source\gui\graphics\effects</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\gui\graphics\effects\juce_ReduceOpacityEffect.h"> | |||
| <Filter>Juce\Source\gui\graphics\effects</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\src\gui\graphics\fonts\juce_Font.h"> | |||
| <Filter>Juce\Source\gui\graphics\fonts</Filter> | |||
| </ClInclude> | |||
| @@ -218,7 +218,6 @@ | |||
| 645AF66C048A4815F5A8ECDD = { isa = PBXBuildFile; fileRef = 2BFC199D03DEEC329D6A7CB1; }; | |||
| 38EFE824E76B3BB99824C265 = { isa = PBXBuildFile; fileRef = 32EA297812F1C88B42099501; }; | |||
| E23C5C51305DC7CE30E4DAB7 = { isa = PBXBuildFile; fileRef = CB649686575473223C859482; }; | |||
| 89C96A721F3B54CF3F33848C = { isa = PBXBuildFile; fileRef = 7EBBC368FA350F786EF446B7; }; | |||
| B92F53BABB6A9AC8348B001E = { isa = PBXBuildFile; fileRef = 78068AA59A5DCFCCAAEA79D0; }; | |||
| EBC3AA015D24C62FA0307F51 = { isa = PBXBuildFile; fileRef = 61D06B694603F608CDA0703B; }; | |||
| 803FFCA3DAC0C004A80143B4 = { isa = PBXBuildFile; fileRef = 91CB423DBC5F3CBEDD9CF2EF; }; | |||
| @@ -834,8 +833,6 @@ | |||
| CB649686575473223C859482 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlowEffect.cpp; path = ../../src/gui/graphics/effects/juce_GlowEffect.cpp; sourceTree = SOURCE_ROOT; }; | |||
| FD1FA4ABB4226372235643E4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GlowEffect.h; path = ../../src/gui/graphics/effects/juce_GlowEffect.h; sourceTree = SOURCE_ROOT; }; | |||
| 18DB9BD10F140F132A3279C3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ImageEffectFilter.h; path = ../../src/gui/graphics/effects/juce_ImageEffectFilter.h; sourceTree = SOURCE_ROOT; }; | |||
| 7EBBC368FA350F786EF446B7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ReduceOpacityEffect.cpp; path = ../../src/gui/graphics/effects/juce_ReduceOpacityEffect.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 8D18743ECC1BF12381811FD6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ReduceOpacityEffect.h; path = ../../src/gui/graphics/effects/juce_ReduceOpacityEffect.h; sourceTree = SOURCE_ROOT; }; | |||
| 78068AA59A5DCFCCAAEA79D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Font.cpp; path = ../../src/gui/graphics/fonts/juce_Font.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 0401EA0E883CCAAAC6960A27 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Font.h; path = ../../src/gui/graphics/fonts/juce_Font.h; sourceTree = SOURCE_ROOT; }; | |||
| 61D06B694603F608CDA0703B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlyphArrangement.cpp; path = ../../src/gui/graphics/fonts/juce_GlyphArrangement.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1592,9 +1589,7 @@ | |||
| 85D4043F9E25047E07496DAC, | |||
| CB649686575473223C859482, | |||
| FD1FA4ABB4226372235643E4, | |||
| 18DB9BD10F140F132A3279C3, | |||
| 7EBBC368FA350F786EF446B7, | |||
| 8D18743ECC1BF12381811FD6 ); name = effects; sourceTree = "<group>"; }; | |||
| 18DB9BD10F140F132A3279C3 ); name = effects; sourceTree = "<group>"; }; | |||
| 58FE42C578BFFD1F8F545B39 = { isa = PBXGroup; children = ( | |||
| 78068AA59A5DCFCCAAEA79D0, | |||
| 0401EA0E883CCAAAC6960A27, | |||
| @@ -2143,7 +2138,6 @@ | |||
| 645AF66C048A4815F5A8ECDD, | |||
| 38EFE824E76B3BB99824C265, | |||
| E23C5C51305DC7CE30E4DAB7, | |||
| 89C96A721F3B54CF3F33848C, | |||
| B92F53BABB6A9AC8348B001E, | |||
| EBC3AA015D24C62FA0307F51, | |||
| 803FFCA3DAC0C004A80143B4, | |||
| @@ -1083,10 +1083,6 @@ | |||
| file="src/gui/graphics/effects/juce_GlowEffect.h"/> | |||
| <FILE id="raUYTlokJ" name="juce_ImageEffectFilter.h" compile="0" resource="0" | |||
| file="src/gui/graphics/effects/juce_ImageEffectFilter.h"/> | |||
| <FILE id="TTo5FPVpI" name="juce_ReduceOpacityEffect.cpp" compile="1" | |||
| resource="0" file="src/gui/graphics/effects/juce_ReduceOpacityEffect.cpp"/> | |||
| <FILE id="TyJK1WbMk" name="juce_ReduceOpacityEffect.h" compile="0" | |||
| resource="0" file="src/gui/graphics/effects/juce_ReduceOpacityEffect.h"/> | |||
| </GROUP> | |||
| <GROUP id="nw92NleR1" name="fonts"> | |||
| <FILE id="2zj67pVi" name="juce_Font.cpp" compile="1" resource="0" file="src/gui/graphics/fonts/juce_Font.cpp"/> | |||
| @@ -350,7 +350,6 @@ | |||
| #include "../src/gui/graphics/drawables/juce_SVGParser.cpp" | |||
| #include "../src/gui/graphics/effects/juce_DropShadowEffect.cpp" | |||
| #include "../src/gui/graphics/effects/juce_GlowEffect.cpp" | |||
| #include "../src/gui/graphics/effects/juce_ReduceOpacityEffect.cpp" | |||
| #include "../src/gui/graphics/fonts/juce_Font.cpp" | |||
| #include "../src/gui/graphics/fonts/juce_GlyphArrangement.cpp" | |||
| #include "../src/gui/graphics/fonts/juce_TextLayout.cpp" | |||
| @@ -610,7 +610,9 @@ public: | |||
| Random::getSystemRandom().nextInt (getHeight() / 2), | |||
| 60 + Random::getSystemRandom().nextInt (getWidth() / 3), | |||
| 16 + Random::getSystemRandom().nextInt (getHeight() / 6)), | |||
| Random::getSystemRandom().nextFloat(), | |||
| 500 + Random::getSystemRandom().nextInt (2000), | |||
| false, | |||
| Random::getSystemRandom().nextDouble(), | |||
| Random::getSystemRandom().nextDouble()); | |||
| } | |||
| @@ -64,7 +64,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 80 | |||
| #define JUCE_BUILDNUMBER 81 | |||
| /** Current Juce version number. | |||
| @@ -24909,6 +24909,13 @@ public: | |||
| */ | |||
| bool reduceClipRegion (int x, int y, int width, int height); | |||
| /** Intersects the current clipping region with another region. | |||
| @returns true if the resulting clipping region is non-zero in size | |||
| @see setOrigin, clipRegionIntersects | |||
| */ | |||
| bool reduceClipRegion (const Rectangle<int>& area); | |||
| /** Intersects the current clipping region with a rectangle list region. | |||
| @returns true if the resulting clipping region is non-zero in size | |||
| @@ -25019,9 +25026,12 @@ public: | |||
| its paint() method. The image may or may not have an alpha | |||
| channel, depending on whether the component is opaque. | |||
| @param destContext the graphics context to use to draw the resultant image. | |||
| @param alpha the alpha with which to draw the resultant image to the | |||
| target context | |||
| */ | |||
| virtual void applyEffect (Image& sourceImage, | |||
| Graphics& destContext) = 0; | |||
| Graphics& destContext, | |||
| float alpha) = 0; | |||
| /** Destructor. */ | |||
| virtual ~ImageEffectFilter() {} | |||
| @@ -26010,31 +26020,6 @@ public: | |||
| */ | |||
| bool isShowing() const; | |||
| /** Makes a component invisible using a groovy fade-out and animated zoom effect. | |||
| To do this, this function will cunningly: | |||
| - take a snapshot of the component as it currently looks | |||
| - call setVisible(false) on the component | |||
| - replace it with a special component that will continue drawing the | |||
| snapshot, animating it and gradually making it more transparent | |||
| - when it's gone, the special component will also be deleted | |||
| As soon as this method returns, the component can be safely removed and deleted | |||
| leaving the proxy to do the fade-out, so it's even ok to call this in a | |||
| component's destructor. | |||
| Passing non-zero x and y values will cause the ghostly component image to | |||
| also whizz off by this distance while fading out. If the scale factor is | |||
| not 1.0, it will also zoom from the component's current size to this new size. | |||
| One thing to be careful about is that the parent component must be able to cope | |||
| with this unknown component type being added to it. | |||
| */ | |||
| void fadeOutComponent (int lengthOfFadeOutInMilliseconds, | |||
| int deltaXToMove = 0, | |||
| int deltaYToMove = 0, | |||
| float scaleFactorAtEnd = 1.0f); | |||
| /** Makes this component appear as a window on the desktop. | |||
| Note that before calling this, you should make sure that the component's opacity is | |||
| @@ -26742,8 +26727,12 @@ public: | |||
| The graphics context may be left in an undefined state after this method returns, | |||
| so you may need to reset it if you're going to use it again. | |||
| If ignoreAlphaLevel is false, then the component will be drawn with the opacity level | |||
| specified by getAlpha(); if ignoreAlphaLevel is true, then this will be ignored and | |||
| an alpha of 1.0 will be used. | |||
| */ | |||
| void paintEntireComponent (Graphics& context); | |||
| void paintEntireComponent (Graphics& context, bool ignoreAlphaLevel); | |||
| /** Adds an effect filter to alter the component's appearance. | |||
| @@ -27046,6 +27035,9 @@ public: | |||
| */ | |||
| virtual void enablementChanged(); | |||
| void setAlpha (float newAlpha); | |||
| float getAlpha() const; | |||
| /** Changes the mouse cursor shape to use when the mouse is over this component. | |||
| Note that the cursor set by this method can be overridden by the getMouseCursor | |||
| @@ -27888,6 +27880,8 @@ private: | |||
| ComponentFlags flags; | |||
| }; | |||
| uint8 componentTransparency; | |||
| void internalMouseEnter (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||
| void internalMouseExit (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||
| void internalMouseDown (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||
| @@ -27903,7 +27897,7 @@ private: | |||
| void internalModifierKeysChanged(); | |||
| void internalChildrenChanged(); | |||
| void internalHierarchyChanged(); | |||
| void renderComponent (Graphics& context); | |||
| void renderComponent (Graphics& g); | |||
| void sendMovedResizedMessages (bool wasMoved, bool wasResized); | |||
| void repaintParent(); | |||
| void sendFakeMouseMove() const; | |||
| @@ -28807,6 +28801,139 @@ private: | |||
| #endif // __JUCE_TIMER_JUCEHEADER__ | |||
| /*** End of inlined file: juce_Timer.h ***/ | |||
| /*** Start of inlined file: juce_ComponentAnimator.h ***/ | |||
| #ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ | |||
| #define __JUCE_COMPONENTANIMATOR_JUCEHEADER__ | |||
| /** | |||
| Animates a set of components, moving them to a new position and/or fading their | |||
| alpha levels. | |||
| To animate a component, create a ComponentAnimator instance or (preferably) use the | |||
| global animator object provided by Desktop::getAnimator(), and call its animateComponent() | |||
| method to commence the movement. | |||
| If you're using your own ComponentAnimator instance, you'll need to make sure it isn't | |||
| deleted before it finishes moving the components, or they'll be abandoned before reaching their | |||
| destinations. | |||
| It's ok to delete components while they're being animated - the animator will detect this | |||
| and safely stop using them. | |||
| The class is a ChangeBroadcaster and sends a notification when any components | |||
| start or finish being animated. | |||
| @see Desktop::getAnimator | |||
| */ | |||
| class JUCE_API ComponentAnimator : public ChangeBroadcaster, | |||
| private Timer | |||
| { | |||
| public: | |||
| /** Creates a ComponentAnimator. */ | |||
| ComponentAnimator(); | |||
| /** Destructor. */ | |||
| ~ComponentAnimator(); | |||
| /** Starts a component moving from its current position to a specified position. | |||
| If the component is already in the middle of an animation, that will be abandoned, | |||
| and a new animation will begin, moving the component from its current location. | |||
| The start and end speed parameters let you apply some acceleration to the component's | |||
| movement. | |||
| @param component the component to move | |||
| @param finalBounds the destination bounds to which the component should move. To leave the | |||
| component in the same place, just pass component->getBounds() for this value | |||
| @param finalAlpha the alpha value that the component should have at the end of the animation | |||
| @param animationDurationMilliseconds how long the animation should last, in milliseconds | |||
| @param useProxyComponent if true, this means the component should be replaced by an internally | |||
| managed temporary component which is a snapshot of the original component. | |||
| This avoids the component having to paint itself as it moves, so may | |||
| be more efficient. This option also allows you to delete the original | |||
| component immediately after starting the animation, because the animation | |||
| can proceed without it. If you use a proxy, the original component will be | |||
| made invisible by this call, and then will become visible again at the end | |||
| of the animation. It'll also mean that the proxy component will be temporarily | |||
| added to the component's parent, so avoid it if this might confuse the parent | |||
| component, or if there's a chance the parent might decide to delete its children. | |||
| @param startSpeed a value to indicate the relative start speed of the animation. If this is 0, | |||
| the component will start by accelerating from rest; higher values mean that it | |||
| will have an initial speed greater than zero. If the value if greater than 1, it | |||
| will decelerate towards the middle of its journey. To move the component at a | |||
| constant rate for its entire animation, set both the start and end speeds to 1.0 | |||
| @param endSpeed a relative speed at which the component should be moving when the animation finishes. | |||
| If this is 0, the component will decelerate to a standstill at its final position; | |||
| higher values mean the component will still be moving when it stops. To move the component | |||
| at a constant rate for its entire animation, set both the start and end speeds to 1.0 | |||
| */ | |||
| void animateComponent (Component* component, | |||
| const Rectangle<int>& finalBounds, | |||
| float finalAlpha, | |||
| int animationDurationMilliseconds, | |||
| bool useProxyComponent, | |||
| double startSpeed, | |||
| double endSpeed); | |||
| /** Begins a fade-out of this components alpha level. | |||
| This is a quick way of invoking animateComponent() with a target alpha value of 0.0f, using | |||
| a proxy. You're safe to delete the component after calling this method, and this won't | |||
| interfere with the animation's progress. | |||
| */ | |||
| void fadeOut (Component* component, int millisecondsToTake); | |||
| /** Begins a fade-in of a component. | |||
| This is a quick way of invoking animateComponent() with a target alpha value of 1.0f. | |||
| */ | |||
| void fadeIn (Component* component, int millisecondsToTake); | |||
| /** Stops a component if it's currently being animated. | |||
| If moveComponentToItsFinalPosition is true, then the component will | |||
| be immediately moved to its destination position and size. If false, it will be | |||
| left in whatever location it currently occupies. | |||
| */ | |||
| void cancelAnimation (Component* component, | |||
| bool moveComponentToItsFinalPosition); | |||
| /** Clears all of the active animations. | |||
| If moveComponentsToTheirFinalPositions is true, all the components will | |||
| be immediately set to their final positions. If false, they will be | |||
| left in whatever locations they currently occupy. | |||
| */ | |||
| void cancelAllAnimations (bool moveComponentsToTheirFinalPositions); | |||
| /** Returns the destination position for a component. | |||
| If the component is being animated, this will return the target position that | |||
| was specified when animateComponent() was called. | |||
| If the specified component isn't currently being animated, this method will just | |||
| return its current position. | |||
| */ | |||
| const Rectangle<int> getComponentDestination (Component* component); | |||
| /** Returns true if the specified component is currently being animated. */ | |||
| bool isAnimating (Component* component) const; | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class AnimationTask; | |||
| OwnedArray <AnimationTask> tasks; | |||
| uint32 lastTime; | |||
| AnimationTask* findTaskFor (Component* component) const; | |||
| void timerCallback(); | |||
| }; | |||
| #endif // __JUCE_COMPONENTANIMATOR_JUCEHEADER__ | |||
| /*** End of inlined file: juce_ComponentAnimator.h ***/ | |||
| class MouseInputSource; | |||
| class MouseInputSourceInternal; | |||
| class MouseListener; | |||
| @@ -28987,6 +29114,17 @@ public: | |||
| */ | |||
| Component* findComponentAt (const Point<int>& screenPosition) const; | |||
| /** The Desktop object has a ComponentAnimator instance which can be used for performing | |||
| your animations. | |||
| Having a single shared ComponentAnimator object makes it more efficient when multiple | |||
| components are being moved around simultaneously. It's also more convenient than having | |||
| to manage your own instance of one. | |||
| @see ComponentAnimator | |||
| */ | |||
| ComponentAnimator& getAnimator() throw() { return animator; } | |||
| /** Returns the number of MouseInputSource objects the system has at its disposal. | |||
| In a traditional single-mouse system, there might be only one object. On a multi-touch | |||
| system, there could be one input source per potential finger. | |||
| @@ -29091,6 +29229,8 @@ private: | |||
| int allowedOrientations; | |||
| ComponentAnimator animator; | |||
| void timerCallback(); | |||
| void resetTimer(); | |||
| @@ -42486,7 +42626,7 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| PropertyPanel* panel; | |||
| PropertyPanel panel; | |||
| GenericAudioProcessorEditor (const GenericAudioProcessorEditor&); | |||
| GenericAudioProcessorEditor& operator= (const GenericAudioProcessorEditor&); | |||
| @@ -43967,7 +44107,7 @@ public: | |||
| int newShadowOffsetY); | |||
| /** @internal */ | |||
| void applyEffect (Image& sourceImage, Graphics& destContext); | |||
| void applyEffect (Image& sourceImage, Graphics& destContext, float alpha); | |||
| juce_UseDebuggingNewOperator | |||
| @@ -44070,12 +44210,8 @@ public: | |||
| RelativeCoordinate (double absoluteDistanceFromOrigin); | |||
| /** Recreates a coordinate from a string description. | |||
| The string will be parsed by ExpressionParser::parse(). | |||
| @param stringVersion the expression to use | |||
| @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. | |||
| @see toString | |||
| */ | |||
| RelativeCoordinate (const String& stringVersion); | |||
| @@ -45501,115 +45637,6 @@ private: | |||
| #endif // __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__ | |||
| /*** End of inlined file: juce_DragAndDropContainer.h ***/ | |||
| /*** Start of inlined file: juce_ComponentAnimator.h ***/ | |||
| #ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ | |||
| #define __JUCE_COMPONENTANIMATOR_JUCEHEADER__ | |||
| /** | |||
| Animates a set of components, moving it to a new position. | |||
| To use this, create a ComponentAnimator, and use its animateComponent() method | |||
| to tell it to move components to destination positions. Any number of | |||
| components can be animated by one ComponentAnimator object (if you've got a | |||
| lot of components to move, it's much more efficient to share a single animator | |||
| than to have many animators running at once). | |||
| You'll need to make sure the animator object isn't deleted before it finishes | |||
| moving the components. | |||
| The class is a ChangeBroadcaster and sends a notification when any components | |||
| start or finish being animated. | |||
| */ | |||
| class JUCE_API ComponentAnimator : public ChangeBroadcaster, | |||
| private Timer | |||
| { | |||
| public: | |||
| /** Creates a ComponentAnimator. */ | |||
| ComponentAnimator(); | |||
| /** Destructor. */ | |||
| ~ComponentAnimator(); | |||
| /** Starts a component moving from its current position to a specified position. | |||
| If the component is already in the middle of an animation, that will be abandoned, | |||
| and a new animation will begin, moving the component from its current location. | |||
| The start and end speed parameters let you apply some acceleration to the component's | |||
| movement. | |||
| @param component the component to move | |||
| @param finalPosition the destination position and size to move it to | |||
| @param millisecondsToSpendMoving how long, in milliseconds, it should take | |||
| to arrive at its destination | |||
| @param startSpeed a value to indicate the relative start speed of the | |||
| animation. If this is 0, the component will start | |||
| by accelerating from rest; higher values mean that it | |||
| will have an initial speed greater than zero. If the | |||
| value if greater than 1, it will decelerate towards the | |||
| middle of its journey. To move the component at a constant | |||
| rate for its entire animation, set both the start and | |||
| end speeds to 1.0 | |||
| @param endSpeed a relative speed at which the component should be moving | |||
| when the animation finishes. If this is 0, the component | |||
| will decelerate to a standstill at its final position; higher | |||
| values mean the component will still be moving when it stops. | |||
| To move the component at a constant rate for its entire | |||
| animation, set both the start and end speeds to 1.0 | |||
| */ | |||
| void animateComponent (Component* component, | |||
| const Rectangle<int>& finalPosition, | |||
| int millisecondsToSpendMoving, | |||
| double startSpeed = 1.0, | |||
| double endSpeed = 1.0); | |||
| /** Stops a component if it's currently being animated. | |||
| If moveComponentToItsFinalPosition is true, then the component will | |||
| be immediately moved to its destination position and size. If false, it will be | |||
| left in whatever location it currently occupies. | |||
| */ | |||
| void cancelAnimation (Component* component, | |||
| bool moveComponentToItsFinalPosition); | |||
| /** Clears all of the active animations. | |||
| If moveComponentsToTheirFinalPositions is true, all the components will | |||
| be immediately set to their final positions. If false, they will be | |||
| left in whatever locations they currently occupy. | |||
| */ | |||
| void cancelAllAnimations (bool moveComponentsToTheirFinalPositions); | |||
| /** Returns the destination position for a component. | |||
| If the component is being animated, this will return the target position that | |||
| was specified when animateComponent() was called. | |||
| If the specified component isn't currently being animated, this method will just | |||
| return its current position. | |||
| */ | |||
| const Rectangle<int> getComponentDestination (Component* component); | |||
| /** Returns true if the specified component is currently being animated. | |||
| */ | |||
| bool isAnimating (Component* component) const; | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class AnimationTask; | |||
| OwnedArray <AnimationTask> tasks; | |||
| uint32 lastTime; | |||
| AnimationTask* findTaskFor (Component* component) const; | |||
| void timerCallback(); | |||
| }; | |||
| #endif // __JUCE_COMPONENTANIMATOR_JUCEHEADER__ | |||
| /*** End of inlined file: juce_ComponentAnimator.h ***/ | |||
| class ToolbarItemComponent; | |||
| class ToolbarItemFactory; | |||
| @@ -45869,7 +45896,6 @@ private: | |||
| Button* missingItemsButton; | |||
| bool vertical, isEditingActive; | |||
| ToolbarItemStyle toolbarStyle; | |||
| ComponentAnimator animator; | |||
| class MissingItemsComponent; | |||
| friend class MissingItemsComponent; | |||
| Array <ToolbarItemComponent*> items; | |||
| @@ -52521,13 +52547,14 @@ public: | |||
| private: | |||
| KeyPressMappingSet* mappings; | |||
| TreeView* tree; | |||
| friend class KeyMappingTreeViewItem; | |||
| friend class KeyCategoryTreeViewItem; | |||
| friend class KeyMappingItemComponent; | |||
| friend class KeyMappingChangeButton; | |||
| TextButton* resetButton; | |||
| KeyPressMappingSet* mappings; | |||
| TreeView tree; | |||
| TextButton resetButton; | |||
| void assignNewKey (CommandID commandID, int index); | |||
| @@ -56770,7 +56797,7 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| Label* textEditor; | |||
| ScopedPointer<Label> textEditor; | |||
| void createEditor (int maxNumChars, bool isMultiLine); | |||
| @@ -59117,6 +59144,9 @@ public: | |||
| */ | |||
| virtual void performAnyPendingRepaintsNow() = 0; | |||
| /** Changes the window's transparency. */ | |||
| virtual void setAlpha (float newAlpha) = 0; | |||
| void handleMouseEvent (int touchIndex, const Point<int>& positionWithinPeer, const ModifierKeys& newMods, int64 time); | |||
| void handleMouseWheel (int touchIndex, const Point<int>& positionWithinPeer, int64 time, float x, float y); | |||
| @@ -59719,7 +59749,7 @@ public: | |||
| { | |||
| // plot the fist pixel of this segment, including any accumulated | |||
| // levels from smaller segments that haven't been drawn yet | |||
| levelAccumulator += (0xff - (x & 0xff)) * level; | |||
| levelAccumulator += (0x100 - (x & 0xff)) * level; | |||
| levelAccumulator >>= 8; | |||
| x >>= 8; | |||
| @@ -61024,7 +61054,7 @@ public: | |||
| const Colour& newColour); | |||
| /** @internal */ | |||
| void applyEffect (Image& sourceImage, Graphics& destContext); | |||
| void applyEffect (Image& sourceImage, Graphics& destContext, float alpha); | |||
| juce_UseDebuggingNewOperator | |||
| @@ -61040,54 +61070,6 @@ private: | |||
| #endif | |||
| #ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__ | |||
| #endif | |||
| #ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| /*** Start of inlined file: juce_ReduceOpacityEffect.h ***/ | |||
| #ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| #define __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| /** | |||
| An effect filter that reduces the image's opacity. | |||
| This can be used to make a component (and its child components) more | |||
| transparent. | |||
| @see Component::setComponentEffect | |||
| */ | |||
| class JUCE_API ReduceOpacityEffect : public ImageEffectFilter | |||
| { | |||
| public: | |||
| /** Creates the effect object. | |||
| The opacity of the component to which the effect is applied will be | |||
| scaled by the given factor (in the range 0 to 1.0f). | |||
| */ | |||
| ReduceOpacityEffect (float opacity = 1.0f); | |||
| /** Destructor. */ | |||
| ~ReduceOpacityEffect(); | |||
| /** Sets how much to scale the component's opacity. | |||
| @param newOpacity should be between 0 and 1.0f | |||
| */ | |||
| void setOpacity (float newOpacity); | |||
| /** @internal */ | |||
| void applyEffect (Image& sourceImage, Graphics& destContext); | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| float opacity; | |||
| }; | |||
| #endif // __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| /*** End of inlined file: juce_ReduceOpacityEffect.h ***/ | |||
| #endif | |||
| #ifndef __JUCE_FONT_JUCEHEADER__ | |||
| @@ -35,15 +35,17 @@ BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| class ProcessorParameterPropertyComp : public PropertyComponent, | |||
| public AudioProcessorListener, | |||
| public AsyncUpdater | |||
| public Timer | |||
| { | |||
| public: | |||
| ProcessorParameterPropertyComp (const String& name, AudioProcessor& owner_, int index_) | |||
| ProcessorParameterPropertyComp (const String& name, AudioProcessor& owner_, const int index_) | |||
| : PropertyComponent (name), | |||
| owner (owner_), | |||
| index (index_), | |||
| paramHasChanged (false), | |||
| slider (owner_, index_) | |||
| { | |||
| startTimer (100); | |||
| addAndMakeVisible (&slider); | |||
| owner_.addListener (this); | |||
| } | |||
| @@ -55,6 +57,7 @@ public: | |||
| void refresh() | |||
| { | |||
| paramHasChanged = false; | |||
| slider.setValue (owner.getParameter (index), false); | |||
| } | |||
| @@ -63,12 +66,20 @@ public: | |||
| void audioProcessorParameterChanged (AudioProcessor*, int parameterIndex, float) | |||
| { | |||
| if (parameterIndex == index) | |||
| triggerAsyncUpdate(); | |||
| paramHasChanged = true; | |||
| } | |||
| void handleAsyncUpdate() | |||
| void timerCallback() | |||
| { | |||
| refresh(); | |||
| if (paramHasChanged) | |||
| { | |||
| refresh(); | |||
| startTimer (1000 / 50); | |||
| } | |||
| else | |||
| { | |||
| startTimer (jmin (1000 / 4, getTimerInterval() + 10)); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| @@ -80,8 +91,7 @@ private: | |||
| { | |||
| public: | |||
| ParamSlider (AudioProcessor& owner_, const int index_) | |||
| : Slider (String::empty), | |||
| owner (owner_), | |||
| : owner (owner_), | |||
| index (index_) | |||
| { | |||
| setRange (0.0, 1.0, 0.0); | |||
| @@ -90,10 +100,6 @@ private: | |||
| setScrollWheelEnabled (false); | |||
| } | |||
| ~ParamSlider() | |||
| { | |||
| } | |||
| void valueChanged() | |||
| { | |||
| const float newVal = (float) getValue(); | |||
| @@ -120,6 +126,7 @@ private: | |||
| AudioProcessor& owner; | |||
| const int index; | |||
| bool volatile paramHasChanged; | |||
| ParamSlider slider; | |||
| ProcessorParameterPropertyComp (const ProcessorParameterPropertyComp&); | |||
| @@ -134,7 +141,7 @@ GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const | |||
| jassert (owner_ != 0); | |||
| setOpaque (true); | |||
| addAndMakeVisible (panel = new PropertyPanel()); | |||
| addAndMakeVisible (&panel); | |||
| Array <PropertyComponent*> params; | |||
| @@ -152,14 +159,13 @@ GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const | |||
| totalHeight += pc->getPreferredHeight(); | |||
| } | |||
| panel->addProperties (params); | |||
| panel.addProperties (params); | |||
| setSize (400, jlimit (25, 400, totalHeight)); | |||
| } | |||
| GenericAudioProcessorEditor::~GenericAudioProcessorEditor() | |||
| { | |||
| deleteAllChildren(); | |||
| } | |||
| void GenericAudioProcessorEditor::paint (Graphics& g) | |||
| @@ -169,7 +175,7 @@ void GenericAudioProcessorEditor::paint (Graphics& g) | |||
| void GenericAudioProcessorEditor::resized() | |||
| { | |||
| panel->setSize (getWidth(), getHeight()); | |||
| panel.setBounds (getLocalBounds()); | |||
| } | |||
| @@ -56,7 +56,7 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| PropertyPanel* panel; | |||
| PropertyPanel panel; | |||
| GenericAudioProcessorEditor (const GenericAudioProcessorEditor&); | |||
| GenericAudioProcessorEditor& operator= (const GenericAudioProcessorEditor&); | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 80 | |||
| #define JUCE_BUILDNUMBER 81 | |||
| /** Current Juce version number. | |||
| @@ -912,8 +912,8 @@ const Image ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | |||
| Graphics g (snapshot); | |||
| g.setOrigin (pos.getX() - imageX, pos.getY() - imageY); | |||
| if (g.reduceClipRegion (0, 0, rowComp->getWidth(), rowComp->getHeight())) | |||
| rowComp->paintEntireComponent (g); | |||
| if (g.reduceClipRegion (rowComp->getLocalBounds())) | |||
| rowComp->paintEntireComponent (g, false); | |||
| } | |||
| } | |||
| @@ -281,7 +281,6 @@ Toolbar::Toolbar() | |||
| Toolbar::~Toolbar() | |||
| { | |||
| animator.cancelAllAnimations (true); | |||
| deleteAllChildren(); | |||
| } | |||
| @@ -552,11 +551,11 @@ void Toolbar::updateAllItemPositions (const bool animate) | |||
| if (animate) | |||
| { | |||
| animator.animateComponent (tc, newBounds, 200, 3.0, 0.0); | |||
| Desktop::getInstance().getAnimator().animateComponent (tc, newBounds, 1.0f, 200, false, 3.0, 0.0); | |||
| } | |||
| else | |||
| { | |||
| animator.cancelAnimation (tc, false); | |||
| Desktop::getInstance().getAnimator().cancelAnimation (tc, false); | |||
| tc->setBounds (newBounds); | |||
| } | |||
| @@ -644,12 +643,13 @@ void Toolbar::itemDragMove (const String&, Component* sourceComponent, int x, in | |||
| const int dragObjectLeft = vertical ? (y - tc->dragOffsetY) : (x - tc->dragOffsetX); | |||
| const int dragObjectRight = dragObjectLeft + (vertical ? tc->getHeight() : tc->getWidth()); | |||
| const Rectangle<int> current (animator.getComponentDestination (getChildComponent (newIndex))); | |||
| const Rectangle<int> current (Desktop::getInstance().getAnimator() | |||
| .getComponentDestination (getChildComponent (newIndex))); | |||
| ToolbarItemComponent* const prev = getNextActiveComponent (newIndex, -1); | |||
| if (prev != 0) | |||
| { | |||
| const Rectangle<int> previousPos (animator.getComponentDestination (prev)); | |||
| const Rectangle<int> previousPos (Desktop::getInstance().getAnimator().getComponentDestination (prev)); | |||
| if (abs (dragObjectLeft - (vertical ? previousPos.getY() : previousPos.getX()) | |||
| < abs (dragObjectRight - (vertical ? current.getBottom() : current.getRight())))) | |||
| @@ -661,7 +661,7 @@ void Toolbar::itemDragMove (const String&, Component* sourceComponent, int x, in | |||
| ToolbarItemComponent* const next = getNextActiveComponent (newIndex, 1); | |||
| if (next != 0) | |||
| { | |||
| const Rectangle<int> nextPos (animator.getComponentDestination (next)); | |||
| const Rectangle<int> nextPos (Desktop::getInstance().getAnimator().getComponentDestination (next)); | |||
| if (abs (dragObjectLeft - (vertical ? current.getY() : current.getX()) | |||
| > abs (dragObjectRight - (vertical ? nextPos.getBottom() : nextPos.getRight())))) | |||
| @@ -297,7 +297,6 @@ private: | |||
| Button* missingItemsButton; | |||
| bool vertical, isEditingActive; | |||
| ToolbarItemStyle toolbarStyle; | |||
| ComponentAnimator animator; | |||
| class MissingItemsComponent; | |||
| friend class MissingItemsComponent; | |||
| Array <ToolbarItemComponent*> items; | |||
| @@ -215,8 +215,8 @@ void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool | |||
| if (! contentArea.isEmpty()) | |||
| { | |||
| g.saveState(); | |||
| g.reduceClipRegion (contentArea); | |||
| g.setOrigin (contentArea.getX(), contentArea.getY()); | |||
| g.reduceClipRegion (0, 0, contentArea.getWidth(), contentArea.getHeight()); | |||
| paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down); | |||
| @@ -66,7 +66,8 @@ Component::Component() | |||
| bufferedImage_ (0), | |||
| mouseListeners_ (0), | |||
| keyListeners_ (0), | |||
| componentFlags_ (0) | |||
| componentFlags_ (0), | |||
| componentTransparency (0) | |||
| { | |||
| } | |||
| @@ -80,12 +81,15 @@ Component::Component (const String& name) | |||
| bufferedImage_ (0), | |||
| mouseListeners_ (0), | |||
| keyListeners_ (0), | |||
| componentFlags_ (0) | |||
| componentFlags_ (0), | |||
| componentTransparency (0) | |||
| { | |||
| } | |||
| Component::~Component() | |||
| { | |||
| static_jassert (sizeof (flags) <= sizeof (componentFlags_)); | |||
| componentListeners.call (&ComponentListener::componentBeingDeleted, *this); | |||
| if (parentComponent_ != 0) | |||
| @@ -213,117 +217,6 @@ bool Component::isShowing() const | |||
| return false; | |||
| } | |||
| //============================================================================== | |||
| class FadeOutProxyComponent : public Component, | |||
| public Timer | |||
| { | |||
| public: | |||
| FadeOutProxyComponent (Component* comp, | |||
| const int fadeLengthMs, | |||
| const int deltaXToMove, | |||
| const int deltaYToMove, | |||
| const float scaleFactorAtEnd) | |||
| : lastTime (0), | |||
| alpha (1.0f), | |||
| scale (1.0f) | |||
| { | |||
| image = comp->createComponentSnapshot (comp->getLocalBounds()); | |||
| setBounds (comp->getBounds()); | |||
| comp->getParentComponent()->addAndMakeVisible (this); | |||
| toBehind (comp); | |||
| alphaChangePerMs = -1.0f / (float)fadeLengthMs; | |||
| centreX = comp->getX() + comp->getWidth() * 0.5f; | |||
| xChangePerMs = deltaXToMove / (float)fadeLengthMs; | |||
| centreY = comp->getY() + comp->getHeight() * 0.5f; | |||
| yChangePerMs = deltaYToMove / (float)fadeLengthMs; | |||
| scaleChangePerMs = (scaleFactorAtEnd - 1.0f) / (float)fadeLengthMs; | |||
| setInterceptsMouseClicks (false, false); | |||
| // 30 fps is enough for a fade, but we need a higher rate if it's moving as well.. | |||
| startTimer (1000 / ((deltaXToMove == 0 && deltaYToMove == 0) ? 30 : 50)); | |||
| } | |||
| ~FadeOutProxyComponent() | |||
| { | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.setOpacity (alpha); | |||
| g.drawImage (image, | |||
| 0, 0, getWidth(), getHeight(), | |||
| 0, 0, image.getWidth(), image.getHeight()); | |||
| } | |||
| void timerCallback() | |||
| { | |||
| const uint32 now = Time::getMillisecondCounter(); | |||
| if (lastTime == 0) | |||
| lastTime = now; | |||
| const int msPassed = (now > lastTime) ? now - lastTime : 0; | |||
| lastTime = now; | |||
| alpha += alphaChangePerMs * msPassed; | |||
| if (alpha > 0) | |||
| { | |||
| if (xChangePerMs != 0.0f || yChangePerMs != 0.0f || scaleChangePerMs != 0.0f) | |||
| { | |||
| centreX += xChangePerMs * msPassed; | |||
| centreY += yChangePerMs * msPassed; | |||
| scale += scaleChangePerMs * msPassed; | |||
| const int w = roundToInt (image.getWidth() * scale); | |||
| const int h = roundToInt (image.getHeight() * scale); | |||
| setBounds (roundToInt (centreX) - w / 2, | |||
| roundToInt (centreY) - h / 2, | |||
| w, h); | |||
| } | |||
| repaint(); | |||
| } | |||
| else | |||
| { | |||
| delete this; | |||
| } | |||
| } | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| Image image; | |||
| uint32 lastTime; | |||
| float alpha, alphaChangePerMs; | |||
| float centreX, xChangePerMs; | |||
| float centreY, yChangePerMs; | |||
| float scale, scaleChangePerMs; | |||
| FadeOutProxyComponent (const FadeOutProxyComponent&); | |||
| FadeOutProxyComponent& operator= (const FadeOutProxyComponent&); | |||
| }; | |||
| void Component::fadeOutComponent (const int millisecondsToFade, | |||
| const int deltaXToMove, | |||
| const int deltaYToMove, | |||
| const float scaleFactorAtEnd) | |||
| { | |||
| //xxx won't work for comps without parents | |||
| if (isShowing() && millisecondsToFade > 0) | |||
| new FadeOutProxyComponent (this, millisecondsToFade, | |||
| deltaXToMove, deltaYToMove, scaleFactorAtEnd); | |||
| setVisible (false); | |||
| } | |||
| //============================================================================== | |||
| bool Component::isValidComponent() const | |||
| @@ -1464,6 +1357,33 @@ void Component::setRepaintsOnMouseActivity (const bool shouldRepaint) throw() | |||
| } | |||
| //============================================================================== | |||
| void Component::setAlpha (const float newAlpha) | |||
| { | |||
| const uint8 newIntAlpha = (uint8) (255 - jlimit (0, 255, roundToInt (newAlpha * 255.0))); | |||
| if (componentTransparency != newIntAlpha) | |||
| { | |||
| componentTransparency = newIntAlpha; | |||
| if (flags.hasHeavyweightPeerFlag) | |||
| { | |||
| ComponentPeer* const peer = getPeer(); | |||
| if (peer != 0) | |||
| peer->setAlpha (newAlpha); | |||
| } | |||
| else | |||
| { | |||
| repaint(); | |||
| } | |||
| } | |||
| } | |||
| float Component::getAlpha() const | |||
| { | |||
| return (255 - componentTransparency) / 255.0f; | |||
| } | |||
| void Component::repaintParent() | |||
| { | |||
| if (flags.visibleFlag) | |||
| @@ -1557,7 +1477,7 @@ void Component::renderComponent (Graphics& g) | |||
| paint (imG); | |||
| } | |||
| g.setColour (Colours::black); | |||
| g.setColour (Colours::black.withAlpha (getAlpha())); | |||
| g.drawImageAt (bufferedImage_, 0, 0); | |||
| } | |||
| else | |||
| @@ -1576,8 +1496,7 @@ void Component::renderComponent (Graphics& g) | |||
| { | |||
| g.saveState(); | |||
| if (g.reduceClipRegion (child->getX(), child->getY(), | |||
| child->getWidth(), child->getHeight())) | |||
| if (g.reduceClipRegion (child->getBounds())) | |||
| { | |||
| for (int j = i + 1; j < childComponentList_.size(); ++j) | |||
| { | |||
| @@ -1590,7 +1509,7 @@ void Component::renderComponent (Graphics& g) | |||
| if (! g.isClipEmpty()) | |||
| { | |||
| g.setOrigin (child->getX(), child->getY()); | |||
| child->paintEntireComponent (g); | |||
| child->paintEntireComponent (g, false); | |||
| } | |||
| } | |||
| @@ -1603,34 +1522,53 @@ void Component::renderComponent (Graphics& g) | |||
| g.restoreState(); | |||
| } | |||
| void Component::paintEntireComponent (Graphics& g) | |||
| void Component::paintEntireComponent (Graphics& g, bool ignoreAlphaLevel) | |||
| { | |||
| jassert (! g.isClipEmpty()); | |||
| #if JUCE_DEBUG | |||
| #if JUCE_DEBUG | |||
| flags.isInsidePaintCall = true; | |||
| #endif | |||
| #endif | |||
| if (effect_ != 0) | |||
| { | |||
| Image effectImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, | |||
| getWidth(), getHeight(), | |||
| ! flags.opaqueFlag, Image::NativeImage); | |||
| getWidth(), getHeight(), ! flags.opaqueFlag, Image::NativeImage); | |||
| { | |||
| Graphics g2 (effectImage); | |||
| renderComponent (g2); | |||
| } | |||
| effect_->applyEffect (effectImage, g); | |||
| effect_->applyEffect (effectImage, g, ignoreAlphaLevel ? 1.0f : getAlpha()); | |||
| } | |||
| else | |||
| { | |||
| renderComponent (g); | |||
| if (componentTransparency > 0 && ! ignoreAlphaLevel) | |||
| { | |||
| if (componentTransparency < 255) | |||
| { | |||
| Image temp (flags.opaqueFlag ? Image::RGB : Image::ARGB, | |||
| getWidth(), getHeight(), ! flags.opaqueFlag, Image::NativeImage); | |||
| { | |||
| Graphics tempG (temp); | |||
| tempG.reduceClipRegion (g.getClipBounds()); | |||
| paintEntireComponent (tempG, true); | |||
| } | |||
| g.setColour (Colours::black.withAlpha (getAlpha())); | |||
| g.drawImageAt (temp, 0, 0); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| renderComponent (g); | |||
| } | |||
| } | |||
| #if JUCE_DEBUG | |||
| #if JUCE_DEBUG | |||
| flags.isInsidePaintCall = false; | |||
| #endif | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| @@ -1649,7 +1587,7 @@ const Image Component::createComponentSnapshot (const Rectangle<int>& areaToGrab | |||
| Graphics imageContext (componentImage); | |||
| imageContext.setOrigin (-r.getX(), -r.getY()); | |||
| paintEntireComponent (imageContext); | |||
| paintEntireComponent (imageContext, true); | |||
| return componentImage; | |||
| } | |||
| @@ -161,31 +161,6 @@ public: | |||
| */ | |||
| bool isShowing() const; | |||
| /** Makes a component invisible using a groovy fade-out and animated zoom effect. | |||
| To do this, this function will cunningly: | |||
| - take a snapshot of the component as it currently looks | |||
| - call setVisible(false) on the component | |||
| - replace it with a special component that will continue drawing the | |||
| snapshot, animating it and gradually making it more transparent | |||
| - when it's gone, the special component will also be deleted | |||
| As soon as this method returns, the component can be safely removed and deleted | |||
| leaving the proxy to do the fade-out, so it's even ok to call this in a | |||
| component's destructor. | |||
| Passing non-zero x and y values will cause the ghostly component image to | |||
| also whizz off by this distance while fading out. If the scale factor is | |||
| not 1.0, it will also zoom from the component's current size to this new size. | |||
| One thing to be careful about is that the parent component must be able to cope | |||
| with this unknown component type being added to it. | |||
| */ | |||
| void fadeOutComponent (int lengthOfFadeOutInMilliseconds, | |||
| int deltaXToMove = 0, | |||
| int deltaYToMove = 0, | |||
| float scaleFactorAtEnd = 1.0f); | |||
| //============================================================================== | |||
| /** Makes this component appear as a window on the desktop. | |||
| @@ -905,8 +880,12 @@ public: | |||
| The graphics context may be left in an undefined state after this method returns, | |||
| so you may need to reset it if you're going to use it again. | |||
| If ignoreAlphaLevel is false, then the component will be drawn with the opacity level | |||
| specified by getAlpha(); if ignoreAlphaLevel is true, then this will be ignored and | |||
| an alpha of 1.0 will be used. | |||
| */ | |||
| void paintEntireComponent (Graphics& context); | |||
| void paintEntireComponent (Graphics& context, bool ignoreAlphaLevel); | |||
| //============================================================================== | |||
| @@ -1219,6 +1198,9 @@ public: | |||
| */ | |||
| virtual void enablementChanged(); | |||
| void setAlpha (float newAlpha); | |||
| float getAlpha() const; | |||
| //============================================================================== | |||
| /** Changes the mouse cursor shape to use when the mouse is over this component. | |||
| @@ -2081,6 +2063,8 @@ private: | |||
| ComponentFlags flags; | |||
| }; | |||
| uint8 componentTransparency; | |||
| //============================================================================== | |||
| void internalMouseEnter (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||
| void internalMouseExit (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||
| @@ -2097,7 +2081,7 @@ private: | |||
| void internalModifierKeysChanged(); | |||
| void internalChildrenChanged(); | |||
| void internalHierarchyChanged(); | |||
| void renderComponent (Graphics& context); | |||
| void renderComponent (Graphics& g); | |||
| void sendMovedResizedMessages (bool wasMoved, bool wasResized); | |||
| void repaintParent(); | |||
| void sendFakeMouseMove() const; | |||
| @@ -33,6 +33,7 @@ | |||
| #include "../../events/juce_AsyncUpdater.h" | |||
| #include "../../containers/juce_OwnedArray.h" | |||
| #include "../graphics/geometry/juce_RectangleList.h" | |||
| #include "layout/juce_ComponentAnimator.h" | |||
| class MouseInputSource; | |||
| class MouseInputSourceInternal; | |||
| class MouseListener; | |||
| @@ -225,6 +226,16 @@ public: | |||
| */ | |||
| Component* findComponentAt (const Point<int>& screenPosition) const; | |||
| /** The Desktop object has a ComponentAnimator instance which can be used for performing | |||
| your animations. | |||
| Having a single shared ComponentAnimator object makes it more efficient when multiple | |||
| components are being moved around simultaneously. It's also more convenient than having | |||
| to manage your own instance of one. | |||
| @see ComponentAnimator | |||
| */ | |||
| ComponentAnimator& getAnimator() throw() { return animator; } | |||
| //============================================================================== | |||
| /** Returns the number of MouseInputSource objects the system has at its disposal. | |||
| @@ -334,6 +345,8 @@ private: | |||
| int allowedOrientations; | |||
| ComponentAnimator animator; | |||
| void timerCallback(); | |||
| void resetTimer(); | |||
| @@ -294,7 +294,8 @@ private: | |||
| //============================================================================== | |||
| KeyMappingEditorComponent::KeyMappingEditorComponent (KeyPressMappingSet* const mappingManager, | |||
| const bool showResetToDefaultButton) | |||
| : mappings (mappingManager) | |||
| : mappings (mappingManager), | |||
| resetButton (TRANS ("reset to defaults")) | |||
| { | |||
| jassert (mappingManager != 0); // can't be null! | |||
| @@ -302,25 +303,22 @@ KeyMappingEditorComponent::KeyMappingEditorComponent (KeyPressMappingSet* const | |||
| setLinesDrawnForSubItems (false); | |||
| resetButton = 0; | |||
| if (showResetToDefaultButton) | |||
| { | |||
| addAndMakeVisible (resetButton = new TextButton (TRANS("reset to defaults"))); | |||
| resetButton->addButtonListener (this); | |||
| addAndMakeVisible (&resetButton); | |||
| resetButton.addButtonListener (this); | |||
| } | |||
| addAndMakeVisible (tree = new TreeView()); | |||
| tree->setColour (TreeView::backgroundColourId, findColour (backgroundColourId)); | |||
| tree->setRootItemVisible (false); | |||
| tree->setDefaultOpenness (true); | |||
| tree->setRootItem (this); | |||
| addAndMakeVisible (&tree); | |||
| tree.setColour (TreeView::backgroundColourId, findColour (backgroundColourId)); | |||
| tree.setRootItemVisible (false); | |||
| tree.setDefaultOpenness (true); | |||
| tree.setRootItem (this); | |||
| } | |||
| KeyMappingEditorComponent::~KeyMappingEditorComponent() | |||
| { | |||
| mappings->removeChangeListener (this); | |||
| deleteAllChildren(); | |||
| } | |||
| //============================================================================== | |||
| @@ -339,7 +337,7 @@ void KeyMappingEditorComponent::setColours (const Colour& mainBackground, | |||
| { | |||
| setColour (backgroundColourId, mainBackground); | |||
| setColour (textColourId, textColour); | |||
| tree->setColour (TreeView::backgroundColourId, mainBackground); | |||
| tree.setColour (TreeView::backgroundColourId, mainBackground); | |||
| } | |||
| void KeyMappingEditorComponent::parentHierarchyChanged() | |||
| @@ -351,22 +349,22 @@ void KeyMappingEditorComponent::resized() | |||
| { | |||
| int h = getHeight(); | |||
| if (resetButton != 0) | |||
| if (resetButton.isVisible()) | |||
| { | |||
| const int buttonHeight = 20; | |||
| h -= buttonHeight + 8; | |||
| int x = getWidth() - 8; | |||
| resetButton->changeWidthToFitText (buttonHeight); | |||
| resetButton->setTopRightPosition (x, h + 6); | |||
| resetButton.changeWidthToFitText (buttonHeight); | |||
| resetButton.setTopRightPosition (x, h + 6); | |||
| } | |||
| tree->setBounds (0, 0, getWidth(), h); | |||
| tree.setBounds (0, 0, getWidth(), h); | |||
| } | |||
| void KeyMappingEditorComponent::buttonClicked (Button* button) | |||
| { | |||
| if (button == resetButton) | |||
| if (button == &resetButton) | |||
| { | |||
| if (AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, | |||
| TRANS("Reset to defaults"), | |||
| @@ -380,7 +378,7 @@ void KeyMappingEditorComponent::buttonClicked (Button* button) | |||
| void KeyMappingEditorComponent::changeListenerCallback (void*) | |||
| { | |||
| ScopedPointer <XmlElement> oldOpenness (tree->getOpennessState (true)); | |||
| ScopedPointer <XmlElement> oldOpenness (tree.getOpennessState (true)); | |||
| clearSubItems(); | |||
| @@ -400,7 +398,7 @@ void KeyMappingEditorComponent::changeListenerCallback (void*) | |||
| } | |||
| if (oldOpenness != 0) | |||
| tree->restoreOpennessState (*oldOpenness); | |||
| tree.restoreOpennessState (*oldOpenness); | |||
| } | |||
| //============================================================================== | |||
| @@ -133,13 +133,14 @@ public: | |||
| private: | |||
| //============================================================================== | |||
| KeyPressMappingSet* mappings; | |||
| TreeView* tree; | |||
| friend class KeyMappingTreeViewItem; | |||
| friend class KeyCategoryTreeViewItem; | |||
| friend class KeyMappingItemComponent; | |||
| friend class KeyMappingChangeButton; | |||
| TextButton* resetButton; | |||
| KeyPressMappingSet* mappings; | |||
| TreeView tree; | |||
| TextButton resetButton; | |||
| void assignNewKey (CommandID commandID, int index); | |||
| @@ -27,6 +27,7 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "../windows/juce_ComponentPeer.h" | |||
| #include "juce_ComponentAnimator.h" | |||
| #include "../../../core/juce_Time.h" | |||
| @@ -40,59 +41,159 @@ public: | |||
| { | |||
| } | |||
| bool useTimeslice (const int elapsed) | |||
| void reset (const Rectangle<int>& finalBounds, | |||
| float finalAlpha, | |||
| int millisecondsToSpendMoving, | |||
| bool useProxyComponent, | |||
| double startSpeed_, double endSpeed_) | |||
| { | |||
| if (component == 0) | |||
| return false; | |||
| msElapsed = 0; | |||
| msTotal = jmax (1, millisecondsToSpendMoving); | |||
| lastProgress = 0; | |||
| destination = finalBounds; | |||
| destAlpha = finalAlpha; | |||
| isMoving = (finalBounds != component->getBounds()); | |||
| isChangingAlpha = (finalAlpha != component->getAlpha()); | |||
| left = component->getX(); | |||
| top = component->getY(); | |||
| right = component->getRight(); | |||
| bottom = component->getBottom(); | |||
| alpha = component->getAlpha(); | |||
| const double invTotalDistance = 4.0 / (startSpeed_ + endSpeed_ + 2.0); | |||
| startSpeed = jmax (0.0, startSpeed_ * invTotalDistance); | |||
| midSpeed = invTotalDistance; | |||
| endSpeed = jmax (0.0, endSpeed_ * invTotalDistance); | |||
| if (useProxyComponent) | |||
| proxy = new ProxyComponent (*component); | |||
| else | |||
| proxy = 0; | |||
| component->setVisible (! useProxyComponent); | |||
| } | |||
| msElapsed += elapsed; | |||
| double newProgress = msElapsed / (double) msTotal; | |||
| bool useTimeslice (const int elapsed) | |||
| { | |||
| Component* const c = proxy != 0 ? static_cast <Component*> (proxy) | |||
| : static_cast <Component*> (component); | |||
| if (newProgress >= 0 && newProgress < 1.0) | |||
| if (c != 0) | |||
| { | |||
| newProgress = timeToDistance (newProgress); | |||
| const double delta = (newProgress - lastProgress) / (1.0 - lastProgress); | |||
| jassert (newProgress >= lastProgress); | |||
| lastProgress = newProgress; | |||
| left += (destination.getX() - left) * delta; | |||
| top += (destination.getY() - top) * delta; | |||
| right += (destination.getRight() - right) * delta; | |||
| bottom += (destination.getBottom() - bottom) * delta; | |||
| msElapsed += elapsed; | |||
| double newProgress = msElapsed / (double) msTotal; | |||
| if (delta < 1.0) | |||
| if (newProgress >= 0 && newProgress < 1.0) | |||
| { | |||
| const Rectangle<int> newBounds (roundToInt (left), | |||
| roundToInt (top), | |||
| roundToInt (right - left), | |||
| roundToInt (bottom - top)); | |||
| newProgress = timeToDistance (newProgress); | |||
| const double delta = (newProgress - lastProgress) / (1.0 - lastProgress); | |||
| jassert (newProgress >= lastProgress); | |||
| lastProgress = newProgress; | |||
| if (newBounds != destination) | |||
| if (delta < 1.0) | |||
| { | |||
| component->setBounds (newBounds); | |||
| return true; | |||
| bool stillBusy = false; | |||
| if (isMoving) | |||
| { | |||
| left += (destination.getX() - left) * delta; | |||
| top += (destination.getY() - top) * delta; | |||
| right += (destination.getRight() - right) * delta; | |||
| bottom += (destination.getBottom() - bottom) * delta; | |||
| const Rectangle<int> newBounds (roundToInt (left), | |||
| roundToInt (top), | |||
| roundToInt (right - left), | |||
| roundToInt (bottom - top)); | |||
| if (newBounds != destination) | |||
| { | |||
| c->setBounds (newBounds); | |||
| stillBusy = true; | |||
| } | |||
| } | |||
| if (isChangingAlpha) | |||
| { | |||
| alpha += (destAlpha - alpha) * delta; | |||
| c->setAlpha ((float) alpha); | |||
| stillBusy = true; | |||
| } | |||
| if (stillBusy) | |||
| return true; | |||
| } | |||
| } | |||
| } | |||
| component->setBounds (destination); | |||
| moveToFinalDestination(); | |||
| return false; | |||
| } | |||
| void moveToFinalDestination() | |||
| { | |||
| if (component != 0) | |||
| { | |||
| component->setAlpha ((float) destAlpha); | |||
| component->setBounds (destination); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class ProxyComponent : public Component | |||
| { | |||
| public: | |||
| ProxyComponent (Component& component) | |||
| : image (component.createComponentSnapshot (component.getLocalBounds())) | |||
| { | |||
| setBounds (component.getBounds()); | |||
| setAlpha (component.getAlpha()); | |||
| setInterceptsMouseClicks (false, false); | |||
| Component* const parent = component.getParentComponent(); | |||
| if (parent != 0) | |||
| parent->addAndMakeVisible (this); | |||
| else if (component.isOnDesktop() && component.getPeer() != 0) | |||
| addToDesktop (component.getPeer()->getStyleFlags()); | |||
| else | |||
| jassertfalse; // seem to be trying to animate a component that's not visible.. | |||
| setVisible (true); | |||
| toBehind (&component); | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| g.setOpacity (1.0f); | |||
| g.drawImage (image, 0, 0, getWidth(), getHeight(), | |||
| 0, 0, image.getWidth(), image.getHeight()); | |||
| } | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| Image image; | |||
| ProxyComponent (const ProxyComponent&); | |||
| ProxyComponent& operator= (const ProxyComponent&); | |||
| }; | |||
| Component::SafePointer<Component> component; | |||
| ScopedPointer<Component> proxy; | |||
| Rectangle<int> destination; | |||
| double destAlpha; | |||
| int msElapsed, msTotal; | |||
| double startSpeed, midSpeed, endSpeed, lastProgress; | |||
| double left, top, right, bottom; | |||
| double left, top, right, bottom, alpha; | |||
| bool isMoving, isChangingAlpha; | |||
| private: | |||
| inline double timeToDistance (const double time) const | |||
| double timeToDistance (const double time) const throw() | |||
| { | |||
| return (time < 0.5) ? time * (startSpeed + time * (midSpeed - startSpeed)) | |||
| : 0.5 * (startSpeed + 0.5 * (midSpeed - startSpeed)) | |||
| @@ -121,11 +222,16 @@ ComponentAnimator::AnimationTask* ComponentAnimator::findTaskFor (Component* con | |||
| } | |||
| void ComponentAnimator::animateComponent (Component* const component, | |||
| const Rectangle<int>& finalPosition, | |||
| const Rectangle<int>& finalBounds, | |||
| const float finalAlpha, | |||
| const int millisecondsToSpendMoving, | |||
| const bool useProxyComponent, | |||
| const double startSpeed, | |||
| const double endSpeed) | |||
| { | |||
| // the speeds must be 0 or greater! | |||
| jassert (startSpeed >= 0 && endSpeed >= 0) | |||
| if (component != 0) | |||
| { | |||
| AnimationTask* at = findTaskFor (component); | |||
| @@ -137,23 +243,8 @@ void ComponentAnimator::animateComponent (Component* const component, | |||
| sendChangeMessage (this); | |||
| } | |||
| at->msElapsed = 0; | |||
| at->lastProgress = 0; | |||
| at->msTotal = jmax (1, millisecondsToSpendMoving); | |||
| at->destination = finalPosition; | |||
| // the speeds must be 0 or greater! | |||
| jassert (startSpeed >= 0 && endSpeed >= 0) | |||
| const double invTotalDistance = 4.0 / (startSpeed + endSpeed + 2.0); | |||
| at->startSpeed = jmax (0.0, startSpeed * invTotalDistance); | |||
| at->midSpeed = invTotalDistance; | |||
| at->endSpeed = jmax (0.0, endSpeed * invTotalDistance); | |||
| at->left = component->getX(); | |||
| at->top = component->getY(); | |||
| at->right = component->getRight(); | |||
| at->bottom = component->getBottom(); | |||
| at->reset (finalBounds, finalAlpha, millisecondsToSpendMoving, | |||
| useProxyComponent, startSpeed, endSpeed); | |||
| if (! isTimerRunning()) | |||
| { | |||
| @@ -163,6 +254,27 @@ void ComponentAnimator::animateComponent (Component* const component, | |||
| } | |||
| } | |||
| void ComponentAnimator::fadeOut (Component* component, int millisecondsToTake) | |||
| { | |||
| if (component != 0) | |||
| { | |||
| if (component->isShowing() && millisecondsToTake > 0) | |||
| animateComponent (component, component->getBounds(), 0.0f, millisecondsToTake, true, 1.0, 1.0); | |||
| component->setVisible (false); | |||
| } | |||
| } | |||
| void ComponentAnimator::fadeIn (Component* component, int millisecondsToTake) | |||
| { | |||
| if (component != 0 && ! (component->isVisible() && component->getAlpha() == 1.0f)) | |||
| { | |||
| component->setAlpha (0.0f); | |||
| component->setVisible (true); | |||
| animateComponent (component, component->getBounds(), 1.0f, millisecondsToTake, false, 1.0, 1.0); | |||
| } | |||
| } | |||
| void ComponentAnimator::cancelAllAnimations (const bool moveComponentsToTheirFinalPositions) | |||
| { | |||
| if (tasks.size() > 0) | |||
| @@ -193,14 +305,13 @@ void ComponentAnimator::cancelAnimation (Component* const component, | |||
| const Rectangle<int> ComponentAnimator::getComponentDestination (Component* const component) | |||
| { | |||
| jassert (component != 0); | |||
| AnimationTask* const at = findTaskFor (component); | |||
| if (at != 0) | |||
| return at->destination; | |||
| else if (component != 0) | |||
| return component->getBounds(); | |||
| return Rectangle<int>(); | |||
| return component->getBounds(); | |||
| } | |||
| bool ComponentAnimator::isAnimating (Component* component) const | |||
| @@ -33,19 +33,24 @@ | |||
| //============================================================================== | |||
| /** | |||
| Animates a set of components, moving it to a new position. | |||
| Animates a set of components, moving them to a new position and/or fading their | |||
| alpha levels. | |||
| To use this, create a ComponentAnimator, and use its animateComponent() method | |||
| to tell it to move components to destination positions. Any number of | |||
| components can be animated by one ComponentAnimator object (if you've got a | |||
| lot of components to move, it's much more efficient to share a single animator | |||
| than to have many animators running at once). | |||
| To animate a component, create a ComponentAnimator instance or (preferably) use the | |||
| global animator object provided by Desktop::getAnimator(), and call its animateComponent() | |||
| method to commence the movement. | |||
| You'll need to make sure the animator object isn't deleted before it finishes | |||
| moving the components. | |||
| If you're using your own ComponentAnimator instance, you'll need to make sure it isn't | |||
| deleted before it finishes moving the components, or they'll be abandoned before reaching their | |||
| destinations. | |||
| It's ok to delete components while they're being animated - the animator will detect this | |||
| and safely stop using them. | |||
| The class is a ChangeBroadcaster and sends a notification when any components | |||
| start or finish being animated. | |||
| @see Desktop::getAnimator | |||
| */ | |||
| class JUCE_API ComponentAnimator : public ChangeBroadcaster, | |||
| private Timer | |||
| @@ -68,29 +73,49 @@ public: | |||
| movement. | |||
| @param component the component to move | |||
| @param finalPosition the destination position and size to move it to | |||
| @param millisecondsToSpendMoving how long, in milliseconds, it should take | |||
| to arrive at its destination | |||
| @param startSpeed a value to indicate the relative start speed of the | |||
| animation. If this is 0, the component will start | |||
| by accelerating from rest; higher values mean that it | |||
| will have an initial speed greater than zero. If the | |||
| value if greater than 1, it will decelerate towards the | |||
| middle of its journey. To move the component at a constant | |||
| rate for its entire animation, set both the start and | |||
| end speeds to 1.0 | |||
| @param endSpeed a relative speed at which the component should be moving | |||
| when the animation finishes. If this is 0, the component | |||
| will decelerate to a standstill at its final position; higher | |||
| values mean the component will still be moving when it stops. | |||
| To move the component at a constant rate for its entire | |||
| animation, set both the start and end speeds to 1.0 | |||
| @param finalBounds the destination bounds to which the component should move. To leave the | |||
| component in the same place, just pass component->getBounds() for this value | |||
| @param finalAlpha the alpha value that the component should have at the end of the animation | |||
| @param animationDurationMilliseconds how long the animation should last, in milliseconds | |||
| @param useProxyComponent if true, this means the component should be replaced by an internally | |||
| managed temporary component which is a snapshot of the original component. | |||
| This avoids the component having to paint itself as it moves, so may | |||
| be more efficient. This option also allows you to delete the original | |||
| component immediately after starting the animation, because the animation | |||
| can proceed without it. If you use a proxy, the original component will be | |||
| made invisible by this call, and then will become visible again at the end | |||
| of the animation. It'll also mean that the proxy component will be temporarily | |||
| added to the component's parent, so avoid it if this might confuse the parent | |||
| component, or if there's a chance the parent might decide to delete its children. | |||
| @param startSpeed a value to indicate the relative start speed of the animation. If this is 0, | |||
| the component will start by accelerating from rest; higher values mean that it | |||
| will have an initial speed greater than zero. If the value if greater than 1, it | |||
| will decelerate towards the middle of its journey. To move the component at a | |||
| constant rate for its entire animation, set both the start and end speeds to 1.0 | |||
| @param endSpeed a relative speed at which the component should be moving when the animation finishes. | |||
| If this is 0, the component will decelerate to a standstill at its final position; | |||
| higher values mean the component will still be moving when it stops. To move the component | |||
| at a constant rate for its entire animation, set both the start and end speeds to 1.0 | |||
| */ | |||
| void animateComponent (Component* component, | |||
| const Rectangle<int>& finalPosition, | |||
| int millisecondsToSpendMoving, | |||
| double startSpeed = 1.0, | |||
| double endSpeed = 1.0); | |||
| const Rectangle<int>& finalBounds, | |||
| float finalAlpha, | |||
| int animationDurationMilliseconds, | |||
| bool useProxyComponent, | |||
| double startSpeed, | |||
| double endSpeed); | |||
| /** Begins a fade-out of this components alpha level. | |||
| This is a quick way of invoking animateComponent() with a target alpha value of 0.0f, using | |||
| a proxy. You're safe to delete the component after calling this method, and this won't | |||
| interfere with the animation's progress. | |||
| */ | |||
| void fadeOut (Component* component, int millisecondsToTake); | |||
| /** Begins a fade-in of a component. | |||
| This is a quick way of invoking animateComponent() with a target alpha value of 1.0f. | |||
| */ | |||
| void fadeIn (Component* component, int millisecondsToTake); | |||
| /** Stops a component if it's currently being animated. | |||
| @@ -119,8 +144,7 @@ public: | |||
| */ | |||
| const Rectangle<int> getComponentDestination (Component* component); | |||
| /** Returns true if the specified component is currently being animated. | |||
| */ | |||
| /** Returns true if the specified component is currently being animated. */ | |||
| bool isAnimating (Component* component) const; | |||
| //============================================================================== | |||
| @@ -2556,7 +2556,7 @@ void LookAndFeel::drawCallOutBoxBackground (CallOutBox& box, Graphics& g, const | |||
| DropShadowEffect shadow; | |||
| shadow.setShadowProperties (5.0f, 0.4f, 0, 2); | |||
| shadow.applyEffect (content, g); | |||
| shadow.applyEffect (content, g, 1.0f); | |||
| } | |||
| @@ -415,7 +415,7 @@ public: | |||
| //============================================================================== | |||
| // hide this and all sub-comps | |||
| void hide (const PopupMenu::Item* const item) | |||
| void hide (const PopupMenu::Item* const item, const bool makeInvisible) | |||
| { | |||
| if (isVisible()) | |||
| { | |||
| @@ -425,7 +425,9 @@ public: | |||
| currentChild = 0; | |||
| exitModalState (item != 0 ? item->itemId : 0); | |||
| setVisible (false); | |||
| if (makeInvisible) | |||
| setVisible (false); | |||
| if (item != 0 | |||
| && item->commandManager != 0 | |||
| @@ -448,11 +450,11 @@ public: | |||
| { | |||
| // need a copy of this on the stack as the one passed in will get deleted during this call | |||
| const PopupMenu::Item mi (*item); | |||
| hide (&mi); | |||
| hide (&mi, false); | |||
| } | |||
| else | |||
| { | |||
| hide (0); | |||
| hide (0, false); | |||
| } | |||
| } | |||
| } | |||
| @@ -501,7 +503,7 @@ public: | |||
| Component::SafePointer<Window> parentWindow (owner); | |||
| PopupMenu::ItemComponent* currentChildOfParent = parentWindow->currentChild; | |||
| hide (0); | |||
| hide (0, true); | |||
| if (parentWindow != 0) | |||
| parentWindow->setCurrentlyHighlightedChild (currentChildOfParent); | |||
| @@ -660,7 +662,7 @@ public: | |||
| if (hideOnExit && hasBeenOver && ! isOverAny) | |||
| { | |||
| hide (0); | |||
| hide (0, true); | |||
| } | |||
| else | |||
| { | |||
| @@ -1191,7 +1193,7 @@ private: | |||
| { | |||
| if (isOver && (c != 0) && (activeSubMenu != 0)) | |||
| { | |||
| activeSubMenu->hide (0); | |||
| activeSubMenu->hide (0, true); | |||
| } | |||
| if (! isOver) | |||
| @@ -1504,6 +1506,9 @@ public: | |||
| managerOfChosenCommand->invoke (info, true); | |||
| } | |||
| // (this would be the place to fade out the component, if that's what's required) | |||
| component = 0; | |||
| } | |||
| ApplicationCommandManager* managerOfChosenCommand; | |||
| @@ -158,19 +158,17 @@ public: | |||
| if (dropAccepted || source == 0) | |||
| { | |||
| fadeOutComponent (120); | |||
| Desktop::getInstance().getAnimator().fadeOut (this, 120); | |||
| } | |||
| else | |||
| { | |||
| const Point<int> target (source->relativePositionToGlobal (Point<int> (source->getWidth() / 2, | |||
| source->getHeight() / 2))); | |||
| const Point<int> target (source->relativePositionToGlobal (source->getLocalBounds().getCentre())); | |||
| const Point<int> ourCentre (relativePositionToGlobal (getLocalBounds().getCentre())); | |||
| const Point<int> ourCentre (relativePositionToGlobal (Point<int> (getWidth() / 2, | |||
| getHeight() / 2))); | |||
| fadeOutComponent (120, | |||
| target.getX() - ourCentre.getX(), | |||
| target.getY() - ourCentre.getY()); | |||
| Desktop::getInstance().getAnimator().animateComponent (this, | |||
| getBounds() + (target - ourCentre), | |||
| 0.0f, 120, | |||
| true, 1.0, 1.0); | |||
| } | |||
| } | |||
| @@ -34,10 +34,6 @@ BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| class TextPropLabel : public Label | |||
| { | |||
| TextPropertyComponent& owner; | |||
| int maxChars; | |||
| bool isMultiline; | |||
| public: | |||
| TextPropLabel (TextPropertyComponent& owner_, | |||
| const int maxChars_, const bool isMultiline_) | |||
| @@ -52,14 +48,9 @@ public: | |||
| setColour (outlineColourId, findColour (ComboBox::outlineColourId)); | |||
| } | |||
| ~TextPropLabel() | |||
| { | |||
| } | |||
| TextEditor* createEditorComponent() | |||
| { | |||
| TextEditor* const textEditor = Label::createEditorComponent(); | |||
| textEditor->setInputRestrictions (maxChars); | |||
| if (isMultiline) | |||
| @@ -75,6 +66,11 @@ public: | |||
| { | |||
| owner.textWasEdited(); | |||
| } | |||
| private: | |||
| TextPropertyComponent& owner; | |||
| int maxChars; | |||
| bool isMultiline; | |||
| }; | |||
| //============================================================================== | |||
| @@ -99,7 +95,6 @@ TextPropertyComponent::TextPropertyComponent (const Value& valueToControl, | |||
| TextPropertyComponent::~TextPropertyComponent() | |||
| { | |||
| deleteAllChildren(); | |||
| } | |||
| void TextPropertyComponent::setText (const String& newText) | |||
| @@ -89,7 +89,7 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| Label* textEditor; | |||
| ScopedPointer<Label> textEditor; | |||
| void createEditor (int maxNumChars, bool isMultiLine); | |||
| @@ -117,18 +117,8 @@ void BubbleComponent::setPosition (const int arrowTipX_, | |||
| //============================================================================== | |||
| void BubbleComponent::setPosition (const Rectangle<int>& rectangleToPointTo) | |||
| { | |||
| Rectangle<int> availableSpace; | |||
| if (getParentComponent() != 0) | |||
| { | |||
| availableSpace.setSize (getParentComponent()->getWidth(), | |||
| getParentComponent()->getHeight()); | |||
| } | |||
| else | |||
| { | |||
| availableSpace = getParentMonitorArea(); | |||
| } | |||
| Rectangle<int> availableSpace (getParentComponent() != 0 ? getParentComponent()->getLocalBounds() | |||
| : getParentMonitorArea()); | |||
| int x = 0; | |||
| int y = 0; | |||
| int w = 150; | |||
| @@ -41,7 +41,7 @@ BubbleMessageComponent::BubbleMessageComponent (int fadeOutLengthMs) | |||
| BubbleMessageComponent::~BubbleMessageComponent() | |||
| { | |||
| fadeOutComponent (fadeOutLength); | |||
| Desktop::getInstance().getAnimator().fadeOut (this, fadeOutLength); | |||
| } | |||
| void BubbleMessageComponent::showAt (int x, int y, | |||
| @@ -123,10 +123,11 @@ void BubbleMessageComponent::timerCallback() | |||
| else if (expiryTime != 0 && Time::getMillisecondCounter() > expiryTime) | |||
| { | |||
| stopTimer(); | |||
| fadeOutComponent (fadeOutLength); | |||
| if (deleteAfterUse) | |||
| delete this; | |||
| else | |||
| Desktop::getInstance().getAnimator().fadeOut (this, fadeOutLength); | |||
| } | |||
| } | |||
| @@ -56,6 +56,7 @@ public: | |||
| void setSize (int, int) {} | |||
| void setBounds (int, int, int, int, bool) {} | |||
| void setMinimised (bool) {} | |||
| void setAlpha (float /*newAlpha*/) {} | |||
| bool isMinimised() const { return false; } | |||
| void setFullScreen (bool) {} | |||
| bool isFullScreen() const { return false; } | |||
| @@ -266,12 +267,13 @@ void MagnifierComponent::paint (Graphics& g) | |||
| } | |||
| Image temp (Image::ARGB, jmax (w, srcX + srcW), jmax (h, srcY + srcH), false); | |||
| temp.clear (Rectangle<int> (srcX, srcY, srcW, srcH)); | |||
| const Rectangle<int> area (srcX, srcY, srcW, srcH); | |||
| temp.clear (area); | |||
| { | |||
| Graphics g2 (temp); | |||
| g2.reduceClipRegion (srcX, srcY, srcW, srcH); | |||
| holderComp->paintEntireComponent (g2); | |||
| g2.reduceClipRegion (area); | |||
| holderComp->paintEntireComponent (g2, false); | |||
| } | |||
| g.setImageResamplingQuality (quality); | |||
| @@ -126,7 +126,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) | |||
| JUCE_TRY | |||
| { | |||
| component->paintEntireComponent (g); | |||
| component->paintEntireComponent (g, true); | |||
| } | |||
| JUCE_CATCH_EXCEPTION | |||
| @@ -291,6 +291,9 @@ public: | |||
| */ | |||
| virtual void performAnyPendingRepaintsNow() = 0; | |||
| /** Changes the window's transparency. */ | |||
| virtual void setAlpha (float newAlpha) = 0; | |||
| //============================================================================== | |||
| void handleMouseEvent (int touchIndex, const Point<int>& positionWithinPeer, const ModifierKeys& newMods, int64 time); | |||
| void handleMouseWheel (int touchIndex, const Point<int>& positionWithinPeer, int64 time, float x, float y); | |||
| @@ -204,8 +204,8 @@ void DocumentWindow::paint (Graphics& g) | |||
| } | |||
| const Rectangle<int> titleBarArea (getTitleBarArea()); | |||
| g.reduceClipRegion (titleBarArea); | |||
| g.setOrigin (titleBarArea.getX(), titleBarArea.getY()); | |||
| g.reduceClipRegion (0, 0, titleBarArea.getWidth(), titleBarArea.getHeight()); | |||
| int titleSpaceX1 = 6; | |||
| int titleSpaceX2 = titleBarArea.getWidth() - 6; | |||
| @@ -148,7 +148,7 @@ public: | |||
| { | |||
| // plot the fist pixel of this segment, including any accumulated | |||
| // levels from smaller segments that haven't been drawn yet | |||
| levelAccumulator += (0xff - (x & 0xff)) * level; | |||
| levelAccumulator += (0x100 - (x & 0xff)) * level; | |||
| levelAccumulator >>= 8; | |||
| x >>= 8; | |||
| @@ -86,10 +86,15 @@ bool Graphics::isVectorDevice() const | |||
| return context->isVectorDevice(); | |||
| } | |||
| bool Graphics::reduceClipRegion (const int x, const int y, const int w, const int h) | |||
| bool Graphics::reduceClipRegion (const Rectangle<int>& area) | |||
| { | |||
| saveStateIfPending(); | |||
| return context->clipToRectangle (Rectangle<int> (x, y, w, h)); | |||
| return context->clipToRectangle (area); | |||
| } | |||
| bool Graphics::reduceClipRegion (const int x, const int y, const int w, const int h) | |||
| { | |||
| return reduceClipRegion (Rectangle<int> (x, y, w, h)); | |||
| } | |||
| bool Graphics::reduceClipRegion (const RectangleList& clipRegion) | |||
| @@ -563,6 +563,13 @@ public: | |||
| */ | |||
| bool reduceClipRegion (int x, int y, int width, int height); | |||
| /** Intersects the current clipping region with another region. | |||
| @returns true if the resulting clipping region is non-zero in size | |||
| @see setOrigin, clipRegionIntersects | |||
| */ | |||
| bool reduceClipRegion (const Rectangle<int>& area); | |||
| /** Intersects the current clipping region with a rectangle list region. | |||
| @returns true if the resulting clipping region is non-zero in size | |||
| @@ -1907,9 +1907,8 @@ public: | |||
| ColourGradient g2 (*(fillType.gradient)); | |||
| g2.multiplyOpacity (fillType.getOpacity()); | |||
| g2.point1.addXY (-0.5f, -0.5f); | |||
| g2.point2.addXY (-0.5f, -0.5f); | |||
| AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); | |||
| AffineTransform transform (fillType.transform.translated (xOffset - 0.5f, yOffset - 0.5f)); | |||
| const bool isIdentity = transform.isOnlyTranslation(); | |||
| if (isIdentity) | |||
| @@ -687,6 +687,8 @@ const Rectangle<float> DrawableComposite::refreshFromValueTree (const ValueTree& | |||
| } | |||
| } | |||
| invalidatePoints(); | |||
| if (redrawAll) | |||
| damage = damage.getUnion (getBounds()); | |||
| else if (! damage.isEmpty()) | |||
| @@ -73,8 +73,8 @@ bool DrawableRectangle::rebuildPath (Path& path) const | |||
| const float w = Line<float> (points[0], points[1]).getLength(); | |||
| const float h = Line<float> (points[0], points[2]).getLength(); | |||
| const float cornerSizeX = cornerSize.x.resolve (parent); | |||
| const float cornerSizeY = cornerSize.y.resolve (parent); | |||
| const float cornerSizeX = (float) cornerSize.x.resolve (parent); | |||
| const float cornerSizeY = (float) cornerSize.y.resolve (parent); | |||
| path.clear(); | |||
| @@ -93,7 +93,7 @@ void DrawableShape::setBrush (const Drawable::RenderingContext& context, const F | |||
| } | |||
| bool DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, | |||
| Expression::EvaluationContext* nameFinder, | |||
| Expression::EvaluationContext* /*nameFinder*/, | |||
| ImageProvider* imageProvider) | |||
| { | |||
| bool hasChanged = false; | |||
| @@ -59,7 +59,7 @@ void DropShadowEffect::setShadowProperties (const float newRadius, | |||
| opacity = newOpacity; | |||
| } | |||
| void DropShadowEffect::applyEffect (Image& image, Graphics& g) | |||
| void DropShadowEffect::applyEffect (Image& image, Graphics& g, float alpha) | |||
| { | |||
| const int w = image.getWidth(); | |||
| const int h = image.getHeight(); | |||
| @@ -101,10 +101,10 @@ void DropShadowEffect::applyEffect (Image& image, Graphics& g) | |||
| } | |||
| } | |||
| g.setColour (Colours::black.withAlpha (opacity)); | |||
| g.setColour (Colours::black.withAlpha (opacity * alpha)); | |||
| g.drawImageAt (shadowImage, offsetX, offsetY, true); | |||
| g.setOpacity (1.0f); | |||
| g.setOpacity (alpha); | |||
| g.drawImageAt (image, 0, 0); | |||
| } | |||
| @@ -77,7 +77,7 @@ public: | |||
| //============================================================================== | |||
| /** @internal */ | |||
| void applyEffect (Image& sourceImage, Graphics& destContext); | |||
| void applyEffect (Image& sourceImage, Graphics& destContext, float alpha); | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| @@ -49,7 +49,7 @@ void GlowEffect::setGlowProperties (const float newRadius, | |||
| colour = newColour; | |||
| } | |||
| void GlowEffect::applyEffect (Image& image, Graphics& g) | |||
| void GlowEffect::applyEffect (Image& image, Graphics& g, float alpha) | |||
| { | |||
| Image temp (image.getFormat(), image.getWidth(), image.getHeight(), true); | |||
| @@ -60,10 +60,10 @@ void GlowEffect::applyEffect (Image& image, Graphics& g) | |||
| blurKernel.applyToImage (temp, image, image.getBounds()); | |||
| g.setColour (colour); | |||
| g.setColour (colour.withMultipliedAlpha (alpha)); | |||
| g.drawImageAt (temp, 0, 0, true); | |||
| g.setOpacity (1.0f); | |||
| g.setOpacity (alpha); | |||
| g.drawImageAt (image, 0, 0, false); | |||
| } | |||
| @@ -63,7 +63,7 @@ public: | |||
| //============================================================================== | |||
| /** @internal */ | |||
| void applyEffect (Image& sourceImage, Graphics& destContext); | |||
| void applyEffect (Image& sourceImage, Graphics& destContext, float alpha); | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| @@ -53,9 +53,12 @@ public: | |||
| its paint() method. The image may or may not have an alpha | |||
| channel, depending on whether the component is opaque. | |||
| @param destContext the graphics context to use to draw the resultant image. | |||
| @param alpha the alpha with which to draw the resultant image to the | |||
| target context | |||
| */ | |||
| virtual void applyEffect (Image& sourceImage, | |||
| Graphics& destContext) = 0; | |||
| Graphics& destContext, | |||
| float alpha) = 0; | |||
| /** Destructor. */ | |||
| virtual ~ImageEffectFilter() {} | |||
| @@ -1,54 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| 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_ReduceOpacityEffect.h" | |||
| //============================================================================== | |||
| ReduceOpacityEffect::ReduceOpacityEffect (const float opacity_) | |||
| : opacity (opacity_) | |||
| { | |||
| } | |||
| ReduceOpacityEffect::~ReduceOpacityEffect() | |||
| { | |||
| } | |||
| void ReduceOpacityEffect::setOpacity (const float newOpacity) | |||
| { | |||
| opacity = jlimit (0.0f, 1.0f, newOpacity); | |||
| } | |||
| void ReduceOpacityEffect::applyEffect (Image& image, Graphics& g) | |||
| { | |||
| g.setOpacity (opacity); | |||
| g.drawImageAt (image, 0, 0); | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -1,74 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| 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_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| #define __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| #include "juce_ImageEffectFilter.h" | |||
| //============================================================================== | |||
| /** | |||
| An effect filter that reduces the image's opacity. | |||
| This can be used to make a component (and its child components) more | |||
| transparent. | |||
| @see Component::setComponentEffect | |||
| */ | |||
| class JUCE_API ReduceOpacityEffect : public ImageEffectFilter | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates the effect object. | |||
| The opacity of the component to which the effect is applied will be | |||
| scaled by the given factor (in the range 0 to 1.0f). | |||
| */ | |||
| ReduceOpacityEffect (float opacity = 1.0f); | |||
| /** Destructor. */ | |||
| ~ReduceOpacityEffect(); | |||
| /** Sets how much to scale the component's opacity. | |||
| @param newOpacity should be between 0 and 1.0f | |||
| */ | |||
| void setOpacity (float newOpacity); | |||
| //============================================================================== | |||
| /** @internal */ | |||
| void applyEffect (Image& sourceImage, Graphics& destContext); | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| float opacity; | |||
| }; | |||
| #endif // __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| @@ -56,12 +56,8 @@ public: | |||
| RelativeCoordinate (double absoluteDistanceFromOrigin); | |||
| /** Recreates a coordinate from a string description. | |||
| The string will be parsed by ExpressionParser::parse(). | |||
| @param stringVersion the expression to use | |||
| @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. | |||
| @see toString | |||
| */ | |||
| RelativeCoordinate (const String& stringVersion); | |||
| @@ -677,9 +677,6 @@ | |||
| #ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__ | |||
| #include "gui/graphics/effects/juce_ImageEffectFilter.h" | |||
| #endif | |||
| #ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ | |||
| #include "gui/graphics/effects/juce_ReduceOpacityEffect.h" | |||
| #endif | |||
| #ifndef __JUCE_FONT_JUCEHEADER__ | |||
| #include "gui/graphics/fonts/juce_Font.h" | |||
| #endif | |||
| @@ -820,6 +820,11 @@ public: | |||
| return screenPosition - getScreenPosition(); | |||
| } | |||
| void setAlpha (float newAlpha) | |||
| { | |||
| //xxx todo! | |||
| } | |||
| void setMinimised (bool shouldBeMinimised) | |||
| { | |||
| if (shouldBeMinimised) | |||
| @@ -111,6 +111,7 @@ public: | |||
| const Point<int> getScreenPosition() const; | |||
| const Point<int> relativePositionToGlobal (const Point<int>& relativePosition); | |||
| const Point<int> globalPositionToRelative (const Point<int>& screenPosition); | |||
| void setAlpha (float newAlpha); | |||
| void setMinimised (bool shouldBeMinimised); | |||
| bool isMinimised() const; | |||
| void setFullScreen (bool shouldBeFullScreen); | |||
| @@ -576,6 +577,11 @@ CGRect UIViewComponentPeer::constrainRect (CGRect r) | |||
| return r; | |||
| } | |||
| void UIViewComponentPeer::setAlpha (float newAlpha) | |||
| { | |||
| [[view window] setAlpha: (CGFloat) newAlpha]; | |||
| } | |||
| void UIViewComponentPeer::setMinimised (bool shouldBeMinimised) | |||
| { | |||
| } | |||
| @@ -160,6 +160,7 @@ public: | |||
| const Point<int> getScreenPosition() const; | |||
| const Point<int> relativePositionToGlobal (const Point<int>& relativePosition); | |||
| const Point<int> globalPositionToRelative (const Point<int>& screenPosition); | |||
| void setAlpha (float newAlpha); | |||
| void setMinimised (bool shouldBeMinimised); | |||
| bool isMinimised() const; | |||
| void setFullScreen (bool shouldBeFullScreen); | |||
| @@ -880,8 +881,6 @@ NSViewComponentPeer::NSViewComponentPeer (Component* const component_, | |||
| { | |||
| window = [viewToAttachTo window]; | |||
| [viewToAttachTo addSubview: view]; | |||
| setVisible (component->isVisible()); | |||
| } | |||
| else | |||
| { | |||
| @@ -931,6 +930,10 @@ NSViewComponentPeer::NSViewComponentPeer (Component* const component_, | |||
| [window setIgnoresMouseEvents: (windowStyleFlags & windowIgnoresMouseClicks) != 0]; | |||
| } | |||
| const float alpha = component->getAlpha(); | |||
| if (alpha < 1.0f) | |||
| setAlpha (alpha); | |||
| setTitle (component->getName()); | |||
| } | |||
| @@ -1094,6 +1097,14 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) | |||
| return r; | |||
| } | |||
| void NSViewComponentPeer::setAlpha (float newAlpha) | |||
| { | |||
| if (! isSharedWindow) | |||
| [window setAlphaValue: (CGFloat) newAlpha]; | |||
| else | |||
| [view setAlphaValue: (CGFloat) newAlpha]; | |||
| } | |||
| void NSViewComponentPeer::setMinimised (bool shouldBeMinimised) | |||
| { | |||
| if (! isSharedWindow) | |||
| @@ -231,7 +231,8 @@ public: | |||
| void blitToWindow (HWND hwnd, HDC dc, const bool transparent, | |||
| const int x, const int y, | |||
| const RectangleList& maskedRegion) throw() | |||
| const RectangleList& maskedRegion, | |||
| const uint8 updateLayeredWindowAlpha) throw() | |||
| { | |||
| static HDRAWDIB hdd = 0; | |||
| static bool needToCreateDrawDib = true; | |||
| @@ -289,7 +290,7 @@ public: | |||
| bf.AlphaFormat = AC_SRC_ALPHA; | |||
| bf.BlendFlags = 0; | |||
| bf.BlendOp = AC_SRC_OVER; | |||
| bf.SourceConstantAlpha = 0xff; | |||
| bf.SourceConstantAlpha = updateLayeredWindowAlpha; | |||
| if (! maskedRegion.isEmpty()) | |||
| { | |||
| @@ -410,6 +411,7 @@ public: | |||
| hasCreatedCaret (false), | |||
| currentWindowIcon (0), | |||
| dropTarget (0), | |||
| updateLayeredWindowAlpha (255), | |||
| parentToAddTo (parentToAddTo_) | |||
| { | |||
| callFunctionIfNotLocked (&createWindowCallback, this); | |||
| @@ -484,7 +486,7 @@ public: | |||
| void repaintNowIfTransparent() | |||
| { | |||
| if (isTransparent() && lastPaintTime > 0 && Time::getMillisecondCounter() > lastPaintTime + 30) | |||
| if (isUsingUpdateLayeredWindow() && lastPaintTime > 0 && Time::getMillisecondCounter() > lastPaintTime + 30) | |||
| handlePaintMessage(); | |||
| } | |||
| @@ -571,6 +573,30 @@ public: | |||
| return screenPosition - getScreenPosition(); | |||
| } | |||
| void setAlpha (float newAlpha) | |||
| { | |||
| const uint8 intAlpha = (uint8) jlimit (0, 255, (int) (newAlpha * 255.0f)); | |||
| if (component->isOpaque()) | |||
| { | |||
| if (newAlpha < 1.0f) | |||
| { | |||
| SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); | |||
| SetLayeredWindowAttributes (hwnd, RGB (0, 0, 0), intAlpha, LWA_ALPHA); | |||
| } | |||
| else | |||
| { | |||
| SetWindowLong (hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); | |||
| RedrawWindow (hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| updateLayeredWindowAlpha = intAlpha; | |||
| component->repaint(); | |||
| } | |||
| } | |||
| void setMinimised (bool shouldBeMinimised) | |||
| { | |||
| if (shouldBeMinimised != isMinimised()) | |||
| @@ -878,6 +904,7 @@ private: | |||
| HICON currentWindowIcon; | |||
| ScopedPointer<NOTIFYICONDATA> taskBarIcon; | |||
| IDropTarget* dropTarget; | |||
| uint8 updateLayeredWindowAlpha; | |||
| //============================================================================== | |||
| class TemporaryImage : public Timer | |||
| @@ -1044,6 +1071,10 @@ private: | |||
| // Calling this function here is (for some reason) necessary to make Windows | |||
| // correctly enable the menu items that we specify in the wm_initmenu message. | |||
| GetSystemMenu (hwnd, false); | |||
| const float alpha = component->getAlpha(); | |||
| if (alpha < 1.0f) | |||
| setAlpha (alpha); | |||
| } | |||
| else | |||
| { | |||
| @@ -1083,7 +1114,7 @@ private: | |||
| void offsetWithinParent (int& x, int& y) const | |||
| { | |||
| if (isTransparent()) | |||
| if (isUsingUpdateLayeredWindow()) | |||
| { | |||
| HWND parentHwnd = GetParent (hwnd); | |||
| @@ -1097,9 +1128,9 @@ private: | |||
| } | |||
| } | |||
| bool isTransparent() const | |||
| bool isUsingUpdateLayeredWindow() const | |||
| { | |||
| return (GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0; | |||
| return ! component->isOpaque(); | |||
| } | |||
| inline bool hasTitleBar() const throw() { return (styleFlags & windowHasTitleBar) != 0; } | |||
| @@ -1165,7 +1196,7 @@ private: | |||
| int w = paintStruct.rcPaint.right - x; | |||
| int h = paintStruct.rcPaint.bottom - y; | |||
| const bool transparent = isTransparent(); | |||
| const bool transparent = isUsingUpdateLayeredWindow(); | |||
| if (transparent) | |||
| { | |||
| @@ -1256,7 +1287,7 @@ private: | |||
| if (! dontRepaint) | |||
| static_cast <WindowsBitmapImage*> (offscreenImage.getSharedImage()) | |||
| ->blitToWindow (hwnd, dc, transparent, x, y, maskedRegion); | |||
| ->blitToWindow (hwnd, dc, transparent, x, y, maskedRegion, updateLayeredWindowAlpha); | |||
| } | |||
| DeleteObject (rgn); | |||
| @@ -1878,7 +1909,12 @@ private: | |||
| return 0; | |||
| case WM_WINDOWPOSCHANGED: | |||
| doMouseEvent (getCurrentMousePos()); | |||
| { | |||
| const Point<int> pos (getCurrentMousePos()); | |||
| if (contains (pos, false)) | |||
| doMouseEvent (pos); | |||
| } | |||
| handleMovedOrResized(); | |||
| if (dontRepaint) | |||
| @@ -2222,13 +2258,13 @@ const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | |||
| { | |||
| Win32ComponentPeer::updateKeyModifiers(); | |||
| int keyMods = 0; | |||
| if ((GetKeyState (VK_LBUTTON) & 0x8000) != 0) keyMods |= ModifierKeys::leftButtonModifier; | |||
| if ((GetKeyState (VK_RBUTTON) & 0x8000) != 0) keyMods |= ModifierKeys::rightButtonModifier; | |||
| if ((GetKeyState (VK_MBUTTON) & 0x8000) != 0) keyMods |= ModifierKeys::middleButtonModifier; | |||
| int mouseMods = 0; | |||
| if ((GetKeyState (VK_LBUTTON) & 0x8000) != 0) mouseMods |= ModifierKeys::leftButtonModifier; | |||
| if ((GetKeyState (VK_RBUTTON) & 0x8000) != 0) mouseMods |= ModifierKeys::rightButtonModifier; | |||
| if ((GetKeyState (VK_MBUTTON) & 0x8000) != 0) mouseMods |= ModifierKeys::middleButtonModifier; | |||
| Win32ComponentPeer::currentModifiers | |||
| = Win32ComponentPeer::currentModifiers.withOnlyMouseButtons().withFlags (keyMods); | |||
| = Win32ComponentPeer::currentModifiers.withoutMouseButtons().withFlags (mouseMods); | |||
| return Win32ComponentPeer::currentModifiers; | |||
| } | |||