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.

427 lines
16KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. class TextEditorHandler : public ComponentTypeHandler
  19. {
  20. public:
  21. TextEditorHandler()
  22. : ComponentTypeHandler ("Text Editor", "TextEditor", typeid (TextEditor), 150, 24)
  23. {
  24. registerColour (TextEditor::textColourId, "text", "textcol");
  25. registerColour (TextEditor::backgroundColourId, "background", "bkgcol");
  26. registerColour (TextEditor::highlightColourId, "highlight", "hilitecol");
  27. registerColour (TextEditor::outlineColourId, "outline", "outlinecol");
  28. registerColour (TextEditor::shadowColourId, "shadow", "shadowcol");
  29. registerColour (CaretComponent::caretColourId, "caret", "caretcol");
  30. }
  31. Component* createNewComponent (JucerDocument*)
  32. {
  33. return new TextEditor ("new text editor");
  34. }
  35. XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout)
  36. {
  37. XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
  38. TextEditor* te = (TextEditor*) comp;
  39. e->setAttribute ("initialText", comp->getProperties() ["initialText"].toString());
  40. e->setAttribute ("multiline", te->isMultiLine());
  41. e->setAttribute ("retKeyStartsLine", te->getReturnKeyStartsNewLine());
  42. e->setAttribute ("readonly", te->isReadOnly());
  43. e->setAttribute ("scrollbars", te->areScrollbarsShown());
  44. e->setAttribute ("caret", te->isCaretVisible());
  45. e->setAttribute ("popupmenu", te->isPopupMenuEnabled());
  46. return e;
  47. }
  48. bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout)
  49. {
  50. if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
  51. return false;
  52. TextEditor* te = (TextEditor*) comp;
  53. TextEditor defaultEditor;
  54. te->setMultiLine (xml.getBoolAttribute ("multiline", defaultEditor.isMultiLine()));
  55. te->setReturnKeyStartsNewLine (xml.getBoolAttribute ("retKeyStartsLine", defaultEditor.getReturnKeyStartsNewLine()));
  56. te->setReadOnly (xml.getBoolAttribute ("readonly", defaultEditor.isReadOnly()));
  57. te->setScrollbarsShown (xml.getBoolAttribute ("scrollbars", defaultEditor.areScrollbarsShown()));
  58. te->setCaretVisible (xml.getBoolAttribute ("caret", defaultEditor.isCaretVisible()));
  59. te->setPopupMenuEnabled (xml.getBoolAttribute ("popupmenu", defaultEditor.isPopupMenuEnabled()));
  60. const String initialText (xml.getStringAttribute ("initialText"));
  61. te->setText (initialText, false);
  62. te->getProperties().set ("initialText", initialText);
  63. return true;
  64. }
  65. void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties)
  66. {
  67. ComponentTypeHandler::getEditableProperties (component, document, properties);
  68. TextEditor* const t = dynamic_cast <TextEditor*> (component);
  69. jassert (t != nullptr);
  70. properties.add (new TextEditorInitialTextProperty (t, document));
  71. properties.add (new TextEditorMultiLineProperty (t, document));
  72. properties.add (new TextEditorReadOnlyProperty (t, document));
  73. properties.add (new TextEditorScrollbarsProperty (t, document));
  74. properties.add (new TextEditorCaretProperty (t, document));
  75. properties.add (new TextEditorPopupMenuProperty (t, document));
  76. addColourProperties (t, document, properties);
  77. }
  78. String getCreationParameters (Component* component)
  79. {
  80. return quotedString (component->getName());
  81. }
  82. void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName)
  83. {
  84. ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
  85. TextEditor* const te = dynamic_cast <TextEditor*> (component);
  86. jassert (te != 0);
  87. String s;
  88. s << memberVariableName << "->setMultiLine (" << CodeHelpers::boolLiteral (te->isMultiLine()) << ");\n"
  89. << memberVariableName << "->setReturnKeyStartsNewLine (" << CodeHelpers::boolLiteral (te->getReturnKeyStartsNewLine()) << ");\n"
  90. << memberVariableName << "->setReadOnly (" << CodeHelpers::boolLiteral (te->isReadOnly()) << ");\n"
  91. << memberVariableName << "->setScrollbarsShown (" << CodeHelpers::boolLiteral (te->areScrollbarsShown()) << ");\n"
  92. << memberVariableName << "->setCaretVisible (" << CodeHelpers::boolLiteral (te->isCaretVisible()) << ");\n"
  93. << memberVariableName << "->setPopupMenuEnabled (" << CodeHelpers::boolLiteral (te->isPopupMenuEnabled()) << ");\n"
  94. << getColourIntialisationCode (component, memberVariableName)
  95. << memberVariableName << "->setText (" << quotedString (te->getProperties() ["initialText"].toString()) << ");\n\n";
  96. code.constructorCode += s;
  97. }
  98. private:
  99. //==============================================================================
  100. class TextEditorMultiLineProperty : public ComponentChoiceProperty <TextEditor>
  101. {
  102. public:
  103. TextEditorMultiLineProperty (TextEditor* comp, JucerDocument& doc)
  104. : ComponentChoiceProperty <TextEditor> ("mode", comp, doc)
  105. {
  106. choices.add ("single line");
  107. choices.add ("multi-line, return key starts new line");
  108. choices.add ("multi-line, return key disabled");
  109. }
  110. void setIndex (int newIndex)
  111. {
  112. document.perform (new TextEditorMultilineChangeAction (component, *document.getComponentLayout(), newIndex),
  113. "Change TextEditor multiline mode");
  114. }
  115. int getIndex() const
  116. {
  117. return component->isMultiLine() ? (component->getReturnKeyStartsNewLine() ? 1 : 2) : 0;
  118. }
  119. private:
  120. class TextEditorMultilineChangeAction : public ComponentUndoableAction <TextEditor>
  121. {
  122. public:
  123. TextEditorMultilineChangeAction (TextEditor* const comp, ComponentLayout& layout, const int newState_)
  124. : ComponentUndoableAction <TextEditor> (comp, layout),
  125. newState (newState_)
  126. {
  127. oldState = comp->isMultiLine() ? (comp->getReturnKeyStartsNewLine() ? 1 : 2) : 0;
  128. }
  129. bool perform()
  130. {
  131. showCorrectTab();
  132. getComponent()->setMultiLine (newState > 0);
  133. getComponent()->setReturnKeyStartsNewLine (newState == 1);
  134. changed();
  135. return true;
  136. }
  137. bool undo()
  138. {
  139. showCorrectTab();
  140. getComponent()->setMultiLine (oldState > 0);
  141. getComponent()->setReturnKeyStartsNewLine (oldState == 1);
  142. changed();
  143. return true;
  144. }
  145. int newState, oldState;
  146. };
  147. };
  148. //==============================================================================
  149. class TextEditorReadOnlyProperty : public ComponentBooleanProperty <TextEditor>
  150. {
  151. public:
  152. TextEditorReadOnlyProperty (TextEditor* comp, JucerDocument& doc)
  153. : ComponentBooleanProperty <TextEditor> ("editable", "Editable", "Editable", comp, doc)
  154. {
  155. }
  156. void setState (bool newState)
  157. {
  158. document.perform (new TextEditorReadonlyChangeAction (component, *document.getComponentLayout(), ! newState),
  159. "Change TextEditor read-only mode");
  160. }
  161. bool getState() const { return ! component->isReadOnly(); }
  162. private:
  163. class TextEditorReadonlyChangeAction : public ComponentUndoableAction <TextEditor>
  164. {
  165. public:
  166. TextEditorReadonlyChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_)
  167. : ComponentUndoableAction <TextEditor> (comp, layout),
  168. newState (newState_)
  169. {
  170. oldState = comp->isReadOnly();
  171. }
  172. bool perform()
  173. {
  174. showCorrectTab();
  175. getComponent()->setReadOnly (newState);
  176. changed();
  177. return true;
  178. }
  179. bool undo()
  180. {
  181. showCorrectTab();
  182. getComponent()->setReadOnly (oldState);
  183. changed();
  184. return true;
  185. }
  186. bool newState, oldState;
  187. };
  188. };
  189. //==============================================================================
  190. class TextEditorScrollbarsProperty : public ComponentBooleanProperty <TextEditor>
  191. {
  192. public:
  193. TextEditorScrollbarsProperty (TextEditor* comp, JucerDocument& doc)
  194. : ComponentBooleanProperty <TextEditor> ("scrollbars", "Scrollbars enabled", "Scrollbars enabled", comp, doc)
  195. {
  196. }
  197. void setState (bool newState)
  198. {
  199. document.perform (new TextEditorScrollbarChangeAction (component, *document.getComponentLayout(), newState),
  200. "Change TextEditor scrollbars");
  201. }
  202. bool getState() const { return component->areScrollbarsShown(); }
  203. private:
  204. class TextEditorScrollbarChangeAction : public ComponentUndoableAction <TextEditor>
  205. {
  206. public:
  207. TextEditorScrollbarChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_)
  208. : ComponentUndoableAction <TextEditor> (comp, layout),
  209. newState (newState_)
  210. {
  211. oldState = comp->areScrollbarsShown();
  212. }
  213. bool perform()
  214. {
  215. showCorrectTab();
  216. getComponent()->setScrollbarsShown (newState);
  217. changed();
  218. return true;
  219. }
  220. bool undo()
  221. {
  222. showCorrectTab();
  223. getComponent()->setScrollbarsShown (oldState);
  224. changed();
  225. return true;
  226. }
  227. bool newState, oldState;
  228. };
  229. };
  230. //==============================================================================
  231. class TextEditorCaretProperty : public ComponentBooleanProperty <TextEditor>
  232. {
  233. public:
  234. TextEditorCaretProperty (TextEditor* comp, JucerDocument& doc)
  235. : ComponentBooleanProperty <TextEditor> ("caret", "Caret visible", "Caret visible", comp, doc)
  236. {
  237. }
  238. void setState (bool newState)
  239. {
  240. document.perform (new TextEditorCaretChangeAction (component, *document.getComponentLayout(), newState),
  241. "Change TextEditor caret");
  242. }
  243. bool getState() const { return component->isCaretVisible(); }
  244. private:
  245. class TextEditorCaretChangeAction : public ComponentUndoableAction <TextEditor>
  246. {
  247. public:
  248. TextEditorCaretChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_)
  249. : ComponentUndoableAction <TextEditor> (comp, layout),
  250. newState (newState_)
  251. {
  252. oldState = comp->isCaretVisible();
  253. }
  254. bool perform()
  255. {
  256. showCorrectTab();
  257. getComponent()->setCaretVisible (newState);
  258. changed();
  259. return true;
  260. }
  261. bool undo()
  262. {
  263. showCorrectTab();
  264. getComponent()->setCaretVisible (oldState);
  265. changed();
  266. return true;
  267. }
  268. bool newState, oldState;
  269. };
  270. };
  271. //==============================================================================
  272. class TextEditorPopupMenuProperty : public ComponentBooleanProperty <TextEditor>
  273. {
  274. public:
  275. TextEditorPopupMenuProperty (TextEditor* comp, JucerDocument& doc)
  276. : ComponentBooleanProperty <TextEditor> ("popup menu", "Popup menu enabled", "Popup menu enabled", comp, doc)
  277. {
  278. }
  279. void setState (bool newState)
  280. {
  281. document.perform (new TextEditorPopupMenuChangeAction (component, *document.getComponentLayout(), newState),
  282. "Change TextEditor popup menu");
  283. }
  284. bool getState() const { return component->isPopupMenuEnabled(); }
  285. private:
  286. class TextEditorPopupMenuChangeAction : public ComponentUndoableAction <TextEditor>
  287. {
  288. public:
  289. TextEditorPopupMenuChangeAction (TextEditor* const comp, ComponentLayout& layout, const bool newState_)
  290. : ComponentUndoableAction <TextEditor> (comp, layout),
  291. newState (newState_)
  292. {
  293. oldState = comp->isPopupMenuEnabled();
  294. }
  295. bool perform()
  296. {
  297. showCorrectTab();
  298. getComponent()->setPopupMenuEnabled (newState);
  299. changed();
  300. return true;
  301. }
  302. bool undo()
  303. {
  304. showCorrectTab();
  305. getComponent()->setPopupMenuEnabled (oldState);
  306. changed();
  307. return true;
  308. }
  309. bool newState, oldState;
  310. };
  311. };
  312. //==============================================================================
  313. class TextEditorInitialTextProperty : public ComponentTextProperty <TextEditor>
  314. {
  315. public:
  316. TextEditorInitialTextProperty (TextEditor* comp, JucerDocument& doc)
  317. : ComponentTextProperty <TextEditor> ("initial text", 10000, true, comp, doc)
  318. {}
  319. void setText (const String& newText)
  320. {
  321. document.perform (new TextEditorInitialTextChangeAction (component, *document.getComponentLayout(), newText),
  322. "Change TextEditor initial text");
  323. }
  324. String getText() const
  325. {
  326. return component->getProperties() ["initialText"];
  327. }
  328. private:
  329. class TextEditorInitialTextChangeAction : public ComponentUndoableAction <TextEditor>
  330. {
  331. public:
  332. TextEditorInitialTextChangeAction (TextEditor* const comp, ComponentLayout& layout, const String& newState_)
  333. : ComponentUndoableAction <TextEditor> (comp, layout),
  334. newState (newState_)
  335. {
  336. oldState = comp->getProperties() ["initialText"];
  337. }
  338. bool perform()
  339. {
  340. showCorrectTab();
  341. getComponent()->setText (newState, false);
  342. getComponent()->getProperties().set ("initialText", newState);
  343. changed();
  344. return true;
  345. }
  346. bool undo()
  347. {
  348. showCorrectTab();
  349. getComponent()->setText (oldState, false);
  350. getComponent()->getProperties().set ("initialText", oldState);
  351. changed();
  352. return true;
  353. }
  354. String newState, oldState;
  355. };
  356. };
  357. };