| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 -    Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 -    27th April 2017).
 - 
 -    End User License Agreement: www.juce.com/juce-5-licence
 -    Privacy Policy: www.juce.com/juce-5-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - #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;
 -         startTimerHz (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 (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground,
 -                                            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 (getUIColourIfAvailable(LookAndFeel_V4::ColourScheme::UIColour::defaultText,
 -                                             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");
 
 
  |