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.

447 lines
18KB

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