| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library - "Jules' Utility Class Extensions"
 -    Copyright 2004-12 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 "../JuceDemoHeader.h"
 - 
 - //==============================================================================
 - /** Simple message that holds a Colour. */
 - struct ColourMessage  : public Message
 - {
 -     ColourMessage (Colour col)  : colour (col)
 -     {
 -     }
 - 
 -     /** Returns the colour of a ColourMessage of white if the message is not a ColourMessage. */
 -     static Colour getColour (const Message& message)
 -     {
 -         if (const ColourMessage* cm = dynamic_cast<const ColourMessage*> (&message))
 -             return cm->colour;
 - 
 -         return Colours::white;
 -     }
 - 
 - private:
 -     Colour colour;
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourMessage)
 - };
 - 
 - //==============================================================================
 - /** Simple component that can be triggered to flash.
 -     The flash will then fade using a Timer to repaint itself and will send a change
 -     message once it is finished.
 -  */
 - class FlashingComponent   : public Component,
 -                             public MessageListener,
 -                             public ChangeBroadcaster,
 -                             private Timer
 - {
 - public:
 -     FlashingComponent()
 -         : flashAlpha (0.0f),
 -           colour (Colours::red)
 -     {
 -     }
 - 
 -     void startFlashing()
 -     {
 -         flashAlpha = 1.0f;
 -         startTimer (1000 / 25);
 -     }
 - 
 -     /** Stops this component flashing without sending a change message. */
 -     void stopFlashing()
 -     {
 -         flashAlpha = 0.0f;
 -         stopTimer();
 -         repaint();
 -     }
 - 
 -     /** Sets the colour of the component. */
 -     void setFlashColour (const Colour newColour)
 -     {
 -         colour = newColour;
 -         repaint();
 -     }
 - 
 -     /** Draws our component. */
 -     void paint (Graphics& g) override
 -     {
 -         g.setColour (colour.overlaidWith (Colours::white.withAlpha (flashAlpha)));
 -         g.fillEllipse (getLocalBounds().toFloat());
 -     }
 - 
 -     /** Custom mouse handler to trigger a flash. */
 -     void mouseDown (const MouseEvent&) override
 -     {
 -         startFlashing();
 -     }
 - 
 -     /** Message listener callback used to change our colour */
 -     void handleMessage (const Message& message) override
 -     {
 -         setFlashColour (ColourMessage::getColour (message));
 -     }
 - 
 - private:
 -     float flashAlpha;
 -     Colour colour;
 - 
 -     void timerCallback() override
 -     {
 -         // Reduce the alpha level of the flash slightly so it fades out
 -         flashAlpha -= 0.075f;
 - 
 -         if (flashAlpha < 0.05f)
 -         {
 -             stopFlashing();
 -             sendChangeMessage();
 -             // Once we've finsihed flashing send a change message to trigger the next component to flash
 -         }
 - 
 -         repaint();
 -     }
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlashingComponent)
 - };
 - 
 - //==============================================================================
 - class TimersAndEventsDemo   : public Component,
 -                               private ChangeListener,
 -                               private Button::Listener
 - {
 - public:
 -     TimersAndEventsDemo()
 -     {
 -         setOpaque (true);
 - 
 -         // Create and add our FlashingComponents with some random colours and sizes
 -         for (int i = 0; i < numFlashingComponents; ++i)
 -         {
 -             FlashingComponent* newFlasher = new FlashingComponent();
 -             flashingComponents.add (newFlasher);
 - 
 -             newFlasher->setFlashColour (getRandomBrightColour());
 -             newFlasher->addChangeListener (this);
 - 
 -             const int diameter = 25 + random.nextInt (75);
 -             newFlasher->setSize (diameter, diameter);
 - 
 -             addAndMakeVisible (newFlasher);
 -         }
 - 
 -         addAndMakeVisible (stopButton);
 -         stopButton.addListener (this);
 -         stopButton.setButtonText ("Stop");
 - 
 -         addAndMakeVisible (randomColourButton);
 -         randomColourButton.addListener (this);
 -         randomColourButton.setButtonText ("Set Random Colour");
 - 
 -         // lay out our components in a psudo random grid
 -         Rectangle<int> area (0, 100, 150, 150);
 - 
 -         for (int i = 0; i < flashingComponents.size(); ++i)
 -         {
 -             FlashingComponent* comp = flashingComponents.getUnchecked (i);
 -             Rectangle<int> buttonArea (area.withSize (comp->getWidth(), comp->getHeight()));
 -             buttonArea.translate (random.nextInt (area.getWidth() - comp->getWidth()),
 -                                   random.nextInt (area.getHeight() - comp->getHeight()));
 -             comp->setBounds (buttonArea);
 - 
 -             area.translate (area.getWidth(), 0);
 - 
 -             // if we go off the right start a new row
 -             if (area.getRight() > (800 - area.getWidth()))
 -             {
 -                 area.translate (0, area.getWidth());
 -                 area.setX (0);
 -             }
 -         }
 -     }
 - 
 -     ~TimersAndEventsDemo()
 -     {
 -         stopButton.removeListener (this);
 -         randomColourButton.removeListener (this);
 - 
 -         for (int i = flashingComponents.size(); --i >= 0;)
 -             flashingComponents.getUnchecked (i)->removeChangeListener (this);
 -     }
 - 
 -     void paint (Graphics& g) override
 -     {
 -         g.fillAll (Colours::darkgrey);
 -     }
 - 
 -     void paintOverChildren (Graphics& g) override
 -     {
 -         const Rectangle<int> explanationArea (getLocalBounds().removeFromTop (100));
 - 
 -         AttributedString s;
 -         s.append ("Click on a circle to make it flash. When it has finished flashing it will send a message which causes the next circle to flash");
 -         s.append (newLine);
 -         s.append ("Click the \"Set Random Colour\" button to change the colour of one of the circles.");
 -         s.append (newLine);
 -         s.setFont (Font (16.0f));
 -         s.setColour (Colours::lightgrey);
 -         s.draw (g, explanationArea.reduced (10).toFloat());
 -     }
 - 
 -     void resized() override
 -     {
 -         Rectangle<int> area (getLocalBounds().removeFromBottom (40));
 -         randomColourButton.setBounds (area.removeFromLeft (166).reduced (8));
 -         stopButton.setBounds (area.removeFromRight (166).reduced (8));
 -     }
 - 
 - private:
 -     enum { numFlashingComponents = 9 };
 - 
 -     OwnedArray<FlashingComponent> flashingComponents;
 -     TextButton randomColourButton, stopButton;
 -     Random random;
 - 
 -     void changeListenerCallback (ChangeBroadcaster* source) override
 -     {
 -         for (int i = 0; i < flashingComponents.size(); ++i)
 -             if (source == flashingComponents.getUnchecked (i))
 -                 flashingComponents.getUnchecked ((i + 1) % flashingComponents.size())->startFlashing();
 -     }
 - 
 -     void buttonClicked (Button* button) override
 -     {
 -         if (button == &randomColourButton)
 -         {
 -             // Here we post a new ColourMessage with a random colour to a random flashing component.
 -             // This will send a message to the component asynchronously and trigger its handleMessage callback
 -             flashingComponents.getUnchecked (random.nextInt (flashingComponents.size()))->postMessage (new ColourMessage (getRandomBrightColour()));
 -         }
 -         else if (button == &stopButton)
 -         {
 -             for (int i = 0; i < flashingComponents.size(); ++i)
 -                 flashingComponents.getUnchecked (i)->stopFlashing();
 -         }
 -     }
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimersAndEventsDemo)
 - };
 - 
 - 
 - // This static object will register this demo type in a global list of demos..
 - static JuceDemoType<TimersAndEventsDemo> demo ("40 Timers & Events");
 
 
  |