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.

332 lines
11KB

  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. /** Just a simple window that deletes itself when closed. */
  21. class BasicWindow : public DocumentWindow
  22. {
  23. public:
  24. BasicWindow (const String& name, Colour backgroundColour, int buttonsNeeded)
  25. : DocumentWindow (name, backgroundColour, buttonsNeeded)
  26. {
  27. }
  28. void closeButtonPressed()
  29. {
  30. delete this;
  31. }
  32. private:
  33. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BasicWindow)
  34. };
  35. //==============================================================================
  36. /** This window contains a ColourSelector which can be used to change the window's colour. */
  37. class ColourSelectorWindow : public DocumentWindow,
  38. private ChangeListener
  39. {
  40. public:
  41. ColourSelectorWindow (const String& name, Colour backgroundColour, int buttonsNeeded)
  42. : DocumentWindow (name, backgroundColour, buttonsNeeded),
  43. selector (ColourSelector::showColourAtTop | ColourSelector::showSliders | ColourSelector::showColourspace)
  44. {
  45. selector.setCurrentColour (backgroundColour);
  46. selector.setColour (ColourSelector::backgroundColourId, Colours::transparentWhite);
  47. selector.addChangeListener (this);
  48. setContentOwned (&selector, false);
  49. }
  50. ~ColourSelectorWindow()
  51. {
  52. selector.removeChangeListener (this);
  53. }
  54. void closeButtonPressed()
  55. {
  56. delete this;
  57. }
  58. private:
  59. ColourSelector selector;
  60. void changeListenerCallback (ChangeBroadcaster* source)
  61. {
  62. if (source == &selector)
  63. setBackgroundColour (selector.getCurrentColour());
  64. }
  65. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourSelectorWindow)
  66. };
  67. //==============================================================================
  68. class BouncingBallComponent : public Component,
  69. public Timer
  70. {
  71. public:
  72. BouncingBallComponent()
  73. {
  74. setInterceptsMouseClicks (false, false);
  75. Random random;
  76. const float size = 10.0f + random.nextInt (30);
  77. ballBounds.setBounds (random.nextFloat() * 100.0f,
  78. random.nextFloat() * 100.0f,
  79. size, size);
  80. direction.x = random.nextFloat() * 8.0f - 4.0f;
  81. direction.y = random.nextFloat() * 8.0f - 4.0f;
  82. colour = Colour ((juce::uint32) random.nextInt())
  83. .withAlpha (0.5f)
  84. .withBrightness (0.7f);
  85. startTimer (60);
  86. }
  87. void paint (Graphics& g)
  88. {
  89. g.setColour (colour);
  90. g.fillEllipse (ballBounds - getPosition().toFloat());
  91. }
  92. void timerCallback()
  93. {
  94. ballBounds += direction;
  95. if (ballBounds.getX() < 0) direction.x = std::abs (direction.x);
  96. if (ballBounds.getY() < 0) direction.y = std::abs (direction.y);
  97. if (ballBounds.getRight() > getParentWidth()) direction.x = -std::abs (direction.x);
  98. if (ballBounds.getBottom() > getParentHeight()) direction.y = -std::abs (direction.y);
  99. setBounds (ballBounds.getSmallestIntegerContainer());
  100. }
  101. private:
  102. Colour colour;
  103. Rectangle<float> ballBounds;
  104. Point<float> direction;
  105. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BouncingBallComponent)
  106. };
  107. //==============================================================================
  108. class BouncingBallsContainer : public Component
  109. {
  110. public:
  111. BouncingBallsContainer (int numBalls)
  112. {
  113. for (int i = 0; i < numBalls; ++i)
  114. {
  115. BouncingBallComponent* newBall = new BouncingBallComponent();
  116. balls.add (newBall);
  117. addAndMakeVisible (newBall);
  118. }
  119. }
  120. void mouseDown (const MouseEvent& e)
  121. {
  122. dragger.startDraggingComponent (this, e);
  123. }
  124. void mouseDrag (const MouseEvent& e)
  125. {
  126. // as there's no titlebar we have to manage the dragging ourselves
  127. dragger.dragComponent (this, e, 0);
  128. }
  129. void paint (Graphics& g)
  130. {
  131. if (isOpaque())
  132. g.fillAll (Colours::white);
  133. else
  134. g.fillAll (Colours::blue.withAlpha (0.2f));
  135. g.setFont (16.0f);
  136. g.setColour (Colours::black);
  137. g.drawFittedText ("This window has no titlebar and a transparent background.",
  138. getLocalBounds().reduced (8, 0),
  139. Justification::centred, 5);
  140. g.drawRect (getLocalBounds());
  141. }
  142. private:
  143. ComponentDragger dragger;
  144. OwnedArray<BouncingBallComponent> balls;
  145. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BouncingBallsContainer)
  146. };
  147. //==============================================================================
  148. class WindowsDemo : public Component,
  149. private Button::Listener
  150. {
  151. public:
  152. enum Windows
  153. {
  154. dialog,
  155. document,
  156. alert,
  157. numWindows
  158. };
  159. WindowsDemo()
  160. {
  161. setOpaque (true);
  162. showWindowsButton.setButtonText ("Show Windows");
  163. addAndMakeVisible (showWindowsButton);
  164. showWindowsButton.addListener (this);
  165. closeWindowsButton.setButtonText ("Close Windows");
  166. addAndMakeVisible (closeWindowsButton);
  167. closeWindowsButton.addListener (this);
  168. }
  169. ~WindowsDemo()
  170. {
  171. closeAllWindows();
  172. closeWindowsButton.removeListener (this);
  173. showWindowsButton.removeListener (this);
  174. }
  175. void paint (Graphics& g) override
  176. {
  177. g.fillAll (Colours::grey);
  178. }
  179. void resized() override
  180. {
  181. const Rectangle<int> buttonSize (0, 0, 108, 28);
  182. Rectangle<int> area ((getWidth() / 2) - (buttonSize.getWidth() / 2),
  183. (getHeight() / 2) - buttonSize.getHeight(),
  184. buttonSize.getWidth(), buttonSize.getHeight());
  185. showWindowsButton.setBounds (area.reduced (2));
  186. closeWindowsButton.setBounds (area.translated (0, buttonSize.getHeight()).reduced (2));
  187. }
  188. private:
  189. // Because in this demo the windows delete themselves, we'll use the
  190. // Component::SafePointer class to point to them, which automatically becomes
  191. // null when the component that it points to is deleted.
  192. Array< Component::SafePointer<Component> > windows;
  193. TextButton showWindowsButton, closeWindowsButton;
  194. void showAllWindows()
  195. {
  196. closeAllWindows();
  197. showDocumentWindow (false);
  198. showDocumentWindow (true);
  199. showTransparentWindow();
  200. showDialogWindow();
  201. }
  202. void closeAllWindows()
  203. {
  204. for (int i = 0; i < windows.size(); ++i)
  205. windows.getReference(i).deleteAndZero();
  206. windows.clear();
  207. }
  208. void showDialogWindow()
  209. {
  210. String m;
  211. m << "Dialog Windows can be used to quickly show a component, usually blocking mouse input to other windows." << newLine
  212. << newLine
  213. << "They can also be quickly closed with the escape key, try it now.";
  214. DialogWindow::LaunchOptions options;
  215. Label* label = new Label();
  216. label->setText (m, dontSendNotification);
  217. label->setColour (Label::textColourId, Colours::whitesmoke);
  218. options.content.setOwned (label);
  219. Rectangle<int> area (0, 0, 300, 200);
  220. options.content->setSize (area.getWidth(), area.getHeight());
  221. options.dialogTitle = "Dialog Window";
  222. options.dialogBackgroundColour = Colour (0xff0e345a);
  223. options.escapeKeyTriggersCloseButton = true;
  224. options.useNativeTitleBar = false;
  225. options.resizable = true;
  226. const RectanglePlacement placement (RectanglePlacement::xRight + RectanglePlacement::yBottom + RectanglePlacement::doNotResize);
  227. DialogWindow* dw = options.launchAsync();
  228. dw->centreWithSize (300, 200);
  229. }
  230. void showDocumentWindow (bool native)
  231. {
  232. DocumentWindow* dw = new ColourSelectorWindow ("Document Window", getRandomBrightColour(), DocumentWindow::allButtons);
  233. windows.add (dw);
  234. Rectangle<int> area (0, 0, 300, 400);
  235. const RectanglePlacement placement ((native ? RectanglePlacement::xLeft : RectanglePlacement::xRight)
  236. + RectanglePlacement::yTop + RectanglePlacement::doNotResize);
  237. Rectangle<int> result (placement.appliedTo (area, Desktop::getInstance().getDisplays().getMainDisplay().userArea.reduced (20)));
  238. dw->setBounds (result);
  239. dw->setResizable (true, ! native);
  240. dw->setUsingNativeTitleBar (native);
  241. dw->setVisible (true);
  242. }
  243. void showTransparentWindow()
  244. {
  245. BouncingBallsContainer* balls = new BouncingBallsContainer (3);
  246. balls->addToDesktop (ComponentPeer::windowIsTemporary);
  247. windows.add (balls);
  248. Rectangle<int> area (0, 0, 200, 200);
  249. const RectanglePlacement placement (RectanglePlacement::xLeft + RectanglePlacement::yBottom + RectanglePlacement::doNotResize);
  250. Rectangle<int> result (placement.appliedTo (area, Desktop::getInstance().getDisplays().getMainDisplay().userArea.reduced (20)));
  251. balls->setBounds (result);
  252. balls->setVisible (true);
  253. }
  254. void buttonClicked (Button* button) override
  255. {
  256. if (button == &showWindowsButton)
  257. showAllWindows();
  258. else if (button == &closeWindowsButton)
  259. closeAllWindows();
  260. }
  261. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsDemo);
  262. };
  263. // This static object will register this demo type in a global list of demos..
  264. static JuceDemoType<WindowsDemo> demo ("10 Components: Windows");