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.

274 lines
9.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  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 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. #pragma once
  19. #include "../UI/jucer_TestComponent.h"
  20. #include "../Properties/jucer_FilePropertyComponent.h"
  21. #include "../Properties/jucer_ComponentTextProperty.h"
  22. #include "jucer_ComponentUndoableAction.h"
  23. #include "../../Project/UI/jucer_ProjectContentComponent.h"
  24. //==============================================================================
  25. class JucerComponentHandler : public ComponentTypeHandler
  26. {
  27. public:
  28. JucerComponentHandler()
  29. : ComponentTypeHandler ("Projucer Component", "xxx",
  30. typeid (TestComponent), 300, 200)
  31. {}
  32. Component* createNewComponent (JucerDocument* doc) override
  33. {
  34. return new TestComponent (doc, nullptr, false);
  35. }
  36. String getXmlTagName() const noexcept override { return "JUCERCOMP"; }
  37. XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
  38. {
  39. TestComponent* const tc = dynamic_cast<TestComponent*> (comp);
  40. XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
  41. e->setAttribute ("sourceFile", tc->getFilename());
  42. e->setAttribute ("constructorParams", tc->getConstructorParams());
  43. return e;
  44. }
  45. bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
  46. {
  47. auto tc = dynamic_cast<TestComponent*> (comp);
  48. if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
  49. return false;
  50. tc->setFilename (xml.getStringAttribute ("sourceFile", tc->getFilename()));
  51. tc->setConstructorParams (xml.getStringAttribute ("constructorParams"));
  52. return true;
  53. }
  54. String getClassName (Component* comp) const override
  55. {
  56. auto tc = dynamic_cast<TestComponent*> (comp);
  57. String jucerCompClassName;
  58. if (tc->getDocument() != nullptr)
  59. jucerCompClassName = tc->getDocument()->getClassName();
  60. if (jucerCompClassName.isEmpty())
  61. jucerCompClassName = "juce::Component";
  62. return jucerCompClassName;
  63. }
  64. void getEditableProperties (Component* component, JucerDocument& document,
  65. Array<PropertyComponent*>& props, bool multipleSelected) override
  66. {
  67. ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
  68. if (multipleSelected)
  69. return;
  70. if (auto tc = dynamic_cast<TestComponent*> (component))
  71. {
  72. props.add (new JucerCompFileProperty (tc, document));
  73. props.add (new ConstructorParamsProperty (tc, document));
  74. props.add (new JucerCompOpenDocProperty (tc));
  75. }
  76. }
  77. String getCreationParameters (GeneratedCode&, Component* component) override
  78. {
  79. return dynamic_cast<TestComponent*> (component)->getConstructorParams().trim();
  80. }
  81. void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
  82. {
  83. ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
  84. if (auto tc = dynamic_cast<TestComponent*> (component))
  85. code.includeFilesH.add (tc->findFile().withFileExtension (".h"));
  86. else
  87. jassertfalse;
  88. }
  89. //==============================================================================
  90. class JucerCompFileChangeAction : public ComponentUndoableAction <TestComponent>
  91. {
  92. public:
  93. JucerCompFileChangeAction (TestComponent* const comp, ComponentLayout& l, const String& newState_)
  94. : ComponentUndoableAction <TestComponent> (comp, l),
  95. newState (newState_)
  96. {
  97. oldState = comp->getFilename();
  98. }
  99. bool perform()
  100. {
  101. showCorrectTab();
  102. getComponent()->setFilename (newState);
  103. changed();
  104. return true;
  105. }
  106. bool undo()
  107. {
  108. showCorrectTab();
  109. getComponent()->setFilename (oldState);
  110. changed();
  111. return true;
  112. }
  113. String newState, oldState;
  114. };
  115. static void setJucerComponentFile (JucerDocument& document, TestComponent* comp, const String& newFilename)
  116. {
  117. jassert (comp != nullptr);
  118. if (comp != nullptr)
  119. document.perform (new JucerCompFileChangeAction (comp, *document.getComponentLayout(), newFilename),
  120. "Change Projucer component file");
  121. }
  122. private:
  123. //==============================================================================
  124. class JucerCompFileProperty : public FilePropertyComponent,
  125. private ChangeListener
  126. {
  127. public:
  128. JucerCompFileProperty (TestComponent* const comp, JucerDocument& doc)
  129. : FilePropertyComponent ("Jucer file", false, true),
  130. component (comp),
  131. document (doc)
  132. {
  133. document.addChangeListener (this);
  134. }
  135. ~JucerCompFileProperty() override
  136. {
  137. document.removeChangeListener (this);
  138. }
  139. void setFile (const File& newFile) override
  140. {
  141. setJucerComponentFile (document, component,
  142. newFile.getRelativePathFrom (document.getCppFile().getParentDirectory())
  143. .replaceCharacter ('\\', '/'));
  144. }
  145. File getFile() const override
  146. {
  147. return component->findFile();
  148. }
  149. private:
  150. void changeListenerCallback (ChangeBroadcaster*) override
  151. {
  152. refresh();
  153. }
  154. TestComponent* const component;
  155. JucerDocument& document;
  156. };
  157. //==============================================================================
  158. struct JucerCompOpenDocProperty : public ButtonPropertyComponent
  159. {
  160. JucerCompOpenDocProperty (TestComponent* const c)
  161. : ButtonPropertyComponent ("edit", false),
  162. component (c)
  163. {
  164. }
  165. void buttonClicked()
  166. {
  167. if (ProjectContentComponent* const pcc = findParentComponentOfClass<ProjectContentComponent>())
  168. pcc->showEditorForFile (component->findFile(), true);
  169. }
  170. String getButtonText() const
  171. {
  172. return "Open file for editing";
  173. }
  174. TestComponent* const component;
  175. };
  176. //==============================================================================
  177. struct ConstructorParamsProperty : public ComponentTextProperty <TestComponent>
  178. {
  179. ConstructorParamsProperty (TestComponent* comp, JucerDocument& doc)
  180. : ComponentTextProperty <TestComponent> ("constructor params", 512, false, comp, doc)
  181. {
  182. }
  183. void setText (const String& newText) override
  184. {
  185. document.perform (new ConstructorParamChangeAction (component, *document.getComponentLayout(), newText),
  186. "Change Viewport content constructor params");
  187. }
  188. String getText() const override
  189. {
  190. return component->getConstructorParams();
  191. }
  192. private:
  193. struct ConstructorParamChangeAction : public ComponentUndoableAction <TestComponent>
  194. {
  195. ConstructorParamChangeAction (TestComponent* const comp, ComponentLayout& l, const String& newValue_)
  196. : ComponentUndoableAction <TestComponent> (comp, l),
  197. newValue (newValue_)
  198. {
  199. oldValue = comp->getConstructorParams();
  200. }
  201. bool perform()
  202. {
  203. showCorrectTab();
  204. getComponent()->setConstructorParams (newValue);
  205. changed();
  206. layout.getDocument()->refreshAllPropertyComps();
  207. return true;
  208. }
  209. bool undo()
  210. {
  211. showCorrectTab();
  212. getComponent()->setConstructorParams (oldValue);
  213. changed();
  214. layout.getDocument()->refreshAllPropertyComps();
  215. return true;
  216. }
  217. String newValue, oldValue;
  218. };
  219. };
  220. };