/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2013 - Raw Material Software Ltd. Permission is granted to use this software under the terms of either: a) the GPL v2 (or any later version) b) the Affero GPL v3 Details of these licenses can be found at: www.gnu.org/licenses JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are available: visit www.juce.com for more information. ============================================================================== */ #ifndef __JUCER_JUCERCOMPONENTHANDLER_JUCEHEADER__ #define __JUCER_JUCERCOMPONENTHANDLER_JUCEHEADER__ #include "../ui/jucer_TestComponent.h" #include "../properties/jucer_FilePropertyComponent.h" #include "../properties/jucer_ComponentTextProperty.h" #include "jucer_ComponentUndoableAction.h" #include "../../Project/jucer_ProjectContentComponent.h" //============================================================================== class JucerComponentHandler : public ComponentTypeHandler { public: JucerComponentHandler() : ComponentTypeHandler ("Jucer Component", "xxx", typeid (TestComponent), 300, 200) {} Component* createNewComponent (JucerDocument* doc) { return new TestComponent (doc, 0, false); } String getXmlTagName() const noexcept { return "JUCERCOMP"; } XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) { TestComponent* const tc = dynamic_cast (comp); XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); e->setAttribute ("sourceFile", tc->getFilename()); e->setAttribute ("constructorParams", tc->getConstructorParams()); return e; } bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) { TestComponent* const tc = dynamic_cast (comp); if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) return false; tc->setFilename (xml.getStringAttribute ("sourceFile", tc->getFilename())); tc->setConstructorParams (xml.getStringAttribute ("constructorParams")); return true; } String getClassName (Component* comp) const { TestComponent* const tc = dynamic_cast (comp); String jucerCompClassName; if (tc->getDocument() != 0) jucerCompClassName = tc->getDocument()->getClassName(); if (jucerCompClassName.isEmpty()) jucerCompClassName = "Component"; return jucerCompClassName; } void getEditableProperties (Component* component, JucerDocument& document, Array & properties) { TestComponent* const tc = dynamic_cast (component); ComponentTypeHandler::getEditableProperties (component, document, properties); properties.add (new JucerCompFileProperty (tc, document)); properties.add (new ConstructorParamsProperty (tc, document)); properties.add (new JucerCompOpenDocProperty (tc)); } String getCreationParameters (Component* component) { TestComponent* const tc = dynamic_cast (component); return tc->getConstructorParams().trim(); } void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) { ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); TestComponent* const tc = dynamic_cast (component); code.includeFilesH.add (tc->getFilename().replace (".cpp", ".h")); } //============================================================================== class JucerCompFileChangeAction : public ComponentUndoableAction { public: JucerCompFileChangeAction (TestComponent* const comp, ComponentLayout& layout, const String& newState_) : ComponentUndoableAction (comp, layout), newState (newState_) { oldState = comp->getFilename(); } bool perform() { showCorrectTab(); getComponent()->setFilename (newState); changed(); return true; } bool undo() { showCorrectTab(); getComponent()->setFilename (oldState); changed(); return true; } String newState, oldState; }; static void setJucerComponentFile (JucerDocument& document, TestComponent* comp, const String& newFilename) { jassert (comp != 0); if (comp != 0) document.perform (new JucerCompFileChangeAction (comp, *document.getComponentLayout(), newFilename), "Change Jucer component file"); } private: //============================================================================== class JucerCompFileProperty : public FilePropertyComponent, public ChangeListener { public: JucerCompFileProperty (TestComponent* const comp, JucerDocument& doc) : FilePropertyComponent ("Jucer file", false, true), component (comp), document (doc) { document.addChangeListener (this); } ~JucerCompFileProperty() { document.removeChangeListener (this); } void setFile (const File& newFile) { setJucerComponentFile (document, component, newFile.getRelativePathFrom (document.getCppFile().getParentDirectory()) .replaceCharacter ('\\', '/')); } File getFile() const { return component->findFile(); } void changeListenerCallback (ChangeBroadcaster*) { refresh(); } private: TestComponent* const component; JucerDocument& document; }; //============================================================================== class JucerCompOpenDocProperty : public ButtonPropertyComponent { public: JucerCompOpenDocProperty (TestComponent* const c) : ButtonPropertyComponent ("edit", false), component (c) { } void buttonClicked() { if (ProjectContentComponent* const pcc = findParentComponentOfClass()) pcc->showEditorForFile (component->findFile(), true); } String getButtonText() const { return "Open file for editing"; } private: TestComponent* const component; }; //============================================================================== class ConstructorParamsProperty : public ComponentTextProperty { public: ConstructorParamsProperty (TestComponent* comp, JucerDocument& document) : ComponentTextProperty ("constructor params", 512, false, comp, document) { } void setText (const String& newText) { document.perform (new ConstructorParamChangeAction (component, *document.getComponentLayout(), newText), "Change Viewport content constructor params"); } String getText() const { return component->getConstructorParams(); } private: class ConstructorParamChangeAction : public ComponentUndoableAction { public: ConstructorParamChangeAction (TestComponent* const comp, ComponentLayout& layout, const String& newValue_) : ComponentUndoableAction (comp, layout), newValue (newValue_) { oldValue = comp->getConstructorParams(); } bool perform() { showCorrectTab(); getComponent()->setConstructorParams (newValue); changed(); layout.getDocument()->refreshAllPropertyComps(); return true; } bool undo() { showCorrectTab(); getComponent()->setConstructorParams (oldValue); changed(); layout.getDocument()->refreshAllPropertyComps(); return true; } String newValue, oldValue; }; }; }; #endif // __JUCER_JUCERCOMPONENTHANDLER_JUCEHEADER__