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.

331 lines
11KB

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