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.

250 lines
7.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #include "Main.h"
  20. #include "MainComponent.h"
  21. //==============================================================================
  22. AudioPlayerHeader::AudioPlayerHeader()
  23. : thumbnailComp (DSPSamplesApplication::getApp().getDeviceManager(),
  24. DSPSamplesApplication::getApp().getFormatManager())
  25. {
  26. setOpaque (true);
  27. addAndMakeVisible (loadButton);
  28. addAndMakeVisible (playButton);
  29. addAndMakeVisible (loopButton);
  30. loadButton.addListener (this);
  31. playButton.addListener (this);
  32. addAndMakeVisible (thumbnailComp);
  33. thumbnailComp.addChangeListener (this);
  34. DSPSamplesApplication::getApp().getPlayState().addListener (this);
  35. loopButton.getToggleStateValue().referTo (DSPSamplesApplication::getApp().getLoopState());
  36. }
  37. AudioPlayerHeader::~AudioPlayerHeader()
  38. {
  39. playButton.removeListener (this);
  40. loadButton.removeListener (this);
  41. loopButton.removeListener (this);
  42. DSPSamplesApplication::getApp().getPlayState().removeListener (this);
  43. }
  44. void AudioPlayerHeader::paint (Graphics& g)
  45. {
  46. g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId).darker());
  47. g.fillRect (getLocalBounds());
  48. }
  49. void AudioPlayerHeader::resized()
  50. {
  51. auto bounds = getLocalBounds();
  52. auto buttonBounds = bounds.removeFromLeft (jmin (250, bounds.getWidth() / 4));
  53. auto top = buttonBounds.removeFromTop (40);
  54. loadButton.setBounds (top.removeFromLeft (buttonBounds.getWidth() / 2).reduced (10, 10));
  55. playButton.setBounds (top.reduced (10, 10));
  56. loopButton.setSize (0, 25);
  57. loopButton.changeWidthToFitText();
  58. loopButton.setCentrePosition (buttonBounds.getCentre());
  59. thumbnailComp.setBounds (bounds);
  60. }
  61. void AudioPlayerHeader::buttonClicked (Button* button)
  62. {
  63. auto& app = DSPSamplesApplication::getApp();
  64. if (button == &loadButton)
  65. {
  66. app.stop();
  67. FileChooser fc ("Select an audio file...", File(), "*.wav;*.mp3;*.aif;");
  68. if (fc.browseForFileToOpen())
  69. {
  70. auto f = fc.getResult();
  71. if (! app.loadFile (f))
  72. NativeMessageBox::showOkCancelBox (AlertWindow::WarningIcon, "Error loading file", "Unable to load audio file", nullptr, nullptr);
  73. else
  74. thumbnailComp.setCurrentFile (f);
  75. }
  76. }
  77. else if (button == &playButton)
  78. {
  79. app.togglePlay();
  80. }
  81. }
  82. void AudioPlayerHeader::changeListenerCallback (ChangeBroadcaster*)
  83. {
  84. auto& app = DSPSamplesApplication::getApp();
  85. if (app.getPlayState().getValue())
  86. app.stop();
  87. app.loadFile (thumbnailComp.getCurrentFile());
  88. }
  89. void AudioPlayerHeader::valueChanged (Value& v)
  90. {
  91. playButton.setButtonText (v.getValue() ? "Stop" : "Play");
  92. }
  93. //==============================================================================
  94. MainContentComponent::MainContentComponent()
  95. {
  96. setSize (1000, 800);
  97. setOpaque (true);
  98. codeEditor.setEnabled (false);
  99. auto currentDemoIndex = DSPSamplesApplication::getApp().getCurrentDemoIndex();
  100. demoList.setModel (this);
  101. demoList.updateContent();
  102. demoList.selectRow (currentDemoIndex);
  103. addAndMakeVisible (header);
  104. addAndMakeVisible (demoList);
  105. addAndMakeVisible (codeEditor);
  106. setupDemoColours();
  107. }
  108. void MainContentComponent::paint (Graphics& g)
  109. {
  110. g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
  111. g.fillRect (getLocalBounds());
  112. }
  113. void MainContentComponent::resized()
  114. {
  115. auto r = getLocalBounds();
  116. auto listWidth = jmin (250, r.getWidth() / 4);
  117. header.setBounds (r.removeFromTop (80));
  118. demoList.setBounds (r.removeFromLeft (listWidth));
  119. r.removeFromTop (5);
  120. if (parametersComponent != nullptr)
  121. parametersComponent->setBounds (r.removeFromTop (parametersComponent->getHeightNeeded()).reduced (20, 0));
  122. r.removeFromBottom (10);
  123. codeEditor.setBounds (r);
  124. }
  125. void MainContentComponent::paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
  126. {
  127. Rectangle<int> r { 0, 0, width, height };
  128. auto& lf = getLookAndFeel();
  129. g.setColour (lf.findColour (rowIsSelected ? static_cast<int> (TextEditor::highlightColourId) : static_cast<int> (ListBox::backgroundColourId)));
  130. g.fillRect (r);
  131. if (auto demo = Demo::getList()[rowNumber])
  132. {
  133. g.setColour (lf.findColour (rowIsSelected ? static_cast<int> (TextEditor::highlightedTextColourId) : static_cast<int> (ListBox::textColourId)));
  134. g.drawFittedText (demo->name, r.reduced (10, 2), Justification::centredLeft, 1);
  135. }
  136. }
  137. int MainContentComponent::getNumRows()
  138. {
  139. return Demo::getList().size();
  140. }
  141. void MainContentComponent::selectedRowsChanged (int lastRowSelected)
  142. {
  143. if (lastRowSelected >= 0)
  144. {
  145. DSPSamplesApplication::getApp().setCurrentDemo (lastRowSelected);
  146. if (auto demo = Demo::getList()[DSPSamplesApplication::getApp().getCurrentDemoIndex()])
  147. {
  148. if (demo->code.isNotEmpty())
  149. codeDocument.replaceAllContent (demo->code);
  150. codeEditor.scrollToLine (0);
  151. initParameters();
  152. }
  153. }
  154. }
  155. void MainContentComponent::setupDemoColours()
  156. {
  157. auto& lf = getLookAndFeel();
  158. lf.setColour (CodeEditorComponent::backgroundColourId, Colour (0xff263238));
  159. lf.setColour (CodeEditorComponent::lineNumberTextId, Colour (0xffaaaaaa));
  160. lf.setColour (CodeEditorComponent::lineNumberBackgroundId, Colour (0xff323e44));
  161. lf.setColour (CodeEditorComponent::highlightColourId, Colour (0xffe0ec65).withAlpha (0.5f));
  162. lf.setColour (ScrollBar::ColourIds::thumbColourId, Colour (0xffd0d8e0));
  163. lf.setColour (TextEditor::highlightColourId, Colour (0xffe0ec65).withAlpha (0.75f));
  164. lf.setColour (TextEditor::highlightedTextColourId, Colours::black);
  165. ScopedPointer<XmlElement> xml (XmlDocument::parse (BinaryData::EditorColourScheme_xml));
  166. if (xml != nullptr)
  167. {
  168. auto colourSchemeTree = ValueTree::fromXml (*xml);
  169. auto& scheme = codeEditor.getColourScheme();
  170. for (auto& type : scheme.types)
  171. {
  172. auto colour = colourSchemeTree.getChildWithProperty ("name", type.name);
  173. if (colour.isValid())
  174. type.colour = Colour::fromString (colour ["colour"].toString());
  175. }
  176. }
  177. codeEditor.setScrollbarThickness (6);
  178. }
  179. void MainContentComponent::initParameters()
  180. {
  181. auto& parameters = DSPSamplesApplication::getApp().getCurrentDemoParameters();
  182. if (parametersComponent != nullptr)
  183. parametersComponent = nullptr;
  184. if (parameters.size() > 0)
  185. addAndMakeVisible (parametersComponent = new DemoParametersComponent (parameters));
  186. resized();
  187. }