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.

213 lines
6.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. #pragma once
  20. #include "../Filters/FilterIOConfiguration.h"
  21. class FilterGraph;
  22. //==============================================================================
  23. /**
  24. A desktop window containing a plugin's GUI.
  25. */
  26. class PluginWindow : public DocumentWindow
  27. {
  28. public:
  29. enum class Type
  30. {
  31. normal = 0,
  32. generic,
  33. programs,
  34. audioIO,
  35. numTypes
  36. };
  37. PluginWindow (AudioProcessorGraph::Node* n, Type t, OwnedArray<PluginWindow>& windowList)
  38. : DocumentWindow (n->getProcessor()->getName(),
  39. LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
  40. DocumentWindow::minimiseButton | DocumentWindow::closeButton),
  41. activeWindowList (windowList),
  42. node (n), type (t)
  43. {
  44. setSize (400, 300);
  45. if (auto* ui = createProcessorEditor (*node->getProcessor(), type))
  46. setContentOwned (ui, true);
  47. #if JUCE_IOS || JUCE_ANDROID
  48. auto screenBounds = Desktop::getInstance().getDisplays().getTotalBounds (true).toFloat();
  49. auto scaleFactor = jmin ((screenBounds.getWidth() - 50) / getWidth(), (screenBounds.getHeight() - 50) / getHeight());
  50. if (scaleFactor < 1.0f)
  51. setSize (getWidth() * scaleFactor, getHeight() * scaleFactor);
  52. setTopLeftPosition (20, 20);
  53. #else
  54. setTopLeftPosition (node->properties.getWithDefault (getLastXProp (type), Random::getSystemRandom().nextInt (500)),
  55. node->properties.getWithDefault (getLastYProp (type), Random::getSystemRandom().nextInt (500)));
  56. #endif
  57. node->properties.set (getOpenProp (type), true);
  58. setVisible (true);
  59. }
  60. ~PluginWindow()
  61. {
  62. clearContentComponent();
  63. }
  64. void moved() override
  65. {
  66. node->properties.set (getLastXProp (type), getX());
  67. node->properties.set (getLastYProp (type), getY());
  68. }
  69. void closeButtonPressed() override
  70. {
  71. node->properties.set (getOpenProp (type), false);
  72. activeWindowList.removeObject (this);
  73. }
  74. static String getLastXProp (Type type) { return "uiLastX_" + getTypeName (type); }
  75. static String getLastYProp (Type type) { return "uiLastY_" + getTypeName (type); }
  76. static String getOpenProp (Type type) { return "uiopen_" + getTypeName (type); }
  77. OwnedArray<PluginWindow>& activeWindowList;
  78. const AudioProcessorGraph::Node::Ptr node;
  79. const Type type;
  80. private:
  81. float getDesktopScaleFactor() const override { return 1.0f; }
  82. static AudioProcessorEditor* createProcessorEditor (AudioProcessor& processor, PluginWindow::Type type)
  83. {
  84. if (type == PluginWindow::Type::normal)
  85. {
  86. if (auto* ui = processor.createEditorIfNeeded())
  87. return ui;
  88. type = PluginWindow::Type::generic;
  89. }
  90. if (type == PluginWindow::Type::generic)
  91. return new GenericAudioProcessorEditor (&processor);
  92. if (type == PluginWindow::Type::programs)
  93. return new ProgramAudioProcessorEditor (processor);
  94. if (type == PluginWindow::Type::audioIO)
  95. return new FilterIOConfigurationWindow (processor);
  96. jassertfalse;
  97. return {};
  98. }
  99. static String getTypeName (Type type)
  100. {
  101. switch (type)
  102. {
  103. case Type::normal: return "Normal";
  104. case Type::generic: return "Generic";
  105. case Type::programs: return "Programs";
  106. case Type::audioIO: return "IO";
  107. default: return {};
  108. }
  109. }
  110. //==============================================================================
  111. struct ProgramAudioProcessorEditor : public AudioProcessorEditor
  112. {
  113. ProgramAudioProcessorEditor (AudioProcessor& p) : AudioProcessorEditor (p)
  114. {
  115. setOpaque (true);
  116. addAndMakeVisible (panel);
  117. Array<PropertyComponent*> programs;
  118. auto numPrograms = p.getNumPrograms();
  119. int totalHeight = 0;
  120. for (int i = 0; i < numPrograms; ++i)
  121. {
  122. auto name = p.getProgramName (i).trim();
  123. if (name.isEmpty())
  124. name = "Unnamed";
  125. auto pc = new PropertyComp (name, p);
  126. programs.add (pc);
  127. totalHeight += pc->getPreferredHeight();
  128. }
  129. panel.addProperties (programs);
  130. setSize (400, jlimit (25, 400, totalHeight));
  131. }
  132. void paint (Graphics& g) override
  133. {
  134. g.fillAll (Colours::grey);
  135. }
  136. void resized() override
  137. {
  138. panel.setBounds (getLocalBounds());
  139. }
  140. private:
  141. struct PropertyComp : public PropertyComponent,
  142. private AudioProcessorListener
  143. {
  144. PropertyComp (const String& name, AudioProcessor& p) : PropertyComponent (name), owner (p)
  145. {
  146. owner.addListener (this);
  147. }
  148. ~PropertyComp()
  149. {
  150. owner.removeListener (this);
  151. }
  152. void refresh() override {}
  153. void audioProcessorChanged (AudioProcessor*) override {}
  154. void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}
  155. AudioProcessor& owner;
  156. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyComp)
  157. };
  158. PropertyPanel panel;
  159. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramAudioProcessorEditor)
  160. };
  161. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow)
  162. };