diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp index 220b8c1354..804b52248c 100644 --- a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp +++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp @@ -659,9 +659,15 @@ static const unsigned char temp_73015554[] = "//[MiscUserDefs] You can add your own user definitions and misc code here...\r\n" "//[/MiscUserDefs]\r\n" "\r\n" +"extern const unsigned char %%className%%_ComponentStateData[];\r\n" +"\r\n" "//==============================================================================\r\n" "%%className%%::%%className%% (%%constructorParams%%)\r\n" "%%initialisers%%{\r\n" +" componentState = ValueTree::readFromData (%%className%%_ComponentStateData, %%statedatasize%%);\r\n" +" jassert (componentState.isValid());\r\n" +" const ValueTree componentStateList (componentState.getChildByName (\"COMPONENTS\"));\r\n" +"\r\n" " %%constructor%%\r\n" "\r\n" " //[Constructor] You can add your own custom stuff here..\r\n" @@ -688,6 +694,10 @@ static const unsigned char temp_73015554[] = "%%staticMemberDefinitions%%\r\n" "\r\n" "//==============================================================================\r\n" +"/* This data contains the ValueTree that holds all the Jucer-generated settings for the components */\r\n" +"const unsigned char %%className%%_ComponentStateData[] = %%statedata%%;\r\n" +"\r\n" +"//==============================================================================\r\n" "//======================= Jucer Information Section ==========================\r\n" "//==============================================================================\r\n" "#if 0\r\n" @@ -760,6 +770,8 @@ static const unsigned char temp_b930c59[] = " %%privateMemberDeclarations%%\r\n" "\r\n" " //==============================================================================\r\n" +" ValueTree componentState;\r\n" +" \r\n" " // (prevent copy constructor and operator= being generated..)\r\n" " %%className%% (const %%className%%&);\r\n" " %%className%%& operator= (const %%className%%&);\r\n" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h index 32e5c5b533..50f94d0b3c 100644 --- a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h +++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h @@ -26,10 +26,10 @@ namespace BinaryData const int jucer_AudioPluginFilterTemplate_hSize = 2353; extern const char* jucer_ComponentTemplate_cpp; - const int jucer_ComponentTemplate_cppSize = 1976; + const int jucer_ComponentTemplate_cppSize = 2534; extern const char* jucer_ComponentTemplate_h; - const int jucer_ComponentTemplate_hSize = 2239; + const int jucer_ComponentTemplate_hSize = 2276; extern const char* jucer_MainConsoleAppTemplate_cpp; const int jucer_MainConsoleAppTemplate_cppSize = 749; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h index 6f0d228597..b280c11f31 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h @@ -34,7 +34,7 @@ class ComboBoxHandler : public ComponentTypeHelper { public: - ComboBoxHandler() : ComponentTypeHelper ("ComboBox", "COMBOBOX", "comboBox") + ComboBoxHandler() : ComponentTypeHelper ("ComboBox", "ComboBox", "COMBOBOX", "comboBox") { addEditableColour (ComboBox::backgroundColourId, "Background", "backgroundColour"); addEditableColour (ComboBox::textColourId, "Text", "textColour"); @@ -45,16 +45,16 @@ public: ~ComboBoxHandler() {} - Component* createComponent() { return new ComboBox (String::empty); } + Component* createComponent() { return new ComboBox(); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 180, 24); } - void initialiseNew (ComponentDocument& document, ValueTree& state) + void initialiseNew (ComponentTypeInstance& item) { - state.setProperty ("items", "Item 1\nItem 2", 0); - state.setProperty ("editable", false, 0); - state.setProperty ("textJustification", (int) Justification::centredLeft, 0); - state.setProperty ("unselectedText", "", 0); - state.setProperty ("noItemsText", "(No Choices)", 0); + item.set ("items", "Item 1\nItem 2"); + item.set ("editable", false); + item.set ("textJustification", (int) Justification::centredLeft); + item.set ("unselectedText", ""); + item.set ("noItemsText", "(No Choices)"); } void updateItems (ComboBox* comp, const String& itemString) @@ -77,29 +77,34 @@ public: } } - void update (ComponentDocument& document, ComboBox* comp, const ValueTree& state) + void update (ComponentTypeInstance& item, ComboBox* comp) { - updateItems (comp, state ["items"]); - comp->setEditableText (state ["editable"]); - comp->setJustificationType ((int) state ["textJustification"]); - comp->setTextWhenNothingSelected (state ["unselectedText"].toString()); - comp->setTextWhenNoChoicesAvailable (state ["noItemsText"].toString()); + updateItems (comp, item ["items"]); + comp->setEditableText (item ["editable"]); + comp->setJustificationType ((int) item ["textJustification"]); + comp->setTextWhenNothingSelected (item ["unselectedText"].toString()); + comp->setTextWhenNoChoicesAvailable (item ["noItemsText"].toString()); } - void createProperties (ComponentDocument& document, ValueTree& state, Array & props) + void createProperties (ComponentTypeInstance& item, Array & props) { - addTooltipProperty (document, state, props); - addFocusOrderProperty (document, state, props); + item.addTooltipProperty (props); + item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (getValue ("items", state, document), "Items", 16384, true)); + props.add (new TextPropertyComponent (item.getValue ("items"), "Items", 16384, true)); props.getLast()->setTooltip ("A list of items to use to initialise the ComboBox"); - props.add (new BooleanPropertyComponent (getValue ("editable", state, document), "Editable", "Text is editable")); - props.add (createJustificationProperty ("Text Position", getValue ("textJustification", state, document), false)); - props.add (new TextPropertyComponent (getValue ("unselectedText", state, document), "Text when none selected", 512, false)); - props.add (new TextPropertyComponent (getValue ("noItemsText", state, document), "Text when no items", 512, false)); + props.add (new BooleanPropertyComponent (item.getValue ("editable"), "Editable", "Text is editable")); + item.addJustificationProperty (props, "Text Position", item.getValue ("textJustification"), false); + props.add (new TextPropertyComponent (item.getValue ("unselectedText"), "Text when none selected", 512, false)); + props.add (new TextPropertyComponent (item.getValue ("noItemsText"), "Text when no items", 512, false)); - addEditableColourProperties (document, state, props); + addEditableColourProperties (item, props); + } + + void createCode (ComponentTypeInstance& item, CodeGenerator& code) + { + code.constructorCode << item.createConstructorStatement (String::empty); } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp index df5a0eefc8..db20f38549 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp @@ -153,101 +153,6 @@ private: } }; - -//============================================================================== -ComponentTypeHandler::ComponentTypeHandler (const String& name_, const String& xmlTag_, - const String& memberNameRoot_) - : name (name_), xmlTag (xmlTag_), - memberNameRoot (memberNameRoot_) -{ -} - -ComponentTypeHandler::~ComponentTypeHandler() -{ -} - -Value ComponentTypeHandler::getValue (const var::identifier& name_, ValueTree& state, ComponentDocument& document) const -{ - return state.getPropertyAsValue (name_, document.getUndoManager()); -} - -void ComponentTypeHandler::updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state) -{ - RectangleCoordinates pos (state [ComponentDocument::compBoundsProperty].toString()); - comp->setBounds (pos.resolve (document)); - - comp->setName (state [ComponentDocument::compNameProperty]); - - comp->setExplicitFocusOrder (state [ComponentDocument::compFocusOrderProperty]); - - SettableTooltipClient* tooltipClient = dynamic_cast (comp); - if (tooltipClient != 0) - tooltipClient->setTooltip (state [ComponentDocument::compTooltipProperty]); -} - -void ComponentTypeHandler::initialiseNewItem (ComponentDocument& document, ValueTree& state) -{ - state.setProperty (ComponentDocument::compNameProperty, String::empty, 0); - state.setProperty (ComponentDocument::memberNameProperty, document.getNonexistentMemberName (getMemberNameRoot()), 0); - - const Rectangle bounds (getDefaultSize().withPosition (Point (Random::getSystemRandom().nextInt (100) + 100, - Random::getSystemRandom().nextInt (100) + 100))); - - state.setProperty (ComponentDocument::compBoundsProperty, - RectangleCoordinates (bounds.toFloat(), - state [ComponentDocument::memberNameProperty]).toString(), 0); -} - - -//============================================================================== -class CompMemberNameValueSource : public Value::ValueSource, - public Value::Listener -{ -public: - CompMemberNameValueSource (ComponentDocument& document_, const ValueTree& state) - : sourceValue (state.getPropertyAsValue (ComponentDocument::memberNameProperty, document_.getUndoManager())), - document (document_) - { - sourceValue.addListener (this); - } - - ~CompMemberNameValueSource() {} - - void valueChanged (Value&) { sendChangeMessage (true); } - const var getValue() const { return sourceValue.toString(); } - - void setValue (const var& newValue) - { - if (newValue == sourceValue) - return; - - const String name (document.getNonexistentMemberName (newValue)); - - if (sourceValue != name) - { - document.renameAnchor (sourceValue.toString(), name); - sourceValue = name; - } - } - -private: - Value sourceValue; - ComponentDocument& document; - - CompMemberNameValueSource (const CompMemberNameValueSource&); - const CompMemberNameValueSource& operator= (const CompMemberNameValueSource&); -}; - -void ComponentTypeHandler::createPropertyEditors (ComponentDocument& document, ValueTree& state, Array & props) -{ - props.add (new TextPropertyComponent (Value (new CompMemberNameValueSource (document, state)), "Member Name", 256, false)); - - props.add (new ComponentBoundsEditor (document, "Left", ComponentBoundsEditor::left, state, getValue (ComponentDocument::compBoundsProperty, state, document))); - props.add (new ComponentBoundsEditor (document, "Right", ComponentBoundsEditor::right, state, getValue (ComponentDocument::compBoundsProperty, state, document))); - props.add (new ComponentBoundsEditor (document, "Top", ComponentBoundsEditor::top, state, getValue (ComponentDocument::compBoundsProperty, state, document))); - props.add (new ComponentBoundsEditor (document, "Bottom", ComponentBoundsEditor::bottom, state, getValue (ComponentDocument::compBoundsProperty, state, document))); -} - //============================================================================== ComponentTypeManager::ComponentTypeManager() { @@ -268,7 +173,10 @@ Component* ComponentTypeManager::createFromStoredType (ComponentDocument& docume Component* c = handler->createComponent(); if (c != 0) - handler->updateComponent (document, c, value); + { + ComponentTypeInstance item (document, value); + handler->updateComponent (item, c); + } return c; } @@ -282,13 +190,372 @@ ComponentTypeHandler* ComponentTypeManager::getHandlerFor (const String& type) return 0; } -const StringArray ComponentTypeManager::getTypeNames() const +const StringArray ComponentTypeManager::getDisplayNames() const { StringArray s; for (int i = 0; i < handlers.size(); ++i) - s.add (handlers.getUnchecked(i)->getName()); + s.add (handlers.getUnchecked(i)->getDisplayName()); return s; } juce_ImplementSingleton_SingleThreaded (ComponentTypeManager); + + + +//============================================================================== +ComponentTypeHandler::ComponentTypeHandler (const String& displayName_, const String& className_, + const String& xmlTag_, const String& memberNameRoot_) + : displayName (displayName_), className (className_), xmlTag (xmlTag_), + memberNameRoot (memberNameRoot_) +{ +} + +ComponentTypeHandler::~ComponentTypeHandler() +{ +} + +//============================================================================== +class CompMemberNameValueSource : public Value::ValueSource, + public Value::Listener +{ +public: + CompMemberNameValueSource (ComponentTypeInstance& item_) + : sourceValue (item_.getValue (ComponentDocument::memberNameProperty)), + item (item_) + { + sourceValue.addListener (this); + } + + ~CompMemberNameValueSource() {} + + void valueChanged (Value&) { sendChangeMessage (true); } + const var getValue() const { return sourceValue.toString(); } + + void setValue (const var& newValue) + { + if (newValue == sourceValue) + return; + + const String name (item.getDocument().getNonexistentMemberName (newValue)); + + if (sourceValue != name) + { + item.getDocument().renameAnchor (sourceValue.toString(), name); + sourceValue = name; + } + } + +private: + Value sourceValue; + ComponentTypeInstance& item; + + CompMemberNameValueSource (const CompMemberNameValueSource&); + const CompMemberNameValueSource& operator= (const CompMemberNameValueSource&); +}; + + +//============================================================================== +ComponentTypeInstance::ComponentTypeInstance (ComponentDocument& document_, const ValueTree& state_) + : document (document_), state (state_) +{ +} + +Value ComponentTypeInstance::getValue (const var::identifier& name) const +{ + return state.getPropertyAsValue (name, document.getUndoManager()); +} + +void ComponentTypeInstance::set (const var::identifier& name, const var& value) +{ + state.setProperty (name, value, 0); +} + +ComponentTypeHandler* ComponentTypeInstance::getHandler() const +{ + ComponentTypeHandler* const handler = ComponentTypeManager::getInstance()->getHandlerFor (state.getType()); + jassert (handler != 0); + return handler; +} + +void ComponentTypeInstance::updateComponent (Component* comp) +{ + getHandler()->updateComponent (*this, comp); +} + +void ComponentTypeInstance::createProperties (Array & props) +{ + getHandler()->createPropertyEditors (*this, props); +} + +void ComponentTypeInstance::createCode (CodeGenerator& code) +{ + code.addPrivateMember (getHandler()->getClassName (*this) + "*", getMemberName()); + getHandler()->createCode (*this, code); +} + +//============================================================================== +void ComponentTypeInstance::initialiseNewItemBasics() +{ + ComponentTypeHandler* handler = getHandler(); + + set (ComponentDocument::compNameProperty, String::empty); + set (ComponentDocument::memberNameProperty, document.getNonexistentMemberName (handler->getMemberNameRoot())); + + Rectangle bounds (handler->getDefaultSize()); + int cw = document.getCanvasWidth().getValue(); + int ch = document.getCanvasHeight().getValue(); + bounds.setPosition (Random::getSystemRandom().nextInt (cw / 3) + cw / 4, + Random::getSystemRandom().nextInt (ch / 3) + ch / 4); + + set (ComponentDocument::compBoundsProperty, RectangleCoordinates (bounds.toFloat(), getMemberName()).toString()); +} + +void ComponentTypeInstance::updateComponentBasics (Component* comp) +{ + RectangleCoordinates pos (state [ComponentDocument::compBoundsProperty].toString()); + comp->setBounds (pos.resolve (document)); + + comp->setName (state [ComponentDocument::compNameProperty]); + + comp->setExplicitFocusOrder (state [ComponentDocument::compFocusOrderProperty]); + + SettableTooltipClient* tooltipClient = dynamic_cast (comp); + if (tooltipClient != 0) + tooltipClient->setTooltip (state [ComponentDocument::compTooltipProperty]); +} + +void ComponentTypeInstance::addMemberNameProperty (Array & props) +{ + props.add (new TextPropertyComponent (Value (new CompMemberNameValueSource (*this)), + "Member Name", 256, false)); +} + +void ComponentTypeInstance::addBoundsProperties (Array & props) +{ + const Value bounds (getValue (ComponentDocument::compBoundsProperty)); + props.add (new ComponentBoundsEditor (document, "Left", ComponentBoundsEditor::left, state, bounds)); + props.add (new ComponentBoundsEditor (document, "Right", ComponentBoundsEditor::right, state, bounds)); + props.add (new ComponentBoundsEditor (document, "Top", ComponentBoundsEditor::top, state, bounds)); + props.add (new ComponentBoundsEditor (document, "Bottom", ComponentBoundsEditor::bottom, state, bounds)); +} + +void ComponentTypeInstance::addTooltipProperty (Array & props) +{ + props.add (new TextPropertyComponent (getValue (ComponentDocument::compTooltipProperty), + "Tooltip", 4096, false)); +} + +void ComponentTypeInstance::addFocusOrderProperty (Array & props) +{ + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue (ComponentDocument::compFocusOrderProperty))), + "Focus Order", 10, false)); +} + +void ComponentTypeInstance::addColourProperty (Array & props, int colourId, const String& name, const String& propertyName) +{ + props.add (new ColourPropertyComponent (document, name, getValue (propertyName), + LookAndFeel::getDefaultLookAndFeel().findColour (colourId), true)); +} + +//============================================================================== +class FontNameValueSource : public Value::ValueSource, + public Value::Listener +{ +public: + FontNameValueSource (const Value& source) + : sourceValue (source) + { + sourceValue.addListener (this); + } + + ~FontNameValueSource() {} + + void valueChanged (Value&) { sendChangeMessage (true); } + + const var getValue() const + { + const String fontName (Font::fromString (sourceValue.toString()).getTypefaceName()); + const int index = StoredSettings::getInstance()->getFontNames().indexOf (fontName); + + if (index >= 0) return 4 + index; + else if (fontName == Font::getDefaultSansSerifFontName()) return 1; + else if (fontName == Font::getDefaultSerifFontName()) return 2; + else if (fontName == Font::getDefaultMonospacedFontName()) return 3; + + return 1; + } + + void setValue (const var& newValue) + { + Font font (Font::fromString (sourceValue.toString())); + + const int index = newValue; + if (index <= 1) font.setTypefaceName (Font::getDefaultSansSerifFontName()); + else if (index == 2) font.setTypefaceName (Font::getDefaultSerifFontName()); + else if (index == 3) font.setTypefaceName (Font::getDefaultMonospacedFontName()); + else font.setTypefaceName (StoredSettings::getInstance()->getFontNames() [index - 4]); + + sourceValue = font.toString(); + } + + static ChoicePropertyComponent* createProperty (const String& title, const Value& value) + { + StringArray fontNames; + fontNames.add (Font::getDefaultSansSerifFontName()); + fontNames.add (Font::getDefaultSerifFontName()); + fontNames.add (Font::getDefaultMonospacedFontName()); + fontNames.add (String::empty); + fontNames.addArray (StoredSettings::getInstance()->getFontNames()); + + return new ChoicePropertyComponent (Value (new FontNameValueSource (value)), title, fontNames); + } + +private: + Value sourceValue; +}; + +class FontSizeValueSource : public Value::ValueSource, + public Value::Listener +{ +public: + FontSizeValueSource (const Value& source) + : sourceValue (source) + { + sourceValue.addListener (this); + } + + ~FontSizeValueSource() {} + + void valueChanged (Value&) { sendChangeMessage (true); } + + const var getValue() const + { + return Font::fromString (sourceValue.toString()).getHeight(); + } + + void setValue (const var& newValue) + { + Font font (Font::fromString (sourceValue.toString())); + font.setHeight (newValue); + sourceValue = font.toString(); + } + + static PropertyComponent* createProperty (const String& title, const Value& value) + { + return new SliderPropertyComponent (Value (new FontSizeValueSource (value)), title, 1.0, 150.0, 0.1, 0.5); + } + +private: + Value sourceValue; +}; + +class FontStyleValueSource : public Value::ValueSource, + public Value::Listener +{ +public: + FontStyleValueSource (const Value& source) + : sourceValue (source) + { + sourceValue.addListener (this); + } + + ~FontStyleValueSource() {} + + void valueChanged (Value&) { sendChangeMessage (true); } + + const var getValue() const + { + const Font f (Font::fromString (sourceValue.toString())); + + if (f.isBold() && f.isItalic()) return getStyles() [3]; + if (f.isBold()) return getStyles() [1]; + if (f.isItalic()) return getStyles() [2]; + + return getStyles() [0]; + } + + void setValue (const var& newValue) + { + Font font (Font::fromString (sourceValue.toString())); + font.setBold (newValue.toString().containsIgnoreCase ("Bold")); + font.setItalic (newValue.toString().containsIgnoreCase ("Italic")); + sourceValue = font.toString(); + } + + static PropertyComponent* createProperty (const String& title, const Value& value) + { + return StringListValueSource::create (title, Value (new FontStyleValueSource (value)), StringArray (getStyles())); + } + + static const char* const* getStyles() + { + static const char* const fontStyles[] = { "Normal", "Bold", "Italic", "Bold + Italic", 0 }; + return fontStyles; + } + +private: + Value sourceValue; +}; + +void ComponentTypeInstance::addFontProperties (Array & props, const var::identifier& name) +{ + Value v (getValue (name)); + props.add (FontNameValueSource::createProperty ("Font", v)); + props.add (FontSizeValueSource::createProperty ("Font Size", v)); + props.add (FontStyleValueSource::createProperty ("Font Style", v)); +} + +//============================================================================== +void ComponentTypeInstance::addJustificationProperty (Array & props, const String& name, const Value& value, bool onlyHorizontal) +{ + ValueRemapperSource* remapper = new ValueRemapperSource (value); + StringArray strings; + + if (onlyHorizontal) + { + const char* const layouts[] = { "Left", "Centred", "Right", 0 }; + const int justifications[] = { Justification::left, Justification::centred, Justification::right, 0 }; + + for (int i = 0; i < numElementsInArray (justifications) - 1; ++i) + remapper->addMapping (justifications[i], i + 1); + + strings = StringArray (layouts); + } + else + { + const char* const layouts[] = { "Centred", "Centred-left", "Centred-right", "Centred-top", "Centred-bottom", "Top-left", + "Top-right", "Bottom-left", "Bottom-right", 0 }; + const int justifications[] = { Justification::centred, Justification::centredLeft, Justification::centredRight, + Justification::centredTop, Justification::centredBottom, Justification::topLeft, + Justification::topRight, Justification::bottomLeft, Justification::bottomRight, 0 }; + + for (int i = 0; i < numElementsInArray (justifications) - 1; ++i) + remapper->addMapping (justifications[i], i + 1); + + strings = StringArray (layouts); + } + + props.add (new ChoicePropertyComponent (Value (remapper), name, strings)); +} + +//============================================================================== +const String ComponentTypeInstance::createConstructorStatement (const String& params) +{ + String s; + s << "addAndMakeVisible (" << getMemberName() + << " = new " << getHandler()->getClassName (*this); + + if (params.isEmpty()) + s << "());" << newLine; + else + { + s << " ("; + s << CodeFormatting::indent (params.trim(), s.length(), false) << "));" << newLine; + } + +// s << getMemberName() << "->updateStateFrom (componentStateList.getChild (" + // << document.getComponentGroup().indexOf (state) << ");" << newLine; + + return s; +} diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h index bfc59c634e..8865010532 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h @@ -29,6 +29,70 @@ #include "../../../jucer_Headers.h" #include "../jucer_ComponentDocument.h" #include "../../../utility/jucer_ColourEditorComponent.h" +class ComponentTypeHandler; + +class JucerState +{ +public: + JucerState (const ValueTree& state_) + : state (state_) + { + } + + ~JucerState() + { + } + +private: + ValueTree state; +}; + +//============================================================================== +/** Temporary wrapper around a document and a component's ValueTree, providing lots of useful + functions that can be performed on the component. +*/ +class ComponentTypeInstance +{ +public: + ComponentTypeInstance (ComponentDocument& document_, const ValueTree& state_); + + //============================================================================== + ComponentDocument& getDocument() throw() { return document; } + ValueTree& getState() throw() { return state; } + + Value getValue (const var::identifier& name) const; + void set (const var::identifier& name, const var& value); + const var operator[] (const var::identifier& name) const { return state [name] ;} + + const String getMemberName() const { return state [ComponentDocument::memberNameProperty]; } + const String getComponentName() const { return state [ComponentDocument::compNameProperty]; } + + //============================================================================== + void initialiseNewItemBasics(); + void updateComponentBasics (Component* comp); + + void addMemberNameProperty (Array & props); + void addBoundsProperties (Array & props); + void addTooltipProperty (Array & props); + void addFocusOrderProperty (Array & props); + void addColourProperty (Array & props, int colourId, const String& name, const String& propertyName); + void addFontProperties (Array & props, const var::identifier& name); + void addJustificationProperty (Array & props, const String& name, const Value& value, bool onlyHorizontal); + + //============================================================================== + const String createConstructorStatement (const String& params); + + //============================================================================== + ComponentTypeHandler* getHandler() const; + void updateComponent (Component* comp); + void createProperties (Array & props); + void createCode (CodeGenerator& code); + +private: + //============================================================================== + ComponentDocument& document; + ValueTree state; +}; //============================================================================== @@ -36,25 +100,25 @@ class ComponentTypeHandler { public: //============================================================================== - ComponentTypeHandler (const String& name_, const String& xmlTag_, const String& memberNameRoot_); + ComponentTypeHandler (const String& displayName_, const String& className_, const String& xmlTag_, const String& memberNameRoot_); virtual ~ComponentTypeHandler(); - const String& getName() const { return name; } + const String& getDisplayName() const { return displayName; } const String& getXmlTag() const { return xmlTag; } const String& getMemberNameRoot() const { return memberNameRoot; } virtual Component* createComponent() = 0; virtual const Rectangle getDefaultSize() = 0; - virtual void updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state); - virtual void initialiseNewItem (ComponentDocument& document, ValueTree& state); - virtual void createPropertyEditors (ComponentDocument& document, ValueTree& state, Array & props); - - Value getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const; + virtual void initialiseNewItem (ComponentTypeInstance& item) = 0; + virtual void updateComponent (ComponentTypeInstance& item, Component* comp) = 0; + virtual void createPropertyEditors (ComponentTypeInstance& item, Array & props) = 0; + virtual void createCode (ComponentTypeInstance& item, CodeGenerator& code) = 0; + virtual const String getClassName (ComponentTypeInstance& item) const { return className; } protected: //============================================================================== - const String name, xmlTag, memberNameRoot; + const String displayName, className, xmlTag, memberNameRoot; private: ComponentTypeHandler (const ComponentTypeHandler&); @@ -79,7 +143,7 @@ public: ComponentTypeHandler* getHandler (const int index) const { return handlers[index]; } ComponentTypeHandler* getHandlerFor (const String& type); - const StringArray getTypeNames() const; + const StringArray getDisplayNames() const; private: //============================================================================== @@ -93,74 +157,46 @@ class ComponentTypeHelper : public ComponentTypeHandler { public: //============================================================================== - ComponentTypeHelper (const String& name_, const String& xmlTag_, const String& memberNameRoot_) - : ComponentTypeHandler (name_, xmlTag_, memberNameRoot_) + ComponentTypeHelper (const String& displayName_, const String& className_, const String& xmlTag_, const String& memberNameRoot_) + : ComponentTypeHandler (displayName_, className_, xmlTag_, memberNameRoot_) { } - virtual void update (ComponentDocument& document, ComponentClass* comp, const ValueTree& state) = 0; + virtual void initialiseNew (ComponentTypeInstance& item) = 0; + virtual void update (ComponentTypeInstance& item, ComponentClass* comp) = 0; + virtual void createProperties (ComponentTypeInstance& item, Array & props) = 0; - void updateComponent (ComponentDocument& document, Component* comp, const ValueTree& state) + void initialiseNewItem (ComponentTypeInstance& item) { - ComponentTypeHandler::updateComponent (document, comp, state); + item.initialiseNewItemBasics(); + initialiseNew (item); + } + + void updateComponent (ComponentTypeInstance& item, Component* comp) + { + item.updateComponentBasics (comp); ComponentClass* const c = dynamic_cast (comp); jassert (c != 0); - updateComponentColours (state, c); - update (document, c, state); + updateComponentColours (item, c); + + update (item, c); } - virtual void initialiseNew (ComponentDocument& document, ValueTree& state) = 0; - - void initialiseNewItem (ComponentDocument& document, ValueTree& state) + void createPropertyEditors (ComponentTypeInstance& item, Array & props) { - ComponentTypeHandler::initialiseNewItem (document, state); - initialiseNew (document, state); - } + item.addMemberNameProperty (props); + item.addBoundsProperties (props); - virtual void createProperties (ComponentDocument& document, ValueTree& state, Array & props) = 0; - - void createPropertyEditors (ComponentDocument& document, ValueTree& state, Array & props) - { - ComponentTypeHandler::createPropertyEditors (document, state, props); - createProperties (document, state, props); + createProperties (item, props); } protected: - //============================================================================== - void addTooltipProperty (ComponentDocument& document, ValueTree& state, Array & props) - { - props.add (new TextPropertyComponent (getValue (ComponentDocument::compTooltipProperty, state, document), - "Tooltip", 4096, false)); - } - - void addFocusOrderProperty (ComponentDocument& document, ValueTree& state, Array & props) - { - props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue (ComponentDocument::compFocusOrderProperty, - state, document))), - "Focus Order", 10, false)); - } - //============================================================================== struct EditableColour { int colourId; String name, propertyName; - - PropertyComponent* createProperty (ComponentTypeHelper& type, ComponentDocument& document, ValueTree& state) - { - return new ColourPropertyComponent (document, name, type.getValue (propertyName, state, document), - LookAndFeel::getDefaultLookAndFeel().findColour (colourId), true); - } - - void updateComponent (const ValueTree& state, Component* component) - { - const String colour (state [propertyName].toString()); - if (colour.isNotEmpty()) - component->setColour (colourId, Colour::fromString (colour)); - else - component->removeColour (colourId); - } }; Array editableColours; @@ -174,16 +210,28 @@ protected: editableColours.add (ec); } - void addEditableColourProperties (ComponentDocument& document, ValueTree& state, Array & props) + void addEditableColourProperties (ComponentTypeInstance& item, Array & props) { for (int i = 0; i < editableColours.size(); ++i) - props.add (editableColours.getReference(i).createProperty (*this, document, state)); + { + const EditableColour& ec = editableColours.getReference(i); + item.addColourProperty (props, ec.colourId, ec.name, ec.propertyName); + } } - void updateComponentColours (const ValueTree& state, Component* component) + void updateComponentColours (ComponentTypeInstance& item, Component* component) { for (int i = 0; i < editableColours.size(); ++i) - editableColours.getReference(i).updateComponent (state, component); + { + const EditableColour& ec = editableColours.getReference(i); + + const String colour (item.getState() [ec.propertyName].toString()); + + if (colour.isNotEmpty()) + component->setColour (ec.colourId, Colour::fromString (colour)); + else + component->removeColour (ec.colourId); + } } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h index cdcb05e942..99e05c274f 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h @@ -34,7 +34,7 @@ class GenericComponentHandler : public ComponentTypeHelper { public: - GenericComponentHandler() : ComponentTypeHelper ("Generic Component", "COMPONENT", "component") {} + GenericComponentHandler() : ComponentTypeHelper ("Generic Component", "Component", "COMPONENT", "component") {} ~GenericComponentHandler() {} //============================================================================== @@ -66,24 +66,34 @@ public: Component* createComponent() { return new PlaceholderComp(); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 180, 24); } - void update (ComponentDocument& document, Component* comp, const ValueTree& state) + void initialiseNew (ComponentTypeInstance& item) { - static_cast (comp)->setDetails (state [ComponentDocument::memberNameProperty], - state ["class"]); + item.set ("class", "Component"); } - void initialiseNew (ComponentDocument& document, ValueTree& state) + void update (ComponentTypeInstance& item, Component* comp) { - state.setProperty ("class", "Component", 0); + static_cast (comp)->setDetails (item [ComponentDocument::memberNameProperty], + item ["class"]); } - void createProperties (ComponentDocument& document, ValueTree& state, Array & props) + void createProperties (ComponentTypeInstance& item, Array & props) { - addFocusOrderProperty (document, state, props); + item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (getValue ("class", state, document), "Class", 256, false)); + props.add (new TextPropertyComponent (item.getValue ("class"), "Class", 256, false)); props.getLast()->setTooltip ("The class that this component is an instance of."); } + + const String getClassName (ComponentTypeInstance& item) const + { + return item ["class"]; + } + + void createCode (ComponentTypeInstance& item, CodeGenerator& code) + { + code.constructorCode << item.createConstructorStatement (String::empty); + } }; #endif diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h index f55a14a641..78abea46d7 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h @@ -34,7 +34,7 @@ class GroupComponentHandler : public ComponentTypeHelper { public: - GroupComponentHandler() : ComponentTypeHelper ("GroupComponent", "GROUPCOMPONENT", "group") + GroupComponentHandler() : ComponentTypeHelper ("GroupComponent", "GroupComponent", "GROUPCOMPONENT", "group") { addEditableColour (GroupComponent::outlineColourId, "Outline", "outlineColour"); addEditableColour (GroupComponent::textColourId, "Text Colour", "textColour"); @@ -42,31 +42,36 @@ public: ~GroupComponentHandler() {} - Component* createComponent() { return new GroupComponent (String::empty, String::empty); } + Component* createComponent() { return new GroupComponent(); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 200, 200); } - void update (ComponentDocument& document, GroupComponent* comp, const ValueTree& state) + void initialiseNew (ComponentTypeInstance& item) { - comp->setText (state ["text"].toString()); - comp->setTextLabelPosition ((int) state ["justification"]); + item.set ("text", "Group"); + item.set ("justification", (int) Justification::left); } - void initialiseNew (ComponentDocument& document, ValueTree& state) + void update (ComponentTypeInstance& item, GroupComponent* comp) { - state.setProperty ("text", "Group", 0); - state.setProperty ("justification", (int) Justification::left, 0); + comp->setText (item ["text"].toString()); + comp->setTextLabelPosition ((int) item ["justification"]); } - void createProperties (ComponentDocument& document, ValueTree& state, Array & props) + void createProperties (ComponentTypeInstance& item, Array & props) { - addTooltipProperty (document, state, props); - addFocusOrderProperty (document, state, props); + item.addTooltipProperty (props); + item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (getValue ("text", state, document), "Label", 512, false)); + props.add (new TextPropertyComponent (item.getValue ("text"), "Label", 512, false)); props.getLast()->setTooltip ("The group's display name."); - props.add (createJustificationProperty ("Text Position", state.getPropertyAsValue ("justification", document.getUndoManager()), true)); - addEditableColourProperties (document, state, props); + item.addJustificationProperty (props, "Text Position", item.getValue ("justification"), true); + addEditableColourProperties (item, props); + } + + void createCode (ComponentTypeInstance& item, CodeGenerator& code) + { + code.constructorCode << item.createConstructorStatement (String::empty); } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h index d9ba66110d..6537b9385d 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h @@ -57,24 +57,34 @@ private: class JucerComponentHandler : public ComponentTypeHelper { public: - JucerComponentHandler() : ComponentTypeHelper ("Jucer Component", "JUCERCOMPONENT", "jucerComp") {} + JucerComponentHandler() : ComponentTypeHelper ("Jucer Component", "Component", "JUCERCOMPONENT", "jucerComp") {} ~JucerComponentHandler() {} //============================================================================== Component* createComponent() { return new JucerComponent(); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 150, 150); } - void update (ComponentDocument& document, JucerComponent* comp, const ValueTree& state) + void initialiseNew (ComponentTypeInstance& item) { } - void initialiseNew (ComponentDocument& document, ValueTree& state) + void update (ComponentTypeInstance& item, JucerComponent* comp) { } - void createProperties (ComponentDocument& document, ValueTree& state, Array & props) + void createProperties (ComponentTypeInstance& item, Array & props) { } + + const String getClassName (ComponentTypeInstance& item) const + { + return "xxx"; + } + + void createCode (ComponentTypeInstance& item, CodeGenerator& code) + { + code.constructorCode << item.createConstructorStatement (String::empty); + } }; #endif diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h index f89a4d499d..0b28894830 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h @@ -34,7 +34,7 @@ class LabelHandler : public ComponentTypeHelper