The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
9.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-12 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "../JuceDemoHeader.h"
  19. //==============================================================================
  20. /** This will be the source of our balls and can be dragged around. */
  21. class BallGeneratorComponent : public Component
  22. {
  23. public:
  24. BallGeneratorComponent()
  25. {
  26. }
  27. void paint (Graphics& g) override
  28. {
  29. Rectangle<float> area (getLocalBounds().toFloat().reduced (2.0f));
  30. g.setColour (Colours::orange.withAlpha (0.6f));
  31. g.fillRoundedRectangle (area, 10.0f);
  32. g.setColour (Colours::darkgrey);
  33. g.drawRoundedRectangle (area, 10.0f, 2.0f);
  34. AttributedString s;
  35. s.setJustification (Justification::centred);
  36. s.setWordWrap (AttributedString::none);
  37. s.append ("Balls!\n"
  38. "(Drag Me)");
  39. s.setColour (Colours::black);
  40. s.draw (g, area);
  41. }
  42. void resized() override
  43. {
  44. // Just set the limits of our constrainer so that we don't drag ourselves off the screen
  45. constrainer.setMinimumOnscreenAmounts (getHeight(), getWidth(), getHeight(), getWidth());
  46. }
  47. void mouseDown (const MouseEvent& e) override
  48. {
  49. // Prepares our dragger to drag this Component
  50. dragger.startDraggingComponent (this, e);
  51. }
  52. void mouseDrag (const MouseEvent& e) override
  53. {
  54. // Moves this Component according to the mouse drag event and applies our constraints to it
  55. dragger.dragComponent (this, e, &constrainer);
  56. }
  57. private:
  58. ComponentBoundsConstrainer constrainer;
  59. ComponentDragger dragger;
  60. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BallGeneratorComponent)
  61. };
  62. //==============================================================================
  63. struct BallComponent : public Component
  64. {
  65. BallComponent (const Point<float>& pos)
  66. : position (pos),
  67. speed (Random::getSystemRandom().nextFloat() * 4.0f - 2.0f,
  68. Random::getSystemRandom().nextFloat() * -6.0f - 2.0f),
  69. colour (getRandomBrightColour().withAlpha (0.4f))
  70. {
  71. setSize (20, 20);
  72. step();
  73. }
  74. bool step()
  75. {
  76. position += speed;
  77. speed.y += 0.05f;
  78. setCentrePosition ((int) position.x,
  79. (int) position.y);
  80. if (Component* parent = getParentComponent())
  81. return isPositiveAndBelow (position.x, (float) parent->getWidth())
  82. && position.y < (float) parent->getHeight();
  83. return position.y < 400.0f && position.x >= -10.0f;
  84. }
  85. void paint (Graphics& g)
  86. {
  87. g.setColour (colour);
  88. g.fillEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f);
  89. g.setColour (Colours::darkgrey);
  90. g.drawEllipse (2.0f, 2.0f, getWidth() - 4.0f, getHeight() - 4.0f, 1.0f);
  91. }
  92. Point<float> position, speed;
  93. Colour colour;
  94. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BallComponent)
  95. };
  96. //==============================================================================
  97. class AnimationDemo : public Component,
  98. private Button::Listener,
  99. private Timer
  100. {
  101. public:
  102. AnimationDemo()
  103. {
  104. setOpaque (true);
  105. for (int i = 11; --i >= 0;)
  106. {
  107. Button* b = createRandomButton();
  108. componentsToAnimate.add (b);
  109. addAndMakeVisible (b);
  110. b->addListener (this);
  111. }
  112. ballGenerator = new BallGeneratorComponent();
  113. componentsToAnimate.add (ballGenerator);
  114. addAndMakeVisible (ballGenerator);
  115. ballGenerator->setBounds (200, 500, 70, 50);
  116. int w = 160, h = 80;
  117. for (int i = 0; i < componentsToAnimate.size(); ++i)
  118. {
  119. Rectangle<int> r (w * (i % 3), h * (i / 3), w, h);
  120. componentsToAnimate.getUnchecked(i)->setBounds (r.reduced (10));
  121. }
  122. startTimer (1000 / 60);
  123. }
  124. void paint (Graphics& g) override
  125. {
  126. fillBrushedAluminiumBackground (g);
  127. }
  128. private:
  129. OwnedArray<Component> componentsToAnimate;
  130. OwnedArray<BallComponent> balls;
  131. BallGeneratorComponent* ballGenerator;
  132. ComponentAnimator animator;
  133. Button* createRandomButton()
  134. {
  135. DrawablePath normal, over;
  136. Path star1;
  137. star1.addStar (Point<float>(), 5, 20.0f, 50.0f, 0.2f);
  138. normal.setPath (star1);
  139. normal.setFill (Colours::red);
  140. Path star2;
  141. star2.addStar (Point<float>(), 7, 30.0f, 50.0f, 0.0f);
  142. over.setPath (star2);
  143. over.setFill (Colours::pink);
  144. over.setStrokeFill (Colours::black);
  145. over.setStrokeThickness (5.0f);
  146. DrawableImage down;
  147. down.setImage (ImageCache::getFromMemory (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize));
  148. down.setOverlayColour (Colours::black.withAlpha (0.3f));
  149. if (Random::getSystemRandom().nextInt (10) > 2)
  150. {
  151. int type = Random::getSystemRandom().nextInt (3);
  152. DrawableButton* d = new DrawableButton ("Button",
  153. type == 0 ? DrawableButton::ImageOnButtonBackground
  154. : (type == 1 ? DrawableButton::ImageFitted
  155. : DrawableButton::ImageAboveTextLabel));
  156. d->setImages (&normal,
  157. Random::getSystemRandom().nextBool() ? &over : nullptr,
  158. Random::getSystemRandom().nextBool() ? &down : nullptr);
  159. if (Random::getSystemRandom().nextBool())
  160. {
  161. d->setColour (DrawableButton::backgroundColourId, getRandomBrightColour());
  162. d->setColour (DrawableButton::backgroundOnColourId, getRandomBrightColour());
  163. }
  164. d->setClickingTogglesState (Random::getSystemRandom().nextBool());
  165. return d;
  166. }
  167. ImageButton* b = new ImageButton ("ImageButton");
  168. Image image = ImageCache::getFromMemory (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize);
  169. b->setImages (true, true, true,
  170. image, 0.7f, Colours::transparentBlack,
  171. image, 1.0f, getRandomDarkColour().withAlpha (0.2f),
  172. image, 1.0f, getRandomBrightColour().withAlpha (0.8f),
  173. 0.5f);
  174. return b;
  175. }
  176. void buttonClicked (Button*) override
  177. {
  178. for (int i = 0; i < componentsToAnimate.size(); ++i)
  179. componentsToAnimate.swap (i, Random::getSystemRandom().nextInt (componentsToAnimate.size()));
  180. int w = 160, h = 80;
  181. for (int i = 0; i < componentsToAnimate.size(); ++i)
  182. {
  183. Rectangle<int> r (w * (i % 3), h * (i / 3), w, h);
  184. animator.animateComponent (componentsToAnimate.getUnchecked(i),
  185. r.reduced (10),
  186. Random::getSystemRandom().nextBool() ? 1.0f : 0.4f,
  187. 500 + Random::getSystemRandom().nextInt (2000),
  188. false,
  189. Random::getSystemRandom().nextDouble(),
  190. Random::getSystemRandom().nextDouble());
  191. }
  192. }
  193. void timerCallback() override
  194. {
  195. // Go through each of our balls and update their position
  196. for (int i = balls.size(); --i >= 0;)
  197. if (! balls.getUnchecked(i)->step())
  198. balls.remove (i);
  199. // Randomly generate new balls
  200. if (Random::getSystemRandom().nextInt (200) < 4)
  201. {
  202. BallComponent* ball = new BallComponent (ballGenerator->getBounds().getCentre().toFloat());
  203. addAndMakeVisible (ball);
  204. balls.add (ball);
  205. }
  206. }
  207. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimationDemo)
  208. };
  209. // This static object will register this demo type in a global list of demos..
  210. static JuceDemoType<AnimationDemo> demo ("10 Components: Animation");