/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2015 - ROLI 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. ============================================================================== */ class LabelHandler : public ComponentTypeHandler { public: LabelHandler() : ComponentTypeHandler ("Label", "Label", typeid (Label), 150, 24) { registerColour (Label::backgroundColourId, "background", "bkgCol"); registerColour (Label::textColourId, "text", "textCol"); registerColour (Label::outlineColourId, "outline", "outlineCol"); registerColour (TextEditor::textColourId, "editor text", "edTextCol"); registerColour (TextEditor::backgroundColourId, "editor bkg", "edBkgCol"); registerColour (TextEditor::highlightColourId, "highlight", "hiliteCol"); } Component* createNewComponent (JucerDocument*) { return new Label ("new label", "label text"); } XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) { Label* const l = dynamic_cast (comp); XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout); e->setAttribute ("labelText", l->getText()); e->setAttribute ("editableSingleClick", l->isEditableOnSingleClick()); e->setAttribute ("editableDoubleClick", l->isEditableOnDoubleClick()); e->setAttribute ("focusDiscardsChanges", l->doesLossOfFocusDiscardChanges()); e->setAttribute ("fontname", l->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()).toString()); e->setAttribute ("fontsize", roundToInt (l->getFont().getHeight() * 100.0) / 100.0); e->setAttribute ("kerning", roundToInt (l->getFont().getExtraKerningFactor() * 1000.0) / 1000.0); e->setAttribute ("bold", l->getFont().isBold()); e->setAttribute ("italic", l->getFont().isItalic()); e->setAttribute ("justification", l->getJustificationType().getFlags()); if (l->getFont().getTypefaceStyle() != "Regular") { e->setAttribute ("typefaceStyle", l->getFont().getTypefaceStyle()); } return e; } bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) { Label* const l = dynamic_cast (comp); if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout)) return false; Label defaultLabel; Font font; font.setHeight ((float) xml.getDoubleAttribute ("fontsize", 15.0)); font.setBold (xml.getBoolAttribute ("bold", false)); font.setItalic (xml.getBoolAttribute ("italic", false)); font.setExtraKerningFactor ((float) xml.getDoubleAttribute ("kerning", 0.0)); auto fontStyle = xml.getStringAttribute ("typefaceStyle"); if (! fontStyle.isEmpty()) font.setTypefaceStyle (fontStyle); l->setFont (font); l->getProperties().set ("typefaceName", xml.getStringAttribute ("fontname", FontPropertyComponent::getDefaultFont())); updateLabelFont (l); l->setJustificationType (Justification (xml.getIntAttribute ("justification", Justification::centred))); l->setText (xml.getStringAttribute ("labelText", "Label Text"), dontSendNotification); l->setEditable (xml.getBoolAttribute ("editableSingleClick", defaultLabel.isEditableOnSingleClick()), xml.getBoolAttribute ("editableDoubleClick", defaultLabel.isEditableOnDoubleClick()), xml.getBoolAttribute ("focusDiscardsChanges", defaultLabel.doesLossOfFocusDiscardChanges())); return true; } static void updateLabelFont (Label* label) { Font f (label->getFont()); f = FontPropertyComponent::applyNameToFont (label->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()), f); label->setFont (f); } String getCreationParameters (GeneratedCode& code, Component* component) { Label* const l = dynamic_cast (component); return quotedString (component->getName(), false) + ",\n" + quotedString (l->getText(), code.shouldUseTransMacro()); } void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) { ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName); Label* const l = dynamic_cast (component); String s; s << memberVariableName << "->setFont (" << FontPropertyComponent::getCompleteFontCode (l->getFont(), l->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont())) << ");\n" << memberVariableName << "->setJustificationType (" << CodeHelpers::justificationToCode (l->getJustificationType()) << ");\n" << memberVariableName << "->setEditable (" << CodeHelpers::boolLiteral (l->isEditableOnSingleClick()) << ", " << CodeHelpers::boolLiteral (l->isEditableOnDoubleClick()) << ", " << CodeHelpers::boolLiteral (l->doesLossOfFocusDiscardChanges()) << ");\n" << getColourIntialisationCode (component, memberVariableName); if (needsCallback (component)) s << memberVariableName << "->addListener (this);\n"; s << '\n'; code.constructorCode += s; } void fillInGeneratedCode (Component* component, GeneratedCode& code) { ComponentTypeHandler::fillInGeneratedCode (component, code); if (needsCallback (component)) { String& callback = code.getCallbackCode ("public LabelListener", "void", "labelTextChanged (Label* labelThatHasChanged)", true); if (callback.trim().isNotEmpty()) callback << "else "; const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component)); const String userCodeComment ("UserLabelCode_" + memberVariableName); callback << "if (labelThatHasChanged == " << memberVariableName << ")\n{\n //[" << userCodeComment << "] -- add your label text handling code here..\n //[/" << userCodeComment << "]\n}\n"; } } void getEditableProperties (Component* component, JucerDocument& document, Array& props) { ComponentTypeHandler::getEditableProperties (component, document, props); Label* const l = dynamic_cast (component); props.add (new LabelTextProperty (l, document)); props.add (new LabelJustificationProperty (l, document)); props.add (new FontNameProperty (l, document)); props.add (new FontStyleProperty (l, document)); props.add (new FontSizeProperty (l, document)); props.add (new FontKerningProperty (l, document)); addColourProperties (component, document, props); props.add (new LabelEditableProperty (l, document)); if (l->isEditableOnDoubleClick() || l->isEditableOnSingleClick()) props.add (new LabelLossOfFocusProperty (l, document)); } static bool needsCallback (Component* label) { return ((Label*) label)->isEditableOnSingleClick() || ((Label*) label)->isEditableOnDoubleClick(); // xxx should be configurable } private: //============================================================================== class LabelTextProperty : public ComponentTextProperty