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.

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