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.

202 lines
6.2KB

  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 "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. setTopLeftPosition (node->properties.getWithDefault (getLastXProp (type), Random::getSystemRandom().nextInt (500)),
  48. node->properties.getWithDefault (getLastYProp (type), Random::getSystemRandom().nextInt (500)));
  49. node->properties.set (getOpenProp (type), true);
  50. setVisible (true);
  51. }
  52. ~PluginWindow()
  53. {
  54. clearContentComponent();
  55. }
  56. void moved() override
  57. {
  58. node->properties.set (getLastXProp (type), getX());
  59. node->properties.set (getLastYProp (type), getY());
  60. }
  61. void closeButtonPressed() override
  62. {
  63. node->properties.set (getOpenProp (type), false);
  64. activeWindowList.removeObject (this);
  65. }
  66. static String getLastXProp (Type type) { return "uiLastX_" + getTypeName (type); }
  67. static String getLastYProp (Type type) { return "uiLastY_" + getTypeName (type); }
  68. static String getOpenProp (Type type) { return "uiopen_" + getTypeName (type); }
  69. OwnedArray<PluginWindow>& activeWindowList;
  70. const AudioProcessorGraph::Node::Ptr node;
  71. const Type type;
  72. private:
  73. float getDesktopScaleFactor() const override { return 1.0f; }
  74. static AudioProcessorEditor* createProcessorEditor (AudioProcessor& processor, PluginWindow::Type type)
  75. {
  76. if (type == PluginWindow::Type::normal)
  77. {
  78. if (auto* ui = processor.createEditorIfNeeded())
  79. return ui;
  80. type = PluginWindow::Type::generic;
  81. }
  82. if (type == PluginWindow::Type::generic)
  83. return new GenericAudioProcessorEditor (&processor);
  84. if (type == PluginWindow::Type::programs)
  85. return new ProgramAudioProcessorEditor (processor);
  86. if (type == PluginWindow::Type::audioIO)
  87. return new FilterIOConfigurationWindow (processor);
  88. jassertfalse;
  89. return {};
  90. }
  91. static String getTypeName (Type type)
  92. {
  93. switch (type)
  94. {
  95. case Type::normal: return "Normal";
  96. case Type::generic: return "Generic";
  97. case Type::programs: return "Programs";
  98. case Type::audioIO: return "IO";
  99. default: return {};
  100. }
  101. }
  102. //==============================================================================
  103. struct ProgramAudioProcessorEditor : public AudioProcessorEditor
  104. {
  105. ProgramAudioProcessorEditor (AudioProcessor& p) : AudioProcessorEditor (p)
  106. {
  107. setOpaque (true);
  108. addAndMakeVisible (panel);
  109. Array<PropertyComponent*> programs;
  110. auto numPrograms = p.getNumPrograms();
  111. int totalHeight = 0;
  112. for (int i = 0; i < numPrograms; ++i)
  113. {
  114. auto name = p.getProgramName (i).trim();
  115. if (name.isEmpty())
  116. name = "Unnamed";
  117. auto pc = new PropertyComp (name, p);
  118. programs.add (pc);
  119. totalHeight += pc->getPreferredHeight();
  120. }
  121. panel.addProperties (programs);
  122. setSize (400, jlimit (25, 400, totalHeight));
  123. }
  124. void paint (Graphics& g) override
  125. {
  126. g.fillAll (Colours::grey);
  127. }
  128. void resized() override
  129. {
  130. panel.setBounds (getLocalBounds());
  131. }
  132. private:
  133. struct PropertyComp : public PropertyComponent,
  134. private AudioProcessorListener
  135. {
  136. PropertyComp (const String& name, AudioProcessor& p) : PropertyComponent (name), owner (p)
  137. {
  138. owner.addListener (this);
  139. }
  140. ~PropertyComp()
  141. {
  142. owner.removeListener (this);
  143. }
  144. void refresh() override {}
  145. void audioProcessorChanged (AudioProcessor*) override {}
  146. void audioProcessorParameterChanged (AudioProcessor*, int, float) override {}
  147. AudioProcessor& owner;
  148. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyComp)
  149. };
  150. PropertyPanel panel;
  151. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramAudioProcessorEditor)
  152. };
  153. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginWindow)
  154. };