migrating to the latest JUCE version
This commit is contained in:
@ -1,389 +1,389 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ButtonHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
ButtonHandler (const String& typeDescription_,
|
||||
const String& className_,
|
||||
const std::type_info& componentClass,
|
||||
const int defaultWidth_,
|
||||
const int defaultHeight_)
|
||||
: ComponentTypeHandler (typeDescription_, className_, componentClass,
|
||||
defaultWidth_, defaultHeight_)
|
||||
{}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* b = dynamic_cast<Button*> (component))
|
||||
{
|
||||
props.add (new ButtonTextProperty (b, document));
|
||||
|
||||
props.add (new ButtonCallbackProperty (b, document));
|
||||
|
||||
props.add (new ButtonRadioGroupProperty (b, document));
|
||||
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected left", Button::ConnectedOnLeft, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected right", Button::ConnectedOnRight, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected top", Button::ConnectedOnTop, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected bottom", Button::ConnectedOnBottom, b, document));
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
Button* const b = dynamic_cast<Button*> (comp);
|
||||
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("buttonText", b->getButtonText());
|
||||
e->setAttribute ("connectedEdges", b->getConnectedEdgeFlags());
|
||||
e->setAttribute ("needsCallback", needsButtonListener (b));
|
||||
e->setAttribute ("radioGroupId", b->getRadioGroupId());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
Button* const b = dynamic_cast<Button*> (comp);
|
||||
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
b->setButtonText (xml.getStringAttribute ("buttonText", b->getButtonText()));
|
||||
b->setConnectedEdges (xml.getIntAttribute ("connectedEdges", 0));
|
||||
setNeedsButtonListener (b, xml.getBoolAttribute ("needsCallback", true));
|
||||
b->setRadioGroupId (xml.getIntAttribute ("radioGroupId", 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
Button* const b = dynamic_cast<Button*> (component);
|
||||
|
||||
if (b->getButtonText() != b->getName())
|
||||
{
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setButtonText ("
|
||||
<< quotedString (b->getButtonText(), code.shouldUseTransMacro()) << ");\n";
|
||||
}
|
||||
|
||||
if (b->getConnectedEdgeFlags() != 0)
|
||||
{
|
||||
StringArray flags;
|
||||
|
||||
if (b->isConnectedOnLeft())
|
||||
flags.add ("juce::Button::ConnectedOnLeft");
|
||||
|
||||
if (b->isConnectedOnRight())
|
||||
flags.add ("juce::Button::ConnectedOnRight");
|
||||
|
||||
if (b->isConnectedOnTop())
|
||||
flags.add ("juce::Button::ConnectedOnTop");
|
||||
|
||||
if (b->isConnectedOnBottom())
|
||||
flags.add ("juce::Button::ConnectedOnBottom");
|
||||
|
||||
String s;
|
||||
s << memberVariableName << "->setConnectedEdges ("
|
||||
<< flags.joinIntoString (" | ") << ");\n";
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
if (b->getRadioGroupId() != 0)
|
||||
code.constructorCode << memberVariableName << "->setRadioGroupId ("
|
||||
<< b->getRadioGroupId() << ");\n";
|
||||
|
||||
if (needsButtonListener (component))
|
||||
code.constructorCode << memberVariableName << "->addListener (this);\n";
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (Component* component, GeneratedCode& code) override
|
||||
{
|
||||
ComponentTypeHandler::fillInGeneratedCode (component, code);
|
||||
|
||||
if (needsButtonListener (component))
|
||||
{
|
||||
String& callback = code.getCallbackCode ("public juce::Button::Listener",
|
||||
"void",
|
||||
"buttonClicked (juce::Button* buttonThatWasClicked)",
|
||||
true);
|
||||
|
||||
if (callback.isNotEmpty())
|
||||
callback << "else ";
|
||||
|
||||
const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component));
|
||||
const String userCodeComment ("UserButtonCode_" + memberVariableName);
|
||||
|
||||
callback
|
||||
<< "if (buttonThatWasClicked == " << memberVariableName << ".get())\n"
|
||||
<< "{\n //[" << userCodeComment << "] -- add your button handler code here..\n //[/" << userCodeComment << "]\n}\n";
|
||||
}
|
||||
}
|
||||
|
||||
static bool needsButtonListener (Component* button)
|
||||
{
|
||||
return button->getProperties().getWithDefault ("generateListenerCallback", true);
|
||||
}
|
||||
|
||||
static void setNeedsButtonListener (Component* button, const bool shouldDoCallback)
|
||||
{
|
||||
button->getProperties().set ("generateListenerCallback", shouldDoCallback);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class ButtonTextProperty : public ComponentTextProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonTextProperty (Button* button_, JucerDocument& doc)
|
||||
: ComponentTextProperty <Button> ("text", 100, false, button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ButtonTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change button text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getButtonText();
|
||||
}
|
||||
|
||||
private:
|
||||
class ButtonTextChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonTextChangeAction (Button* const comp, ComponentLayout& l, const String& newName_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newName (newName_)
|
||||
{
|
||||
oldName = comp->getButtonText();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setButtonText (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setButtonText (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonCallbackProperty : public ComponentBooleanProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonCallbackProperty (Button* b, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <Button> ("callback", "Generate ButtonListener", "Generate ButtonListener", b, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ButtonCallbackChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change button callback");
|
||||
}
|
||||
|
||||
bool getState() const { return needsButtonListener (component); }
|
||||
|
||||
private:
|
||||
class ButtonCallbackChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonCallbackChangeAction (Button* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = needsButtonListener (comp);
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
setNeedsButtonListener (getComponent(), newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
setNeedsButtonListener (getComponent(), oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonRadioGroupProperty : public ComponentTextProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonRadioGroupProperty (Button* const button_, JucerDocument& doc)
|
||||
: ComponentTextProperty <Button> ("radio group", 10, false, button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ButtonRadioGroupChangeAction (component, *document.getComponentLayout(), newText.getIntValue()),
|
||||
"Change radio group ID");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return String (component->getRadioGroupId());
|
||||
}
|
||||
|
||||
private:
|
||||
class ButtonRadioGroupChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonRadioGroupChangeAction (Button* const comp, ComponentLayout& l, const int newId_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newId (newId_)
|
||||
{
|
||||
oldId = comp->getRadioGroupId();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRadioGroupId (newId);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRadioGroupId (oldId);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
int newId, oldId;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonConnectedEdgeProperty : public ComponentBooleanProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonConnectedEdgeProperty (const String& name, const int flag_,
|
||||
Button* b, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <Button> (name, "Connected", "Connected", b, doc),
|
||||
flag (flag_)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ButtonConnectedChangeAction (component, *document.getComponentLayout(), flag, newState),
|
||||
"Change button connected edges");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return (component->getConnectedEdgeFlags() & flag) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const int flag;
|
||||
|
||||
class ButtonConnectedChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonConnectedChangeAction (Button* const comp, ComponentLayout& l, const int flag_, const bool newState_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
flag (flag_),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = ((comp->getConnectedEdgeFlags() & flag) != 0);
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (newState)
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag);
|
||||
else
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag);
|
||||
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (oldState)
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag);
|
||||
else
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag);
|
||||
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
const int flag;
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ButtonHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
ButtonHandler (const String& typeDescription_,
|
||||
const String& className_,
|
||||
const std::type_info& componentClass,
|
||||
const int defaultWidth_,
|
||||
const int defaultHeight_)
|
||||
: ComponentTypeHandler (typeDescription_, className_, componentClass,
|
||||
defaultWidth_, defaultHeight_)
|
||||
{}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* b = dynamic_cast<Button*> (component))
|
||||
{
|
||||
props.add (new ButtonTextProperty (b, document));
|
||||
|
||||
props.add (new ButtonCallbackProperty (b, document));
|
||||
|
||||
props.add (new ButtonRadioGroupProperty (b, document));
|
||||
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected left", Button::ConnectedOnLeft, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected right", Button::ConnectedOnRight, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected top", Button::ConnectedOnTop, b, document));
|
||||
props.add (new ButtonConnectedEdgeProperty ("connected bottom", Button::ConnectedOnBottom, b, document));
|
||||
}
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
Button* const b = dynamic_cast<Button*> (comp);
|
||||
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("buttonText", b->getButtonText());
|
||||
e->setAttribute ("connectedEdges", b->getConnectedEdgeFlags());
|
||||
e->setAttribute ("needsCallback", needsButtonListener (b));
|
||||
e->setAttribute ("radioGroupId", b->getRadioGroupId());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
Button* const b = dynamic_cast<Button*> (comp);
|
||||
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
b->setButtonText (xml.getStringAttribute ("buttonText", b->getButtonText()));
|
||||
b->setConnectedEdges (xml.getIntAttribute ("connectedEdges", 0));
|
||||
setNeedsButtonListener (b, xml.getBoolAttribute ("needsCallback", true));
|
||||
b->setRadioGroupId (xml.getIntAttribute ("radioGroupId", 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
Button* const b = dynamic_cast<Button*> (component);
|
||||
|
||||
if (b->getButtonText() != b->getName())
|
||||
{
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setButtonText ("
|
||||
<< quotedString (b->getButtonText(), code.shouldUseTransMacro()) << ");\n";
|
||||
}
|
||||
|
||||
if (b->getConnectedEdgeFlags() != 0)
|
||||
{
|
||||
StringArray flags;
|
||||
|
||||
if (b->isConnectedOnLeft())
|
||||
flags.add ("juce::Button::ConnectedOnLeft");
|
||||
|
||||
if (b->isConnectedOnRight())
|
||||
flags.add ("juce::Button::ConnectedOnRight");
|
||||
|
||||
if (b->isConnectedOnTop())
|
||||
flags.add ("juce::Button::ConnectedOnTop");
|
||||
|
||||
if (b->isConnectedOnBottom())
|
||||
flags.add ("juce::Button::ConnectedOnBottom");
|
||||
|
||||
String s;
|
||||
s << memberVariableName << "->setConnectedEdges ("
|
||||
<< flags.joinIntoString (" | ") << ");\n";
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
if (b->getRadioGroupId() != 0)
|
||||
code.constructorCode << memberVariableName << "->setRadioGroupId ("
|
||||
<< b->getRadioGroupId() << ");\n";
|
||||
|
||||
if (needsButtonListener (component))
|
||||
code.constructorCode << memberVariableName << "->addListener (this);\n";
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (Component* component, GeneratedCode& code) override
|
||||
{
|
||||
ComponentTypeHandler::fillInGeneratedCode (component, code);
|
||||
|
||||
if (needsButtonListener (component))
|
||||
{
|
||||
String& callback = code.getCallbackCode ("public juce::Button::Listener",
|
||||
"void",
|
||||
"buttonClicked (juce::Button* buttonThatWasClicked)",
|
||||
true);
|
||||
|
||||
if (callback.isNotEmpty())
|
||||
callback << "else ";
|
||||
|
||||
const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component));
|
||||
const String userCodeComment ("UserButtonCode_" + memberVariableName);
|
||||
|
||||
callback
|
||||
<< "if (buttonThatWasClicked == " << memberVariableName << ".get())\n"
|
||||
<< "{\n //[" << userCodeComment << "] -- add your button handler code here..\n //[/" << userCodeComment << "]\n}\n";
|
||||
}
|
||||
}
|
||||
|
||||
static bool needsButtonListener (Component* button)
|
||||
{
|
||||
return button->getProperties().getWithDefault ("generateListenerCallback", true);
|
||||
}
|
||||
|
||||
static void setNeedsButtonListener (Component* button, const bool shouldDoCallback)
|
||||
{
|
||||
button->getProperties().set ("generateListenerCallback", shouldDoCallback);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class ButtonTextProperty : public ComponentTextProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonTextProperty (Button* button_, JucerDocument& doc)
|
||||
: ComponentTextProperty <Button> ("text", 100, false, button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ButtonTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change button text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getButtonText();
|
||||
}
|
||||
|
||||
private:
|
||||
class ButtonTextChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonTextChangeAction (Button* const comp, ComponentLayout& l, const String& newName_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newName (newName_)
|
||||
{
|
||||
oldName = comp->getButtonText();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setButtonText (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setButtonText (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonCallbackProperty : public ComponentBooleanProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonCallbackProperty (Button* b, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <Button> ("callback", "Generate ButtonListener", "Generate ButtonListener", b, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ButtonCallbackChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change button callback");
|
||||
}
|
||||
|
||||
bool getState() const { return needsButtonListener (component); }
|
||||
|
||||
private:
|
||||
class ButtonCallbackChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonCallbackChangeAction (Button* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = needsButtonListener (comp);
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
setNeedsButtonListener (getComponent(), newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
setNeedsButtonListener (getComponent(), oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonRadioGroupProperty : public ComponentTextProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonRadioGroupProperty (Button* const button_, JucerDocument& doc)
|
||||
: ComponentTextProperty <Button> ("radio group", 10, false, button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ButtonRadioGroupChangeAction (component, *document.getComponentLayout(), newText.getIntValue()),
|
||||
"Change radio group ID");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return String (component->getRadioGroupId());
|
||||
}
|
||||
|
||||
private:
|
||||
class ButtonRadioGroupChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonRadioGroupChangeAction (Button* const comp, ComponentLayout& l, const int newId_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
newId (newId_)
|
||||
{
|
||||
oldId = comp->getRadioGroupId();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRadioGroupId (newId);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRadioGroupId (oldId);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
int newId, oldId;
|
||||
};
|
||||
};
|
||||
|
||||
class ButtonConnectedEdgeProperty : public ComponentBooleanProperty <Button>
|
||||
{
|
||||
public:
|
||||
ButtonConnectedEdgeProperty (const String& name, const int flag_,
|
||||
Button* b, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <Button> (name, "Connected", "Connected", b, doc),
|
||||
flag (flag_)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ButtonConnectedChangeAction (component, *document.getComponentLayout(), flag, newState),
|
||||
"Change button connected edges");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return (component->getConnectedEdgeFlags() & flag) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
const int flag;
|
||||
|
||||
class ButtonConnectedChangeAction : public ComponentUndoableAction <Button>
|
||||
{
|
||||
public:
|
||||
ButtonConnectedChangeAction (Button* const comp, ComponentLayout& l, const int flag_, const bool newState_)
|
||||
: ComponentUndoableAction <Button> (comp, l),
|
||||
flag (flag_),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = ((comp->getConnectedEdgeFlags() & flag) != 0);
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (newState)
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag);
|
||||
else
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag);
|
||||
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
|
||||
if (oldState)
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() | flag);
|
||||
else
|
||||
getComponent()->setConnectedEdges (getComponent()->getConnectedEdgeFlags() & ~flag);
|
||||
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
const int flag;
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,446 +1,446 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ComboBoxHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
ComboBoxHandler()
|
||||
: ComponentTypeHandler ("Combo Box", "juce::ComboBox", typeid (ComboBox), 150, 24)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new ComboBox ("new combo box");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (auto* const c = dynamic_cast<ComboBox*> (comp))
|
||||
{
|
||||
if (auto* e = ComponentTypeHandler::createXmlFor (comp, layout))
|
||||
{
|
||||
e->setAttribute ("editable", c->isTextEditable());
|
||||
e->setAttribute ("layout", c->getJustificationType().getFlags());
|
||||
e->setAttribute ("items", c->getProperties() ["items"].toString());
|
||||
e->setAttribute ("textWhenNonSelected", c->getTextWhenNothingSelected());
|
||||
e->setAttribute ("textWhenNoItems", c->getTextWhenNoChoicesAvailable());
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
ComboBox defaultBox;
|
||||
|
||||
if (ComboBox* const c = dynamic_cast<ComboBox*> (comp))
|
||||
{
|
||||
c->setEditableText (xml.getBoolAttribute ("editable", defaultBox.isTextEditable()));
|
||||
c->setJustificationType (Justification (xml.getIntAttribute ("layout", defaultBox.getJustificationType().getFlags())));
|
||||
c->getProperties().set ("items", xml.getStringAttribute ("items", String()));
|
||||
c->setTextWhenNothingSelected (xml.getStringAttribute ("textWhenNonSelected", defaultBox.getTextWhenNothingSelected()));
|
||||
c->setTextWhenNoChoicesAvailable (xml.getStringAttribute ("textWhenNoItems", defaultBox.getTextWhenNoChoicesAvailable()));
|
||||
|
||||
updateItems (c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* c = dynamic_cast<ComboBox*> (component))
|
||||
{
|
||||
props.add (new ComboItemsProperty (c, document));
|
||||
props.add (new ComboEditableProperty (c, document));
|
||||
props.add (new ComboJustificationProperty (c, document));
|
||||
props.add (new ComboTextWhenNoneSelectedProperty (c, document));
|
||||
props.add (new ComboTextWhenNoItemsProperty (c, document));
|
||||
}
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
ComboBox* const c = dynamic_cast<ComboBox*> (component);
|
||||
|
||||
if (c == nullptr)
|
||||
{
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
String s;
|
||||
s << memberVariableName << "->setEditableText (" << CodeHelpers::boolLiteral (c->isTextEditable()) << ");\n"
|
||||
<< memberVariableName << "->setJustificationType (" << CodeHelpers::justificationToCode (c->getJustificationType()) << ");\n"
|
||||
<< memberVariableName << "->setTextWhenNothingSelected (" << quotedString (c->getTextWhenNothingSelected(), code.shouldUseTransMacro()) << ");\n"
|
||||
<< memberVariableName << "->setTextWhenNoChoicesAvailable (" << quotedString (c->getTextWhenNoChoicesAvailable(), code.shouldUseTransMacro()) << ");\n";
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (c->getProperties() ["items"].toString());
|
||||
int itemId = 1;
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
if (lines[i].trim().isEmpty())
|
||||
s << memberVariableName << "->addSeparator();\n";
|
||||
else
|
||||
s << memberVariableName << "->addItem ("
|
||||
<< quotedString (lines[i], code.shouldUseTransMacro()) << ", " << itemId++ << ");\n";
|
||||
}
|
||||
|
||||
if (needsCallback (component))
|
||||
s << memberVariableName << "->addListener (this);\n";
|
||||
|
||||
s << '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (Component* component, GeneratedCode& code) override
|
||||
{
|
||||
ComponentTypeHandler::fillInGeneratedCode (component, code);
|
||||
|
||||
if (needsCallback (component))
|
||||
{
|
||||
String& callback = code.getCallbackCode ("public juce::ComboBox::Listener",
|
||||
"void",
|
||||
"comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged)",
|
||||
true);
|
||||
|
||||
if (callback.trim().isNotEmpty())
|
||||
callback << "else ";
|
||||
|
||||
const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component));
|
||||
const String userCodeComment ("UserComboBoxCode_" + memberVariableName);
|
||||
|
||||
callback
|
||||
<< "if (comboBoxThatHasChanged == " << memberVariableName << ".get())\n"
|
||||
<< "{\n //[" << userCodeComment << "] -- add your combo box handling code here..\n //[/" << userCodeComment << "]\n}\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void updateItems (ComboBox* c)
|
||||
{
|
||||
StringArray lines;
|
||||
lines.addLines (c->getProperties() ["items"].toString());
|
||||
|
||||
c->clear();
|
||||
int itemId = 1;
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
if (lines[i].trim().isEmpty())
|
||||
c->addSeparator();
|
||||
else
|
||||
c->addItem (lines[i], itemId++);
|
||||
}
|
||||
}
|
||||
|
||||
static bool needsCallback (Component*)
|
||||
{
|
||||
return true; // xxx should be configurable
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboEditableProperty : public ComponentBooleanProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboEditableProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <ComboBox> ("editable", "Text is editable", "Text is editable", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ComboEditableChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change combo box editability");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return component->isTextEditable();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboEditableChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboEditableChangeAction (ComboBox* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isTextEditable();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setEditableText (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setEditableText (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboJustificationProperty : public JustificationProperty
|
||||
{
|
||||
public:
|
||||
ComboJustificationProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: JustificationProperty ("text layout", false),
|
||||
component (comp),
|
||||
document (doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setJustification (Justification newJustification)
|
||||
{
|
||||
document.perform (new ComboJustifyChangeAction (component, *document.getComponentLayout(), newJustification),
|
||||
"Change combo box justification");
|
||||
}
|
||||
|
||||
Justification getJustification() const { return component->getJustificationType(); }
|
||||
|
||||
private:
|
||||
ComboBox* const component;
|
||||
JucerDocument& document;
|
||||
|
||||
class ComboJustifyChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboJustifyChangeAction (ComboBox* const comp, ComponentLayout& l, Justification newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_),
|
||||
oldState (comp->getJustificationType())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setJustificationType (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setJustificationType (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
Justification newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboItemsProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboItemsProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("items", 10000, true, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboItemsChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box items");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getProperties() ["items"];
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboItemsChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboItemsChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getProperties() ["items"];
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->getProperties().set ("items", newState);
|
||||
ComboBoxHandler::updateItems (getComponent());
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->getProperties().set ("items", oldState);
|
||||
ComboBoxHandler::updateItems (getComponent());
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboTextWhenNoneSelectedProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboTextWhenNoneSelectedProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("text when none selected", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboNonSelTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box text when nothing selected");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getTextWhenNothingSelected();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboNonSelTextChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboNonSelTextChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getTextWhenNothingSelected();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNothingSelected (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNothingSelected (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboTextWhenNoItemsProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboTextWhenNoItemsProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("text when no items", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboNoItemTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box 'no items' text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getTextWhenNoChoicesAvailable();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboNoItemTextChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboNoItemTextChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getTextWhenNoChoicesAvailable();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNoChoicesAvailable (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNoChoicesAvailable (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ComboBoxHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
ComboBoxHandler()
|
||||
: ComponentTypeHandler ("Combo Box", "juce::ComboBox", typeid (ComboBox), 150, 24)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new ComboBox ("new combo box");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (auto* const c = dynamic_cast<ComboBox*> (comp))
|
||||
{
|
||||
if (auto* e = ComponentTypeHandler::createXmlFor (comp, layout))
|
||||
{
|
||||
e->setAttribute ("editable", c->isTextEditable());
|
||||
e->setAttribute ("layout", c->getJustificationType().getFlags());
|
||||
e->setAttribute ("items", c->getProperties() ["items"].toString());
|
||||
e->setAttribute ("textWhenNonSelected", c->getTextWhenNothingSelected());
|
||||
e->setAttribute ("textWhenNoItems", c->getTextWhenNoChoicesAvailable());
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
ComboBox defaultBox;
|
||||
|
||||
if (ComboBox* const c = dynamic_cast<ComboBox*> (comp))
|
||||
{
|
||||
c->setEditableText (xml.getBoolAttribute ("editable", defaultBox.isTextEditable()));
|
||||
c->setJustificationType (Justification (xml.getIntAttribute ("layout", defaultBox.getJustificationType().getFlags())));
|
||||
c->getProperties().set ("items", xml.getStringAttribute ("items", String()));
|
||||
c->setTextWhenNothingSelected (xml.getStringAttribute ("textWhenNonSelected", defaultBox.getTextWhenNothingSelected()));
|
||||
c->setTextWhenNoChoicesAvailable (xml.getStringAttribute ("textWhenNoItems", defaultBox.getTextWhenNoChoicesAvailable()));
|
||||
|
||||
updateItems (c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* c = dynamic_cast<ComboBox*> (component))
|
||||
{
|
||||
props.add (new ComboItemsProperty (c, document));
|
||||
props.add (new ComboEditableProperty (c, document));
|
||||
props.add (new ComboJustificationProperty (c, document));
|
||||
props.add (new ComboTextWhenNoneSelectedProperty (c, document));
|
||||
props.add (new ComboTextWhenNoItemsProperty (c, document));
|
||||
}
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
ComboBox* const c = dynamic_cast<ComboBox*> (component);
|
||||
|
||||
if (c == nullptr)
|
||||
{
|
||||
jassertfalse;
|
||||
return;
|
||||
}
|
||||
|
||||
String s;
|
||||
s << memberVariableName << "->setEditableText (" << CodeHelpers::boolLiteral (c->isTextEditable()) << ");\n"
|
||||
<< memberVariableName << "->setJustificationType (" << CodeHelpers::justificationToCode (c->getJustificationType()) << ");\n"
|
||||
<< memberVariableName << "->setTextWhenNothingSelected (" << quotedString (c->getTextWhenNothingSelected(), code.shouldUseTransMacro()) << ");\n"
|
||||
<< memberVariableName << "->setTextWhenNoChoicesAvailable (" << quotedString (c->getTextWhenNoChoicesAvailable(), code.shouldUseTransMacro()) << ");\n";
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (c->getProperties() ["items"].toString());
|
||||
int itemId = 1;
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
if (lines[i].trim().isEmpty())
|
||||
s << memberVariableName << "->addSeparator();\n";
|
||||
else
|
||||
s << memberVariableName << "->addItem ("
|
||||
<< quotedString (lines[i], code.shouldUseTransMacro()) << ", " << itemId++ << ");\n";
|
||||
}
|
||||
|
||||
if (needsCallback (component))
|
||||
s << memberVariableName << "->addListener (this);\n";
|
||||
|
||||
s << '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
void fillInGeneratedCode (Component* component, GeneratedCode& code) override
|
||||
{
|
||||
ComponentTypeHandler::fillInGeneratedCode (component, code);
|
||||
|
||||
if (needsCallback (component))
|
||||
{
|
||||
String& callback = code.getCallbackCode ("public juce::ComboBox::Listener",
|
||||
"void",
|
||||
"comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged)",
|
||||
true);
|
||||
|
||||
if (callback.trim().isNotEmpty())
|
||||
callback << "else ";
|
||||
|
||||
const String memberVariableName (code.document->getComponentLayout()->getComponentMemberVariableName (component));
|
||||
const String userCodeComment ("UserComboBoxCode_" + memberVariableName);
|
||||
|
||||
callback
|
||||
<< "if (comboBoxThatHasChanged == " << memberVariableName << ".get())\n"
|
||||
<< "{\n //[" << userCodeComment << "] -- add your combo box handling code here..\n //[/" << userCodeComment << "]\n}\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void updateItems (ComboBox* c)
|
||||
{
|
||||
StringArray lines;
|
||||
lines.addLines (c->getProperties() ["items"].toString());
|
||||
|
||||
c->clear();
|
||||
int itemId = 1;
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
if (lines[i].trim().isEmpty())
|
||||
c->addSeparator();
|
||||
else
|
||||
c->addItem (lines[i], itemId++);
|
||||
}
|
||||
}
|
||||
|
||||
static bool needsCallback (Component*)
|
||||
{
|
||||
return true; // xxx should be configurable
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboEditableProperty : public ComponentBooleanProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboEditableProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <ComboBox> ("editable", "Text is editable", "Text is editable", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ComboEditableChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change combo box editability");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return component->isTextEditable();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboEditableChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboEditableChangeAction (ComboBox* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isTextEditable();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setEditableText (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setEditableText (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboJustificationProperty : public JustificationProperty
|
||||
{
|
||||
public:
|
||||
ComboJustificationProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: JustificationProperty ("text layout", false),
|
||||
component (comp),
|
||||
document (doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setJustification (Justification newJustification)
|
||||
{
|
||||
document.perform (new ComboJustifyChangeAction (component, *document.getComponentLayout(), newJustification),
|
||||
"Change combo box justification");
|
||||
}
|
||||
|
||||
Justification getJustification() const { return component->getJustificationType(); }
|
||||
|
||||
private:
|
||||
ComboBox* const component;
|
||||
JucerDocument& document;
|
||||
|
||||
class ComboJustifyChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboJustifyChangeAction (ComboBox* const comp, ComponentLayout& l, Justification newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_),
|
||||
oldState (comp->getJustificationType())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setJustificationType (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setJustificationType (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
Justification newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboItemsProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboItemsProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("items", 10000, true, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboItemsChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box items");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getProperties() ["items"];
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboItemsChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboItemsChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getProperties() ["items"];
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->getProperties().set ("items", newState);
|
||||
ComboBoxHandler::updateItems (getComponent());
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->getProperties().set ("items", oldState);
|
||||
ComboBoxHandler::updateItems (getComponent());
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboTextWhenNoneSelectedProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboTextWhenNoneSelectedProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("text when none selected", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboNonSelTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box text when nothing selected");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getTextWhenNothingSelected();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboNonSelTextChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboNonSelTextChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getTextWhenNothingSelected();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNothingSelected (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNothingSelected (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComboTextWhenNoItemsProperty : public ComponentTextProperty <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboTextWhenNoItemsProperty (ComboBox* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <ComboBox> ("text when no items", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ComboNoItemTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change combo box 'no items' text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getTextWhenNoChoicesAvailable();
|
||||
}
|
||||
|
||||
private:
|
||||
class ComboNoItemTextChangeAction : public ComponentUndoableAction <ComboBox>
|
||||
{
|
||||
public:
|
||||
ComboNoItemTextChangeAction (ComboBox* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <ComboBox> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getTextWhenNoChoicesAvailable();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNoChoicesAvailable (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextWhenNoChoicesAvailable (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,178 +1,178 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jucer_ComponentTypeHandler.h"
|
||||
#include "jucer_ComponentUndoableAction.h"
|
||||
#include "../Properties/jucer_ComponentTextProperty.h"
|
||||
|
||||
//==============================================================================
|
||||
class ComponentNameProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentNameProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("name", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompNameChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getName();
|
||||
}
|
||||
|
||||
private:
|
||||
class CompNameChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompNameChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (comp->getName())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setName (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setName (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComponentMemberNameProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentMemberNameProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("member name", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompMemberNameChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component member name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return document.getComponentLayout()->getComponentMemberVariableName (component);
|
||||
}
|
||||
|
||||
private:
|
||||
class CompMemberNameChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompMemberNameChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (layout.getComponentMemberVariableName (comp))
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentMemberVariableName (getComponent(), newName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentMemberVariableName (getComponent(), oldName);
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ComponentVirtualClassProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentVirtualClassProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("virtual class", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompVirtualClassChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component virtual class name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return document.getComponentLayout()->getComponentVirtualClassName (component);
|
||||
}
|
||||
|
||||
private:
|
||||
class CompVirtualClassChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompVirtualClassChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (layout.getComponentVirtualClassName (comp))
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentVirtualClassName (getComponent(), newName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentVirtualClassName (getComponent(), oldName);
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jucer_ComponentTypeHandler.h"
|
||||
#include "jucer_ComponentUndoableAction.h"
|
||||
#include "../Properties/jucer_ComponentTextProperty.h"
|
||||
|
||||
//==============================================================================
|
||||
class ComponentNameProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentNameProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("name", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompNameChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getName();
|
||||
}
|
||||
|
||||
private:
|
||||
class CompNameChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompNameChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (comp->getName())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setName (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setName (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComponentMemberNameProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentMemberNameProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("member name", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompMemberNameChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component member name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return document.getComponentLayout()->getComponentMemberVariableName (component);
|
||||
}
|
||||
|
||||
private:
|
||||
class CompMemberNameChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompMemberNameChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (layout.getComponentMemberVariableName (comp))
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentMemberVariableName (getComponent(), newName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentMemberVariableName (getComponent(), oldName);
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ComponentVirtualClassProperty : public ComponentTextProperty <Component>
|
||||
{
|
||||
public:
|
||||
ComponentVirtualClassProperty (Component* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <Component> ("virtual class", 40, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new CompVirtualClassChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change component virtual class name");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return document.getComponentLayout()->getComponentVirtualClassName (component);
|
||||
}
|
||||
|
||||
private:
|
||||
class CompVirtualClassChangeAction : public ComponentUndoableAction <Component>
|
||||
{
|
||||
public:
|
||||
CompVirtualClassChangeAction (Component* const comp, ComponentLayout& l, const String& nm)
|
||||
: ComponentUndoableAction <Component> (comp, l),
|
||||
newName (nm), oldName (layout.getComponentVirtualClassName (comp))
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentVirtualClassName (getComponent(), newName);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
layout.setComponentVirtualClassName (getComponent(), oldName);
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,147 +1,147 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class ComponentOverlayComponent;
|
||||
class ComponentLayout;
|
||||
#include "../jucer_GeneratedCode.h"
|
||||
#include "../UI/jucer_RelativePositionedRectangle.h"
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Base class for handlers that can understand the properties of all the component classes.
|
||||
*/
|
||||
class ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
ComponentTypeHandler (const String& typeDescription_,
|
||||
const String& className_,
|
||||
const std::type_info& componentClass,
|
||||
const int defaultWidth_,
|
||||
const int defaultHeight_);
|
||||
|
||||
virtual ~ComponentTypeHandler() {}
|
||||
|
||||
//==============================================================================
|
||||
virtual bool canHandle (Component& component) const;
|
||||
|
||||
static ComponentTypeHandler* getHandlerFor (Component& component);
|
||||
|
||||
//==============================================================================
|
||||
virtual String getXmlTagName() const noexcept
|
||||
{
|
||||
if (className.startsWith ("juce::"))
|
||||
return className.substring (6).toUpperCase();
|
||||
|
||||
return className.toUpperCase();
|
||||
}
|
||||
|
||||
static ComponentTypeHandler* getHandlerForXmlTag (const String& tagName);
|
||||
|
||||
virtual XmlElement* createXmlFor (Component* component, const ComponentLayout* layout);
|
||||
virtual bool restoreFromXml (const XmlElement& xml, Component* component, const ComponentLayout* layout);
|
||||
|
||||
virtual void getEditableProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props,
|
||||
bool multipleSelected);
|
||||
|
||||
virtual void addPropertiesToPropertyPanel (Component* component,
|
||||
JucerDocument& document,
|
||||
PropertyPanel& panel,
|
||||
bool multipleSelected);
|
||||
|
||||
|
||||
void registerEditableColour (int colourId,
|
||||
const String& colourIdCode,
|
||||
const String& colourName,
|
||||
const String& xmlTagName);
|
||||
|
||||
#define registerColour(colourId, colourName, xmlTagName) \
|
||||
registerEditableColour (colourId, #colourId, colourName, xmlTagName)
|
||||
|
||||
void addColourProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props);
|
||||
|
||||
String getColourIntialisationCode (Component* component,
|
||||
const String& objectName);
|
||||
|
||||
//==============================================================================
|
||||
virtual Component* createNewComponent (JucerDocument*) = 0;
|
||||
|
||||
virtual Component* createCopyOf (JucerDocument*, Component& existing);
|
||||
|
||||
virtual ComponentOverlayComponent* createOverlayComponent (Component* child, ComponentLayout& layout);
|
||||
|
||||
virtual void showPopupMenu (Component* component,
|
||||
ComponentLayout& layout);
|
||||
|
||||
//==============================================================================
|
||||
// Code-generation methods:
|
||||
|
||||
virtual void fillInGeneratedCode (Component* component, GeneratedCode& code);
|
||||
|
||||
virtual void fillInMemberVariableDeclarations (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual void fillInResizeCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual void fillInCreationCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual String getCreationParameters (GeneratedCode&, Component*);
|
||||
virtual void fillInDeletionCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
|
||||
//==============================================================================
|
||||
const String& getTypeName() const noexcept { return typeName; }
|
||||
virtual String getClassName (Component*) const { return className; }
|
||||
|
||||
int getDefaultWidth() const noexcept { return defaultWidth; }
|
||||
int getDefaultHeight() const noexcept { return defaultHeight; }
|
||||
|
||||
static int64 getComponentId (Component* comp);
|
||||
static void setComponentId (Component* comp, const int64 newID);
|
||||
|
||||
static RelativePositionedRectangle getComponentPosition (Component* comp);
|
||||
static void setComponentPosition (Component* comp,
|
||||
const RelativePositionedRectangle& newPos,
|
||||
const ComponentLayout* layout);
|
||||
|
||||
static JucerDocument* findParentDocument (Component* component);
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
const String typeName, className, virtualClass, componentClassRawName;
|
||||
int defaultWidth, defaultHeight;
|
||||
|
||||
struct ComponentColourInfo
|
||||
{
|
||||
int colourId;
|
||||
String colourIdCode, colourName, xmlTagName;
|
||||
};
|
||||
|
||||
OwnedArray<ComponentColourInfo> colours;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (ComponentTypeHandler)
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class ComponentOverlayComponent;
|
||||
class ComponentLayout;
|
||||
#include "../jucer_GeneratedCode.h"
|
||||
#include "../UI/jucer_RelativePositionedRectangle.h"
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Base class for handlers that can understand the properties of all the component classes.
|
||||
*/
|
||||
class ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
ComponentTypeHandler (const String& typeDescription_,
|
||||
const String& className_,
|
||||
const std::type_info& componentClass,
|
||||
const int defaultWidth_,
|
||||
const int defaultHeight_);
|
||||
|
||||
virtual ~ComponentTypeHandler() {}
|
||||
|
||||
//==============================================================================
|
||||
virtual bool canHandle (Component& component) const;
|
||||
|
||||
static ComponentTypeHandler* getHandlerFor (Component& component);
|
||||
|
||||
//==============================================================================
|
||||
virtual String getXmlTagName() const noexcept
|
||||
{
|
||||
if (className.startsWith ("juce::"))
|
||||
return className.substring (6).toUpperCase();
|
||||
|
||||
return className.toUpperCase();
|
||||
}
|
||||
|
||||
static ComponentTypeHandler* getHandlerForXmlTag (const String& tagName);
|
||||
|
||||
virtual XmlElement* createXmlFor (Component* component, const ComponentLayout* layout);
|
||||
virtual bool restoreFromXml (const XmlElement& xml, Component* component, const ComponentLayout* layout);
|
||||
|
||||
virtual void getEditableProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props,
|
||||
bool multipleSelected);
|
||||
|
||||
virtual void addPropertiesToPropertyPanel (Component* component,
|
||||
JucerDocument& document,
|
||||
PropertyPanel& panel,
|
||||
bool multipleSelected);
|
||||
|
||||
|
||||
void registerEditableColour (int colourId,
|
||||
const String& colourIdCode,
|
||||
const String& colourName,
|
||||
const String& xmlTagName);
|
||||
|
||||
#define registerColour(colourId, colourName, xmlTagName) \
|
||||
registerEditableColour (colourId, #colourId, colourName, xmlTagName)
|
||||
|
||||
void addColourProperties (Component* component,
|
||||
JucerDocument& document,
|
||||
Array<PropertyComponent*>& props);
|
||||
|
||||
String getColourIntialisationCode (Component* component,
|
||||
const String& objectName);
|
||||
|
||||
//==============================================================================
|
||||
virtual Component* createNewComponent (JucerDocument*) = 0;
|
||||
|
||||
virtual Component* createCopyOf (JucerDocument*, Component& existing);
|
||||
|
||||
virtual ComponentOverlayComponent* createOverlayComponent (Component* child, ComponentLayout& layout);
|
||||
|
||||
virtual void showPopupMenu (Component* component,
|
||||
ComponentLayout& layout);
|
||||
|
||||
//==============================================================================
|
||||
// Code-generation methods:
|
||||
|
||||
virtual void fillInGeneratedCode (Component* component, GeneratedCode& code);
|
||||
|
||||
virtual void fillInMemberVariableDeclarations (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual void fillInResizeCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual void fillInCreationCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
virtual String getCreationParameters (GeneratedCode&, Component*);
|
||||
virtual void fillInDeletionCode (GeneratedCode&, Component*, const String& memberVariableName);
|
||||
|
||||
//==============================================================================
|
||||
const String& getTypeName() const noexcept { return typeName; }
|
||||
virtual String getClassName (Component*) const { return className; }
|
||||
|
||||
int getDefaultWidth() const noexcept { return defaultWidth; }
|
||||
int getDefaultHeight() const noexcept { return defaultHeight; }
|
||||
|
||||
static int64 getComponentId (Component* comp);
|
||||
static void setComponentId (Component* comp, const int64 newID);
|
||||
|
||||
static RelativePositionedRectangle getComponentPosition (Component* comp);
|
||||
static void setComponentPosition (Component* comp,
|
||||
const RelativePositionedRectangle& newPos,
|
||||
const ComponentLayout* layout);
|
||||
|
||||
static JucerDocument* findParentDocument (Component* component);
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
const String typeName, className, virtualClass, componentClassRawName;
|
||||
int defaultWidth, defaultHeight;
|
||||
|
||||
struct ComponentColourInfo
|
||||
{
|
||||
int colourId;
|
||||
String colourIdCode, colourName, xmlTagName;
|
||||
};
|
||||
|
||||
OwnedArray<ComponentColourInfo> colours;
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE (ComponentTypeHandler)
|
||||
};
|
||||
|
@ -1,75 +1,75 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../UI/jucer_JucerDocumentEditor.h"
|
||||
|
||||
//==============================================================================
|
||||
template <class ComponentType>
|
||||
class ComponentUndoableAction : public UndoableAction
|
||||
{
|
||||
public:
|
||||
ComponentUndoableAction (ComponentType* const comp,
|
||||
ComponentLayout& layout_)
|
||||
: layout (layout_),
|
||||
componentIndex (layout_.indexOfComponent (comp))
|
||||
{
|
||||
jassert (comp != nullptr);
|
||||
jassert (componentIndex >= 0);
|
||||
}
|
||||
|
||||
ComponentType* getComponent() const
|
||||
{
|
||||
ComponentType* const c = dynamic_cast<ComponentType*> (layout.getComponent (componentIndex));
|
||||
jassert (c != nullptr);
|
||||
return c;
|
||||
}
|
||||
|
||||
int getSizeInUnits() { return 2; }
|
||||
|
||||
protected:
|
||||
ComponentLayout& layout;
|
||||
const int componentIndex;
|
||||
|
||||
void changed() const
|
||||
{
|
||||
jassert (layout.getDocument() != nullptr);
|
||||
layout.getDocument()->changed();
|
||||
}
|
||||
|
||||
void showCorrectTab() const
|
||||
{
|
||||
if (JucerDocumentEditor* const ed = JucerDocumentEditor::getActiveDocumentHolder())
|
||||
ed->showLayout();
|
||||
|
||||
if (layout.getSelectedSet().getNumSelected() == 0)
|
||||
if (ComponentType* const c = dynamic_cast<ComponentType*> (layout.getComponent (componentIndex)))
|
||||
layout.getSelectedSet().selectOnly (getComponent());
|
||||
}
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentUndoableAction)
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../UI/jucer_JucerDocumentEditor.h"
|
||||
|
||||
//==============================================================================
|
||||
template <class ComponentType>
|
||||
class ComponentUndoableAction : public UndoableAction
|
||||
{
|
||||
public:
|
||||
ComponentUndoableAction (ComponentType* const comp,
|
||||
ComponentLayout& layout_)
|
||||
: layout (layout_),
|
||||
componentIndex (layout_.indexOfComponent (comp))
|
||||
{
|
||||
jassert (comp != nullptr);
|
||||
jassert (componentIndex >= 0);
|
||||
}
|
||||
|
||||
ComponentType* getComponent() const
|
||||
{
|
||||
ComponentType* const c = dynamic_cast<ComponentType*> (layout.getComponent (componentIndex));
|
||||
jassert (c != nullptr);
|
||||
return c;
|
||||
}
|
||||
|
||||
int getSizeInUnits() { return 2; }
|
||||
|
||||
protected:
|
||||
ComponentLayout& layout;
|
||||
const int componentIndex;
|
||||
|
||||
void changed() const
|
||||
{
|
||||
jassert (layout.getDocument() != nullptr);
|
||||
layout.getDocument()->changed();
|
||||
}
|
||||
|
||||
void showCorrectTab() const
|
||||
{
|
||||
if (JucerDocumentEditor* const ed = JucerDocumentEditor::getActiveDocumentHolder())
|
||||
ed->showLayout();
|
||||
|
||||
if (layout.getSelectedSet().getNumSelected() == 0)
|
||||
if (ComponentType* const c = dynamic_cast<ComponentType*> (layout.getComponent (componentIndex)))
|
||||
layout.getSelectedSet().selectOnly (getComponent());
|
||||
}
|
||||
|
||||
private:
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentUndoableAction)
|
||||
};
|
||||
|
@ -1,241 +1,241 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class GenericComponent : public Component
|
||||
{
|
||||
public:
|
||||
GenericComponent()
|
||||
: Component ("new component"),
|
||||
actualClassName ("juce::Component")
|
||||
{
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (Colours::white.withAlpha (0.25f));
|
||||
|
||||
g.setColour (Colours::black.withAlpha (0.5f));
|
||||
g.drawRect (getLocalBounds());
|
||||
g.drawLine (0.0f, 0.0f, (float) getWidth(), (float) getHeight());
|
||||
g.drawLine (0.0f, (float) getHeight(), (float) getWidth(), 0.0f);
|
||||
|
||||
g.setFont (14.0f);
|
||||
g.drawText (actualClassName, 0, 0, getWidth(), getHeight() / 2, Justification::centred, true);
|
||||
}
|
||||
|
||||
void setClassName (const String& newName)
|
||||
{
|
||||
if (actualClassName != newName)
|
||||
{
|
||||
actualClassName = newName;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void setParams (const String& newParams)
|
||||
{
|
||||
if (constructorParams != newParams)
|
||||
{
|
||||
constructorParams = newParams;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
String actualClassName, constructorParams;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class GenericComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
GenericComponentHandler()
|
||||
: ComponentTypeHandler ("Generic Component", "GenericComponent", typeid (GenericComponent), 150, 24)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new GenericComponent();
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("class", ((GenericComponent*) comp)->actualClassName);
|
||||
e->setAttribute ("params", ((GenericComponent*) comp)->constructorParams);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
((GenericComponent*) comp)->actualClassName = xml.getStringAttribute ("class", "juce::Component");
|
||||
((GenericComponent*) comp)->constructorParams = xml.getStringAttribute ("params", String());
|
||||
return true;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
props.add (new GenericCompClassProperty (dynamic_cast<GenericComponent*> (component), document));
|
||||
props.add (new GenericCompParamsProperty (dynamic_cast<GenericComponent*> (component), document));
|
||||
}
|
||||
|
||||
String getClassName (Component* comp) const override
|
||||
{
|
||||
return static_cast<GenericComponent*> (comp)->actualClassName;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* comp) override
|
||||
{
|
||||
return static_cast<GenericComponent*> (comp)->constructorParams;
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (component->getName().isNotEmpty())
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setName ("
|
||||
<< quotedString (component->getName(), false)
|
||||
<< ");\n\n";
|
||||
else
|
||||
code.constructorCode << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompClassProperty : public ComponentTextProperty <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompClassProperty (GenericComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GenericComponent> ("class", 300, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GenericCompClassChangeAction (component, *document.getComponentLayout(),
|
||||
build_tools::makeValidIdentifier (newText, false, false, true)),
|
||||
"Change generic component class");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->actualClassName;
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompClassChangeAction : public ComponentUndoableAction <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompClassChangeAction (GenericComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <GenericComponent> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->actualClassName;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setClassName (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setClassName (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
class GenericCompParamsProperty : public ComponentTextProperty <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompParamsProperty (GenericComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GenericComponent> ("constructor params", 1024, true, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GenericCompParamsChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change generic component class");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->constructorParams;
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompParamsChangeAction : public ComponentUndoableAction <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompParamsChangeAction (GenericComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <GenericComponent> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->constructorParams;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setParams (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setParams (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class GenericComponent : public Component
|
||||
{
|
||||
public:
|
||||
GenericComponent()
|
||||
: Component ("new component"),
|
||||
actualClassName ("juce::Component")
|
||||
{
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (Colours::white.withAlpha (0.25f));
|
||||
|
||||
g.setColour (Colours::black.withAlpha (0.5f));
|
||||
g.drawRect (getLocalBounds());
|
||||
g.drawLine (0.0f, 0.0f, (float) getWidth(), (float) getHeight());
|
||||
g.drawLine (0.0f, (float) getHeight(), (float) getWidth(), 0.0f);
|
||||
|
||||
g.setFont (14.0f);
|
||||
g.drawText (actualClassName, 0, 0, getWidth(), getHeight() / 2, Justification::centred, true);
|
||||
}
|
||||
|
||||
void setClassName (const String& newName)
|
||||
{
|
||||
if (actualClassName != newName)
|
||||
{
|
||||
actualClassName = newName;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void setParams (const String& newParams)
|
||||
{
|
||||
if (constructorParams != newParams)
|
||||
{
|
||||
constructorParams = newParams;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
String actualClassName, constructorParams;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class GenericComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
GenericComponentHandler()
|
||||
: ComponentTypeHandler ("Generic Component", "GenericComponent", typeid (GenericComponent), 150, 24)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new GenericComponent();
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("class", ((GenericComponent*) comp)->actualClassName);
|
||||
e->setAttribute ("params", ((GenericComponent*) comp)->constructorParams);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
((GenericComponent*) comp)->actualClassName = xml.getStringAttribute ("class", "juce::Component");
|
||||
((GenericComponent*) comp)->constructorParams = xml.getStringAttribute ("params", String());
|
||||
return true;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
props.add (new GenericCompClassProperty (dynamic_cast<GenericComponent*> (component), document));
|
||||
props.add (new GenericCompParamsProperty (dynamic_cast<GenericComponent*> (component), document));
|
||||
}
|
||||
|
||||
String getClassName (Component* comp) const override
|
||||
{
|
||||
return static_cast<GenericComponent*> (comp)->actualClassName;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* comp) override
|
||||
{
|
||||
return static_cast<GenericComponent*> (comp)->constructorParams;
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (component->getName().isNotEmpty())
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setName ("
|
||||
<< quotedString (component->getName(), false)
|
||||
<< ");\n\n";
|
||||
else
|
||||
code.constructorCode << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompClassProperty : public ComponentTextProperty <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompClassProperty (GenericComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GenericComponent> ("class", 300, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GenericCompClassChangeAction (component, *document.getComponentLayout(),
|
||||
build_tools::makeValidIdentifier (newText, false, false, true)),
|
||||
"Change generic component class");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->actualClassName;
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompClassChangeAction : public ComponentUndoableAction <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompClassChangeAction (GenericComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <GenericComponent> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->actualClassName;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setClassName (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setClassName (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
class GenericCompParamsProperty : public ComponentTextProperty <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompParamsProperty (GenericComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GenericComponent> ("constructor params", 1024, true, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GenericCompParamsChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change generic component class");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->constructorParams;
|
||||
}
|
||||
|
||||
private:
|
||||
class GenericCompParamsChangeAction : public ComponentUndoableAction <GenericComponent>
|
||||
{
|
||||
public:
|
||||
GenericCompParamsChangeAction (GenericComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <GenericComponent> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->constructorParams;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setParams (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setParams (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,237 +1,237 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class GroupComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
GroupComponentHandler()
|
||||
: ComponentTypeHandler ("Group Box", "juce::GroupComponent", typeid (GroupComponent), 200, 150)
|
||||
{
|
||||
registerColour (juce::GroupComponent::outlineColourId, "outline", "outlinecol");
|
||||
registerColour (juce::GroupComponent::textColourId, "text", "textcol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new GroupComponent ("new group", "group");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
GroupComponent* const g = (GroupComponent*) comp;
|
||||
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("title", g->getText());
|
||||
|
||||
GroupComponent defaultComp;
|
||||
|
||||
if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags())
|
||||
e->setAttribute ("textpos", g->getTextLabelPosition().getFlags());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
GroupComponent* const g = (GroupComponent*) comp;
|
||||
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
g->setText (xml.getStringAttribute ("title", g->getText()));
|
||||
g->setTextLabelPosition (Justification (xml.getIntAttribute ("textpos", g->getTextLabelPosition().getFlags())));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode& code, Component* component) override
|
||||
{
|
||||
GroupComponent* g = dynamic_cast<GroupComponent*> (component);
|
||||
|
||||
return quotedString (component->getName(), false)
|
||||
+ ",\n"
|
||||
+ quotedString (g->getText(), code.shouldUseTransMacro());
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
GroupComponent* const g = dynamic_cast<GroupComponent*> (component);
|
||||
|
||||
String s;
|
||||
|
||||
GroupComponent defaultComp;
|
||||
|
||||
if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags())
|
||||
{
|
||||
s << memberVariableName << "->setTextLabelPosition ("
|
||||
<< CodeHelpers::justificationToCode (g->getTextLabelPosition())
|
||||
<< ");\n";
|
||||
}
|
||||
|
||||
s << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* gc = dynamic_cast<GroupComponent*> (component))
|
||||
{
|
||||
props.add (new GroupTitleProperty (gc, document));
|
||||
props.add (new GroupJustificationProperty (gc, document));
|
||||
}
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class GroupTitleProperty : public ComponentTextProperty <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupTitleProperty (GroupComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GroupComponent> ("text", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GroupTitleChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change group title");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getText();
|
||||
}
|
||||
|
||||
private:
|
||||
class GroupTitleChangeAction : public ComponentUndoableAction <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupTitleChangeAction (GroupComponent* const comp, ComponentLayout& l, const String& newName_)
|
||||
: ComponentUndoableAction <GroupComponent> (comp, l),
|
||||
newName (newName_)
|
||||
{
|
||||
oldName = comp->getText();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class GroupJustificationProperty : public JustificationProperty,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
GroupJustificationProperty (GroupComponent* const group_, JucerDocument& doc)
|
||||
: JustificationProperty ("layout", true),
|
||||
group (group_),
|
||||
document (doc)
|
||||
{
|
||||
document.addChangeListener (this);
|
||||
}
|
||||
|
||||
~GroupJustificationProperty() override
|
||||
{
|
||||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setJustification (Justification newJustification) override
|
||||
{
|
||||
document.perform (new GroupJustifyChangeAction (group, *document.getComponentLayout(), newJustification),
|
||||
"Change text label position");
|
||||
}
|
||||
|
||||
Justification getJustification() const override
|
||||
{
|
||||
return group->getTextLabelPosition();
|
||||
}
|
||||
|
||||
private:
|
||||
void changeListenerCallback (ChangeBroadcaster*) override { refresh(); }
|
||||
|
||||
GroupComponent* const group;
|
||||
JucerDocument& document;
|
||||
|
||||
class GroupJustifyChangeAction : public ComponentUndoableAction <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupJustifyChangeAction (GroupComponent* const comp, ComponentLayout& l, Justification newState_)
|
||||
: ComponentUndoableAction <GroupComponent> (comp, l),
|
||||
newState (newState_),
|
||||
oldState (comp->getTextLabelPosition())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextLabelPosition (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextLabelPosition (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
Justification newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class GroupComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
GroupComponentHandler()
|
||||
: ComponentTypeHandler ("Group Box", "juce::GroupComponent", typeid (GroupComponent), 200, 150)
|
||||
{
|
||||
registerColour (juce::GroupComponent::outlineColourId, "outline", "outlinecol");
|
||||
registerColour (juce::GroupComponent::textColourId, "text", "textcol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new GroupComponent ("new group", "group");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
GroupComponent* const g = (GroupComponent*) comp;
|
||||
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("title", g->getText());
|
||||
|
||||
GroupComponent defaultComp;
|
||||
|
||||
if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags())
|
||||
e->setAttribute ("textpos", g->getTextLabelPosition().getFlags());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
GroupComponent* const g = (GroupComponent*) comp;
|
||||
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
g->setText (xml.getStringAttribute ("title", g->getText()));
|
||||
g->setTextLabelPosition (Justification (xml.getIntAttribute ("textpos", g->getTextLabelPosition().getFlags())));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode& code, Component* component) override
|
||||
{
|
||||
GroupComponent* g = dynamic_cast<GroupComponent*> (component);
|
||||
|
||||
return quotedString (component->getName(), false)
|
||||
+ ",\n"
|
||||
+ quotedString (g->getText(), code.shouldUseTransMacro());
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
GroupComponent* const g = dynamic_cast<GroupComponent*> (component);
|
||||
|
||||
String s;
|
||||
|
||||
GroupComponent defaultComp;
|
||||
|
||||
if (g->getTextLabelPosition().getFlags() != defaultComp.getTextLabelPosition().getFlags())
|
||||
{
|
||||
s << memberVariableName << "->setTextLabelPosition ("
|
||||
<< CodeHelpers::justificationToCode (g->getTextLabelPosition())
|
||||
<< ");\n";
|
||||
}
|
||||
|
||||
s << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* gc = dynamic_cast<GroupComponent*> (component))
|
||||
{
|
||||
props.add (new GroupTitleProperty (gc, document));
|
||||
props.add (new GroupJustificationProperty (gc, document));
|
||||
}
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class GroupTitleProperty : public ComponentTextProperty <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupTitleProperty (GroupComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <GroupComponent> ("text", 200, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new GroupTitleChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change group title");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getText();
|
||||
}
|
||||
|
||||
private:
|
||||
class GroupTitleChangeAction : public ComponentUndoableAction <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupTitleChangeAction (GroupComponent* const comp, ComponentLayout& l, const String& newName_)
|
||||
: ComponentUndoableAction <GroupComponent> (comp, l),
|
||||
newName (newName_)
|
||||
{
|
||||
oldName = comp->getText();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (newName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (oldName);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newName, oldName;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class GroupJustificationProperty : public JustificationProperty,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
GroupJustificationProperty (GroupComponent* const group_, JucerDocument& doc)
|
||||
: JustificationProperty ("layout", true),
|
||||
group (group_),
|
||||
document (doc)
|
||||
{
|
||||
document.addChangeListener (this);
|
||||
}
|
||||
|
||||
~GroupJustificationProperty() override
|
||||
{
|
||||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setJustification (Justification newJustification) override
|
||||
{
|
||||
document.perform (new GroupJustifyChangeAction (group, *document.getComponentLayout(), newJustification),
|
||||
"Change text label position");
|
||||
}
|
||||
|
||||
Justification getJustification() const override
|
||||
{
|
||||
return group->getTextLabelPosition();
|
||||
}
|
||||
|
||||
private:
|
||||
void changeListenerCallback (ChangeBroadcaster*) override { refresh(); }
|
||||
|
||||
GroupComponent* const group;
|
||||
JucerDocument& document;
|
||||
|
||||
class GroupJustifyChangeAction : public ComponentUndoableAction <GroupComponent>
|
||||
{
|
||||
public:
|
||||
GroupJustifyChangeAction (GroupComponent* const comp, ComponentLayout& l, Justification newState_)
|
||||
: ComponentUndoableAction <GroupComponent> (comp, l),
|
||||
newState (newState_),
|
||||
oldState (comp->getTextLabelPosition())
|
||||
{
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextLabelPosition (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setTextLabelPosition (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
Justification newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,149 +1,149 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class HyperlinkButtonHandler : public ButtonHandler
|
||||
{
|
||||
public:
|
||||
HyperlinkButtonHandler()
|
||||
: ButtonHandler ("Hyperlink Button", "juce::HyperlinkButton", typeid (HyperlinkButton), 150, 24)
|
||||
{
|
||||
registerColour (juce::HyperlinkButton::textColourId, "text", "textCol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
HyperlinkButton* hb = new HyperlinkButton ("new hyperlink", URL ("http://www.juce.com"));
|
||||
|
||||
setNeedsButtonListener (hb, false);
|
||||
return hb;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ButtonHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* hb = dynamic_cast<HyperlinkButton*> (component))
|
||||
props.add (new HyperlinkURLProperty (hb, document));
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
HyperlinkButton* const hb = (HyperlinkButton*) comp;
|
||||
XmlElement* const e = ButtonHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("url", hb->getURL().toString (false));
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
HyperlinkButton* const hb = (HyperlinkButton*) comp;
|
||||
|
||||
if (! ButtonHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
hb->setURL (URL (xml.getStringAttribute ("url", hb->getURL().toString (false))));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode& code, Component* comp) override
|
||||
{
|
||||
HyperlinkButton* const hb = dynamic_cast<HyperlinkButton*> (comp);
|
||||
|
||||
return quotedString (hb->getButtonText(), code.shouldUseTransMacro())
|
||||
+ ",\nURL ("
|
||||
+ quotedString (hb->getURL().toString (false), false)
|
||||
+ ")";
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ButtonHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
code.constructorCode << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class HyperlinkURLProperty : public ComponentTextProperty <HyperlinkButton>
|
||||
{
|
||||
public:
|
||||
HyperlinkURLProperty (HyperlinkButton* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <HyperlinkButton> ("URL", 512, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new HyperlinkURLChangeAction (component, *document.getComponentLayout(), URL::createWithoutParsing (newText)),
|
||||
"Change hyperlink URL");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getURL().toString (false);
|
||||
}
|
||||
|
||||
private:
|
||||
class HyperlinkURLChangeAction : public ComponentUndoableAction <HyperlinkButton>
|
||||
{
|
||||
public:
|
||||
HyperlinkURLChangeAction (HyperlinkButton* const comp, ComponentLayout& l, const URL& newState_)
|
||||
: ComponentUndoableAction <HyperlinkButton> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getURL();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setURL (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setURL (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
URL newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class HyperlinkButtonHandler : public ButtonHandler
|
||||
{
|
||||
public:
|
||||
HyperlinkButtonHandler()
|
||||
: ButtonHandler ("Hyperlink Button", "juce::HyperlinkButton", typeid (HyperlinkButton), 150, 24)
|
||||
{
|
||||
registerColour (juce::HyperlinkButton::textColourId, "text", "textCol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
HyperlinkButton* hb = new HyperlinkButton ("new hyperlink", URL ("http://www.juce.com"));
|
||||
|
||||
setNeedsButtonListener (hb, false);
|
||||
return hb;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ButtonHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* hb = dynamic_cast<HyperlinkButton*> (component))
|
||||
props.add (new HyperlinkURLProperty (hb, document));
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
HyperlinkButton* const hb = (HyperlinkButton*) comp;
|
||||
XmlElement* const e = ButtonHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("url", hb->getURL().toString (false));
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
HyperlinkButton* const hb = (HyperlinkButton*) comp;
|
||||
|
||||
if (! ButtonHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
hb->setURL (URL (xml.getStringAttribute ("url", hb->getURL().toString (false))));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode& code, Component* comp) override
|
||||
{
|
||||
HyperlinkButton* const hb = dynamic_cast<HyperlinkButton*> (comp);
|
||||
|
||||
return quotedString (hb->getButtonText(), code.shouldUseTransMacro())
|
||||
+ ",\njuce::URL ("
|
||||
+ quotedString (hb->getURL().toString (false), false)
|
||||
+ ")";
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ButtonHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
code.constructorCode << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class HyperlinkURLProperty : public ComponentTextProperty <HyperlinkButton>
|
||||
{
|
||||
public:
|
||||
HyperlinkURLProperty (HyperlinkButton* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <HyperlinkButton> ("URL", 512, false, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new HyperlinkURLChangeAction (component, *document.getComponentLayout(), URL::createWithoutParsing (newText)),
|
||||
"Change hyperlink URL");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getURL().toString (false);
|
||||
}
|
||||
|
||||
private:
|
||||
class HyperlinkURLChangeAction : public ComponentUndoableAction <HyperlinkButton>
|
||||
{
|
||||
public:
|
||||
HyperlinkURLChangeAction (HyperlinkButton* const comp, ComponentLayout& l, const URL& newState_)
|
||||
: ComponentUndoableAction <HyperlinkButton> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getURL();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setURL (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setURL (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
URL newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,273 +1,273 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../UI/jucer_TestComponent.h"
|
||||
#include "../Properties/jucer_FilePropertyComponent.h"
|
||||
#include "../Properties/jucer_ComponentTextProperty.h"
|
||||
#include "jucer_ComponentUndoableAction.h"
|
||||
#include "../../Project/UI/jucer_ProjectContentComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
class JucerComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
JucerComponentHandler()
|
||||
: ComponentTypeHandler ("Projucer Component", "xxx",
|
||||
typeid (TestComponent), 300, 200)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument* doc) override
|
||||
{
|
||||
return new TestComponent (doc, nullptr, false);
|
||||
}
|
||||
|
||||
String getXmlTagName() const noexcept override { return "JUCERCOMP"; }
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
TestComponent* const tc = dynamic_cast<TestComponent*> (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) override
|
||||
{
|
||||
auto tc = dynamic_cast<TestComponent*> (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 override
|
||||
{
|
||||
auto tc = dynamic_cast<TestComponent*> (comp);
|
||||
|
||||
String jucerCompClassName;
|
||||
|
||||
if (tc->getDocument() != nullptr)
|
||||
jucerCompClassName = tc->getDocument()->getClassName();
|
||||
|
||||
if (jucerCompClassName.isEmpty())
|
||||
jucerCompClassName = "juce::Component";
|
||||
|
||||
return jucerCompClassName;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto tc = dynamic_cast<TestComponent*> (component))
|
||||
{
|
||||
props.add (new JucerCompFileProperty (tc, document));
|
||||
props.add (new ConstructorParamsProperty (tc, document));
|
||||
props.add (new JucerCompOpenDocProperty (tc));
|
||||
}
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return dynamic_cast<TestComponent*> (component)->getConstructorParams().trim();
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (auto tc = dynamic_cast<TestComponent*> (component))
|
||||
code.includeFilesH.add (tc->findFile().withFileExtension (".h"));
|
||||
else
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class JucerCompFileChangeAction : public ComponentUndoableAction <TestComponent>
|
||||
{
|
||||
public:
|
||||
JucerCompFileChangeAction (TestComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <TestComponent> (comp, l),
|
||||
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 != nullptr);
|
||||
|
||||
if (comp != nullptr)
|
||||
document.perform (new JucerCompFileChangeAction (comp, *document.getComponentLayout(), newFilename),
|
||||
"Change Projucer component file");
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class JucerCompFileProperty : public FilePropertyComponent,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
JucerCompFileProperty (TestComponent* const comp, JucerDocument& doc)
|
||||
: FilePropertyComponent ("Jucer file", false, true),
|
||||
component (comp),
|
||||
document (doc)
|
||||
{
|
||||
document.addChangeListener (this);
|
||||
}
|
||||
|
||||
~JucerCompFileProperty() override
|
||||
{
|
||||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setFile (const File& newFile) override
|
||||
{
|
||||
setJucerComponentFile (document, component,
|
||||
newFile.getRelativePathFrom (document.getCppFile().getParentDirectory())
|
||||
.replaceCharacter ('\\', '/'));
|
||||
}
|
||||
|
||||
File getFile() const override
|
||||
{
|
||||
return component->findFile();
|
||||
}
|
||||
|
||||
private:
|
||||
void changeListenerCallback (ChangeBroadcaster*) override
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
TestComponent* const component;
|
||||
JucerDocument& document;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct JucerCompOpenDocProperty : public ButtonPropertyComponent
|
||||
{
|
||||
JucerCompOpenDocProperty (TestComponent* const c)
|
||||
: ButtonPropertyComponent ("edit", false),
|
||||
component (c)
|
||||
{
|
||||
}
|
||||
|
||||
void buttonClicked()
|
||||
{
|
||||
if (ProjectContentComponent* const pcc = findParentComponentOfClass<ProjectContentComponent>())
|
||||
pcc->showEditorForFile (component->findFile(), true);
|
||||
}
|
||||
|
||||
String getButtonText() const
|
||||
{
|
||||
return "Open file for editing";
|
||||
}
|
||||
|
||||
TestComponent* const component;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct ConstructorParamsProperty : public ComponentTextProperty <TestComponent>
|
||||
{
|
||||
ConstructorParamsProperty (TestComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <TestComponent> ("constructor params", 512, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ConstructorParamChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change Viewport content constructor params");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getConstructorParams();
|
||||
}
|
||||
|
||||
private:
|
||||
struct ConstructorParamChangeAction : public ComponentUndoableAction <TestComponent>
|
||||
{
|
||||
ConstructorParamChangeAction (TestComponent* const comp, ComponentLayout& l, const String& newValue_)
|
||||
: ComponentUndoableAction <TestComponent> (comp, l),
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../UI/jucer_TestComponent.h"
|
||||
#include "../Properties/jucer_FilePropertyComponent.h"
|
||||
#include "../Properties/jucer_ComponentTextProperty.h"
|
||||
#include "jucer_ComponentUndoableAction.h"
|
||||
#include "../../Project/UI/jucer_ProjectContentComponent.h"
|
||||
|
||||
//==============================================================================
|
||||
class JucerComponentHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
JucerComponentHandler()
|
||||
: ComponentTypeHandler ("Projucer Component", "xxx",
|
||||
typeid (TestComponent), 300, 200)
|
||||
{}
|
||||
|
||||
Component* createNewComponent (JucerDocument* doc) override
|
||||
{
|
||||
return new TestComponent (doc, nullptr, false);
|
||||
}
|
||||
|
||||
String getXmlTagName() const noexcept override { return "JUCERCOMP"; }
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
TestComponent* const tc = dynamic_cast<TestComponent*> (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) override
|
||||
{
|
||||
auto tc = dynamic_cast<TestComponent*> (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 override
|
||||
{
|
||||
auto tc = dynamic_cast<TestComponent*> (comp);
|
||||
|
||||
String jucerCompClassName;
|
||||
|
||||
if (tc->getDocument() != nullptr)
|
||||
jucerCompClassName = tc->getDocument()->getClassName();
|
||||
|
||||
if (jucerCompClassName.isEmpty())
|
||||
jucerCompClassName = "juce::Component";
|
||||
|
||||
return jucerCompClassName;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto tc = dynamic_cast<TestComponent*> (component))
|
||||
{
|
||||
props.add (new JucerCompFileProperty (tc, document));
|
||||
props.add (new ConstructorParamsProperty (tc, document));
|
||||
props.add (new JucerCompOpenDocProperty (tc));
|
||||
}
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return dynamic_cast<TestComponent*> (component)->getConstructorParams().trim();
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (auto tc = dynamic_cast<TestComponent*> (component))
|
||||
code.includeFilesH.add (tc->findFile().withFileExtension (".h"));
|
||||
else
|
||||
jassertfalse;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class JucerCompFileChangeAction : public ComponentUndoableAction <TestComponent>
|
||||
{
|
||||
public:
|
||||
JucerCompFileChangeAction (TestComponent* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <TestComponent> (comp, l),
|
||||
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 != nullptr);
|
||||
|
||||
if (comp != nullptr)
|
||||
document.perform (new JucerCompFileChangeAction (comp, *document.getComponentLayout(), newFilename),
|
||||
"Change Projucer component file");
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class JucerCompFileProperty : public FilePropertyComponent,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
JucerCompFileProperty (TestComponent* const comp, JucerDocument& doc)
|
||||
: FilePropertyComponent ("Jucer file", false, true),
|
||||
component (comp),
|
||||
document (doc)
|
||||
{
|
||||
document.addChangeListener (this);
|
||||
}
|
||||
|
||||
~JucerCompFileProperty() override
|
||||
{
|
||||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setFile (const File& newFile) override
|
||||
{
|
||||
setJucerComponentFile (document, component,
|
||||
newFile.getRelativePathFrom (document.getCppFile().getParentDirectory())
|
||||
.replaceCharacter ('\\', '/'));
|
||||
}
|
||||
|
||||
File getFile() const override
|
||||
{
|
||||
return component->findFile();
|
||||
}
|
||||
|
||||
private:
|
||||
void changeListenerCallback (ChangeBroadcaster*) override
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
TestComponent* const component;
|
||||
JucerDocument& document;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct JucerCompOpenDocProperty : public ButtonPropertyComponent
|
||||
{
|
||||
JucerCompOpenDocProperty (TestComponent* const c)
|
||||
: ButtonPropertyComponent ("edit", false),
|
||||
component (c)
|
||||
{
|
||||
}
|
||||
|
||||
void buttonClicked()
|
||||
{
|
||||
if (ProjectContentComponent* const pcc = findParentComponentOfClass<ProjectContentComponent>())
|
||||
pcc->showEditorForFile (component->findFile(), true);
|
||||
}
|
||||
|
||||
String getButtonText() const
|
||||
{
|
||||
return "Open file for editing";
|
||||
}
|
||||
|
||||
TestComponent* const component;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct ConstructorParamsProperty : public ComponentTextProperty <TestComponent>
|
||||
{
|
||||
ConstructorParamsProperty (TestComponent* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <TestComponent> ("constructor params", 512, false, comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new ConstructorParamChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change Viewport content constructor params");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getConstructorParams();
|
||||
}
|
||||
|
||||
private:
|
||||
struct ConstructorParamChangeAction : public ComponentUndoableAction <TestComponent>
|
||||
{
|
||||
ConstructorParamChangeAction (TestComponent* const comp, ComponentLayout& l, const String& newValue_)
|
||||
: ComponentUndoableAction <TestComponent> (comp, l),
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,79 +1,79 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class TextButtonHandler : public ButtonHandler
|
||||
{
|
||||
public:
|
||||
TextButtonHandler()
|
||||
: ButtonHandler ("Text Button", "juce::TextButton", typeid (TextButton), 150, 24)
|
||||
{
|
||||
registerColour (juce::TextButton::buttonColourId, "background (normal)", "bgColOff");
|
||||
registerColour (juce::TextButton::buttonOnColourId, "background (on)", "bgColOn");
|
||||
registerColour (juce::TextButton::textColourOffId, "text colour (normal)", "textCol");
|
||||
registerColour (juce::TextButton::textColourOnId, "text colour (on)", "textColOn");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new TextButton ("new button", String());
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ButtonHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
return ButtonHandler::createXmlFor (comp, layout);
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
return ButtonHandler::restoreFromXml (xml, comp, layout);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ButtonHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
String s;
|
||||
|
||||
s << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class TextButtonHandler : public ButtonHandler
|
||||
{
|
||||
public:
|
||||
TextButtonHandler()
|
||||
: ButtonHandler ("Text Button", "juce::TextButton", typeid (TextButton), 150, 24)
|
||||
{
|
||||
registerColour (juce::TextButton::buttonColourId, "background (normal)", "bgColOff");
|
||||
registerColour (juce::TextButton::buttonOnColourId, "background (on)", "bgColOn");
|
||||
registerColour (juce::TextButton::textColourOffId, "text colour (normal)", "textCol");
|
||||
registerColour (juce::TextButton::textColourOnId, "text colour (on)", "textColOn");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new TextButton ("new button", String());
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ButtonHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
return ButtonHandler::createXmlFor (comp, layout);
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
return ButtonHandler::restoreFromXml (xml, comp, layout);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ButtonHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
String s;
|
||||
|
||||
s << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
};
|
||||
|
@ -1,433 +1,433 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
TextEditorHandler()
|
||||
: ComponentTypeHandler ("Text Editor", "juce::TextEditor", typeid (TextEditor), 150, 24)
|
||||
{
|
||||
registerColour (juce::TextEditor::textColourId, "text", "textcol");
|
||||
registerColour (juce::TextEditor::backgroundColourId, "background", "bkgcol");
|
||||
registerColour (juce::TextEditor::highlightColourId, "highlight", "hilitecol");
|
||||
registerColour (juce::TextEditor::outlineColourId, "outline", "outlinecol");
|
||||
registerColour (juce::TextEditor::shadowColourId, "shadow", "shadowcol");
|
||||
registerColour (juce::CaretComponent::caretColourId, "caret", "caretcol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new TextEditor ("new text editor");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
TextEditor* te = (TextEditor*) comp;
|
||||
|
||||
e->setAttribute ("initialText", comp->getProperties() ["initialText"].toString());
|
||||
|
||||
e->setAttribute ("multiline", te->isMultiLine());
|
||||
e->setAttribute ("retKeyStartsLine", te->getReturnKeyStartsNewLine());
|
||||
e->setAttribute ("readonly", te->isReadOnly());
|
||||
e->setAttribute ("scrollbars", te->areScrollbarsShown());
|
||||
e->setAttribute ("caret", te->isCaretVisible());
|
||||
e->setAttribute ("popupmenu", te->isPopupMenuEnabled());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
TextEditor* te = (TextEditor*) comp;
|
||||
TextEditor defaultEditor;
|
||||
|
||||
te->setMultiLine (xml.getBoolAttribute ("multiline", defaultEditor.isMultiLine()));
|
||||
te->setReturnKeyStartsNewLine (xml.getBoolAttribute ("retKeyStartsLine", defaultEditor.getReturnKeyStartsNewLine()));
|
||||
te->setReadOnly (xml.getBoolAttribute ("readonly", defaultEditor.isReadOnly()));
|
||||
te->setScrollbarsShown (xml.getBoolAttribute ("scrollbars", defaultEditor.areScrollbarsShown()));
|
||||
te->setCaretVisible (xml.getBoolAttribute ("caret", defaultEditor.isCaretVisible()));
|
||||
te->setPopupMenuEnabled (xml.getBoolAttribute ("popupmenu", defaultEditor.isPopupMenuEnabled()));
|
||||
|
||||
const String initialText (xml.getStringAttribute ("initialText"));
|
||||
te->setText (initialText, false);
|
||||
te->getProperties().set ("initialText", initialText);
|
||||
return true;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* t = dynamic_cast<TextEditor*> (component))
|
||||
{
|
||||
props.add (new TextEditorInitialTextProperty (t, document));
|
||||
props.add (new TextEditorMultiLineProperty (t, document));
|
||||
props.add (new TextEditorReadOnlyProperty (t, document));
|
||||
props.add (new TextEditorScrollbarsProperty (t, document));
|
||||
props.add (new TextEditorCaretProperty (t, document));
|
||||
props.add (new TextEditorPopupMenuProperty (t, document));
|
||||
|
||||
addColourProperties (t, document, props);
|
||||
}
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (auto* te = dynamic_cast<TextEditor*> (component))
|
||||
{
|
||||
String s;
|
||||
s << memberVariableName << "->setMultiLine (" << CodeHelpers::boolLiteral (te->isMultiLine()) << ");\n"
|
||||
<< memberVariableName << "->setReturnKeyStartsNewLine (" << CodeHelpers::boolLiteral (te->getReturnKeyStartsNewLine()) << ");\n"
|
||||
<< memberVariableName << "->setReadOnly (" << CodeHelpers::boolLiteral (te->isReadOnly()) << ");\n"
|
||||
<< memberVariableName << "->setScrollbarsShown (" << CodeHelpers::boolLiteral (te->areScrollbarsShown()) << ");\n"
|
||||
<< memberVariableName << "->setCaretVisible (" << CodeHelpers::boolLiteral (te->isCaretVisible()) << ");\n"
|
||||
<< memberVariableName << "->setPopupMenuEnabled (" << CodeHelpers::boolLiteral (te->isPopupMenuEnabled()) << ");\n"
|
||||
<< getColourIntialisationCode (component, memberVariableName)
|
||||
<< memberVariableName << "->setText (" << quotedString (te->getProperties() ["initialText"].toString(), code.shouldUseTransMacro()) << ");\n\n";
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class TextEditorMultiLineProperty : public ComponentChoiceProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorMultiLineProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentChoiceProperty <TextEditor> ("mode", comp, doc)
|
||||
{
|
||||
choices.add ("single line");
|
||||
choices.add ("multi-line, return key starts new line");
|
||||
choices.add ("multi-line, return key disabled");
|
||||
}
|
||||
|
||||
void setIndex (int newIndex)
|
||||
{
|
||||
document.perform (new TextEditorMultilineChangeAction (component, *document.getComponentLayout(), newIndex),
|
||||
"Change TextEditor multiline mode");
|
||||
}
|
||||
|
||||
int getIndex() const
|
||||
{
|
||||
return component->isMultiLine() ? (component->getReturnKeyStartsNewLine() ? 1 : 2) : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
class TextEditorMultilineChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorMultilineChangeAction (TextEditor* const comp, ComponentLayout& l, const int newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isMultiLine() ? (comp->getReturnKeyStartsNewLine() ? 1 : 2) : 0;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setMultiLine (newState > 0);
|
||||
getComponent()->setReturnKeyStartsNewLine (newState == 1);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setMultiLine (oldState > 0);
|
||||
getComponent()->setReturnKeyStartsNewLine (oldState == 1);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
int newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorReadOnlyProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorReadOnlyProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("editable", "Editable", "Editable", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorReadonlyChangeAction (component, *document.getComponentLayout(), ! newState),
|
||||
"Change TextEditor read-only mode");
|
||||
}
|
||||
|
||||
bool getState() const { return ! component->isReadOnly(); }
|
||||
|
||||
private:
|
||||
class TextEditorReadonlyChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorReadonlyChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isReadOnly();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setReadOnly (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setReadOnly (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorScrollbarsProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorScrollbarsProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("scrollbars", "Scrollbars enabled", "Scrollbars enabled", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorScrollbarChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TextEditor scrollbars");
|
||||
}
|
||||
|
||||
bool getState() const { return component->areScrollbarsShown(); }
|
||||
|
||||
private:
|
||||
class TextEditorScrollbarChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorScrollbarChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->areScrollbarsShown();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setScrollbarsShown (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setScrollbarsShown (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorCaretProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorCaretProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("caret", "Caret visible", "Caret visible", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorCaretChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TextEditor caret");
|
||||
}
|
||||
|
||||
bool getState() const { return component->isCaretVisible(); }
|
||||
|
||||
private:
|
||||
class TextEditorCaretChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorCaretChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isCaretVisible();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setCaretVisible (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setCaretVisible (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorPopupMenuProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorPopupMenuProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("popup menu", "Popup menu enabled", "Popup menu enabled", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorPopupMenuChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TextEditor popup menu");
|
||||
}
|
||||
|
||||
bool getState() const { return component->isPopupMenuEnabled(); }
|
||||
|
||||
private:
|
||||
class TextEditorPopupMenuChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorPopupMenuChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isPopupMenuEnabled();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setPopupMenuEnabled (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setPopupMenuEnabled (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorInitialTextProperty : public ComponentTextProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorInitialTextProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <TextEditor> ("initial text", 10000, true, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new TextEditorInitialTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change TextEditor initial text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getProperties() ["initialText"];
|
||||
}
|
||||
|
||||
private:
|
||||
class TextEditorInitialTextChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorInitialTextChangeAction (TextEditor* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getProperties() ["initialText"];
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (newState, false);
|
||||
getComponent()->getProperties().set ("initialText", newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (oldState, false);
|
||||
getComponent()->getProperties().set ("initialText", oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
TextEditorHandler()
|
||||
: ComponentTypeHandler ("Text Editor", "juce::TextEditor", typeid (TextEditor), 150, 24)
|
||||
{
|
||||
registerColour (juce::TextEditor::textColourId, "text", "textcol");
|
||||
registerColour (juce::TextEditor::backgroundColourId, "background", "bkgcol");
|
||||
registerColour (juce::TextEditor::highlightColourId, "highlight", "hilitecol");
|
||||
registerColour (juce::TextEditor::outlineColourId, "outline", "outlinecol");
|
||||
registerColour (juce::TextEditor::shadowColourId, "shadow", "shadowcol");
|
||||
registerColour (juce::CaretComponent::caretColourId, "caret", "caretcol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new TextEditor ("new text editor");
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
XmlElement* e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
TextEditor* te = (TextEditor*) comp;
|
||||
|
||||
e->setAttribute ("initialText", comp->getProperties() ["initialText"].toString());
|
||||
|
||||
e->setAttribute ("multiline", te->isMultiLine());
|
||||
e->setAttribute ("retKeyStartsLine", te->getReturnKeyStartsNewLine());
|
||||
e->setAttribute ("readonly", te->isReadOnly());
|
||||
e->setAttribute ("scrollbars", te->areScrollbarsShown());
|
||||
e->setAttribute ("caret", te->isCaretVisible());
|
||||
e->setAttribute ("popupmenu", te->isPopupMenuEnabled());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
TextEditor* te = (TextEditor*) comp;
|
||||
TextEditor defaultEditor;
|
||||
|
||||
te->setMultiLine (xml.getBoolAttribute ("multiline", defaultEditor.isMultiLine()));
|
||||
te->setReturnKeyStartsNewLine (xml.getBoolAttribute ("retKeyStartsLine", defaultEditor.getReturnKeyStartsNewLine()));
|
||||
te->setReadOnly (xml.getBoolAttribute ("readonly", defaultEditor.isReadOnly()));
|
||||
te->setScrollbarsShown (xml.getBoolAttribute ("scrollbars", defaultEditor.areScrollbarsShown()));
|
||||
te->setCaretVisible (xml.getBoolAttribute ("caret", defaultEditor.isCaretVisible()));
|
||||
te->setPopupMenuEnabled (xml.getBoolAttribute ("popupmenu", defaultEditor.isPopupMenuEnabled()));
|
||||
|
||||
const String initialText (xml.getStringAttribute ("initialText"));
|
||||
te->setText (initialText, false);
|
||||
te->getProperties().set ("initialText", initialText);
|
||||
return true;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* t = dynamic_cast<TextEditor*> (component))
|
||||
{
|
||||
props.add (new TextEditorInitialTextProperty (t, document));
|
||||
props.add (new TextEditorMultiLineProperty (t, document));
|
||||
props.add (new TextEditorReadOnlyProperty (t, document));
|
||||
props.add (new TextEditorScrollbarsProperty (t, document));
|
||||
props.add (new TextEditorCaretProperty (t, document));
|
||||
props.add (new TextEditorPopupMenuProperty (t, document));
|
||||
|
||||
addColourProperties (t, document, props);
|
||||
}
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* component) override
|
||||
{
|
||||
return quotedString (component->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (auto* te = dynamic_cast<TextEditor*> (component))
|
||||
{
|
||||
String s;
|
||||
s << memberVariableName << "->setMultiLine (" << CodeHelpers::boolLiteral (te->isMultiLine()) << ");\n"
|
||||
<< memberVariableName << "->setReturnKeyStartsNewLine (" << CodeHelpers::boolLiteral (te->getReturnKeyStartsNewLine()) << ");\n"
|
||||
<< memberVariableName << "->setReadOnly (" << CodeHelpers::boolLiteral (te->isReadOnly()) << ");\n"
|
||||
<< memberVariableName << "->setScrollbarsShown (" << CodeHelpers::boolLiteral (te->areScrollbarsShown()) << ");\n"
|
||||
<< memberVariableName << "->setCaretVisible (" << CodeHelpers::boolLiteral (te->isCaretVisible()) << ");\n"
|
||||
<< memberVariableName << "->setPopupMenuEnabled (" << CodeHelpers::boolLiteral (te->isPopupMenuEnabled()) << ");\n"
|
||||
<< getColourIntialisationCode (component, memberVariableName)
|
||||
<< memberVariableName << "->setText (" << quotedString (te->getProperties() ["initialText"].toString(), code.shouldUseTransMacro()) << ");\n\n";
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class TextEditorMultiLineProperty : public ComponentChoiceProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorMultiLineProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentChoiceProperty <TextEditor> ("mode", comp, doc)
|
||||
{
|
||||
choices.add ("single line");
|
||||
choices.add ("multi-line, return key starts new line");
|
||||
choices.add ("multi-line, return key disabled");
|
||||
}
|
||||
|
||||
void setIndex (int newIndex)
|
||||
{
|
||||
document.perform (new TextEditorMultilineChangeAction (component, *document.getComponentLayout(), newIndex),
|
||||
"Change TextEditor multiline mode");
|
||||
}
|
||||
|
||||
int getIndex() const
|
||||
{
|
||||
return component->isMultiLine() ? (component->getReturnKeyStartsNewLine() ? 1 : 2) : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
class TextEditorMultilineChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorMultilineChangeAction (TextEditor* const comp, ComponentLayout& l, const int newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isMultiLine() ? (comp->getReturnKeyStartsNewLine() ? 1 : 2) : 0;
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setMultiLine (newState > 0);
|
||||
getComponent()->setReturnKeyStartsNewLine (newState == 1);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setMultiLine (oldState > 0);
|
||||
getComponent()->setReturnKeyStartsNewLine (oldState == 1);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
int newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorReadOnlyProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorReadOnlyProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("editable", "Editable", "Editable", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorReadonlyChangeAction (component, *document.getComponentLayout(), ! newState),
|
||||
"Change TextEditor read-only mode");
|
||||
}
|
||||
|
||||
bool getState() const { return ! component->isReadOnly(); }
|
||||
|
||||
private:
|
||||
class TextEditorReadonlyChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorReadonlyChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isReadOnly();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setReadOnly (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setReadOnly (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorScrollbarsProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorScrollbarsProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("scrollbars", "Scrollbars enabled", "Scrollbars enabled", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorScrollbarChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TextEditor scrollbars");
|
||||
}
|
||||
|
||||
bool getState() const { return component->areScrollbarsShown(); }
|
||||
|
||||
private:
|
||||
class TextEditorScrollbarChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorScrollbarChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->areScrollbarsShown();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setScrollbarsShown (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setScrollbarsShown (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorCaretProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorCaretProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("caret", "Caret visible", "Caret visible", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorCaretChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TextEditor caret");
|
||||
}
|
||||
|
||||
bool getState() const { return component->isCaretVisible(); }
|
||||
|
||||
private:
|
||||
class TextEditorCaretChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorCaretChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isCaretVisible();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setCaretVisible (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setCaretVisible (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorPopupMenuProperty : public ComponentBooleanProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorPopupMenuProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TextEditor> ("popup menu", "Popup menu enabled", "Popup menu enabled", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TextEditorPopupMenuChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TextEditor popup menu");
|
||||
}
|
||||
|
||||
bool getState() const { return component->isPopupMenuEnabled(); }
|
||||
|
||||
private:
|
||||
class TextEditorPopupMenuChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorPopupMenuChangeAction (TextEditor* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isPopupMenuEnabled();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setPopupMenuEnabled (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setPopupMenuEnabled (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextEditorInitialTextProperty : public ComponentTextProperty <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorInitialTextProperty (TextEditor* comp, JucerDocument& doc)
|
||||
: ComponentTextProperty <TextEditor> ("initial text", 10000, true, comp, doc)
|
||||
{}
|
||||
|
||||
void setText (const String& newText) override
|
||||
{
|
||||
document.perform (new TextEditorInitialTextChangeAction (component, *document.getComponentLayout(), newText),
|
||||
"Change TextEditor initial text");
|
||||
}
|
||||
|
||||
String getText() const override
|
||||
{
|
||||
return component->getProperties() ["initialText"];
|
||||
}
|
||||
|
||||
private:
|
||||
class TextEditorInitialTextChangeAction : public ComponentUndoableAction <TextEditor>
|
||||
{
|
||||
public:
|
||||
TextEditorInitialTextChangeAction (TextEditor* const comp, ComponentLayout& l, const String& newState_)
|
||||
: ComponentUndoableAction <TextEditor> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getProperties() ["initialText"];
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (newState, false);
|
||||
getComponent()->getProperties().set ("initialText", newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setText (oldState, false);
|
||||
getComponent()->getProperties().set ("initialText", oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
String newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,146 +1,146 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ToggleButtonHandler : public ButtonHandler
|
||||
{
|
||||
public:
|
||||
ToggleButtonHandler()
|
||||
: ButtonHandler ("Toggle Button", "juce::ToggleButton", typeid (ToggleButton), 150, 24)
|
||||
{
|
||||
registerColour (juce::ToggleButton::textColourId, "text colour", "txtcol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new ToggleButton ("new toggle button");
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ButtonHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* tb = dynamic_cast<ToggleButton*> (component))
|
||||
props.add (new ToggleButtonStateProperty (tb, document));
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
ToggleButton* tb = (ToggleButton*) comp;
|
||||
|
||||
XmlElement* e = ButtonHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("state", tb->getToggleState());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
ToggleButton* const tb = (ToggleButton*) comp;
|
||||
|
||||
if (! ButtonHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
tb->setToggleState (xml.getBoolAttribute ("state", false), dontSendNotification);
|
||||
return true;
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ButtonHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
ToggleButton* const tb = dynamic_cast<ToggleButton*> (component);
|
||||
|
||||
String s;
|
||||
|
||||
if (tb->getToggleState())
|
||||
s << memberVariableName << "->setToggleState (true, juce::dontSendNotification);\n";
|
||||
|
||||
s << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
private:
|
||||
class ToggleButtonStateProperty : public ComponentBooleanProperty <ToggleButton>
|
||||
{
|
||||
public:
|
||||
ToggleButtonStateProperty (ToggleButton* button_, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <ToggleButton> ("initial state", "on", "off", button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ToggleStateChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change ToggleButton state");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return component->getToggleState();
|
||||
}
|
||||
|
||||
private:
|
||||
class ToggleStateChangeAction : public ComponentUndoableAction <ToggleButton>
|
||||
{
|
||||
public:
|
||||
ToggleStateChangeAction (ToggleButton* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <ToggleButton> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getToggleState();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setToggleState (newState, dontSendNotification);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setToggleState (oldState, dontSendNotification);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ToggleButtonHandler : public ButtonHandler
|
||||
{
|
||||
public:
|
||||
ToggleButtonHandler()
|
||||
: ButtonHandler ("Toggle Button", "juce::ToggleButton", typeid (ToggleButton), 150, 24)
|
||||
{
|
||||
registerColour (juce::ToggleButton::textColourId, "text colour", "txtcol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new ToggleButton ("new toggle button");
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ButtonHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
if (auto* tb = dynamic_cast<ToggleButton*> (component))
|
||||
props.add (new ToggleButtonStateProperty (tb, document));
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
ToggleButton* tb = (ToggleButton*) comp;
|
||||
|
||||
XmlElement* e = ButtonHandler::createXmlFor (comp, layout);
|
||||
e->setAttribute ("state", tb->getToggleState());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
ToggleButton* const tb = (ToggleButton*) comp;
|
||||
|
||||
if (! ButtonHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
tb->setToggleState (xml.getBoolAttribute ("state", false), dontSendNotification);
|
||||
return true;
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
ButtonHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
ToggleButton* const tb = dynamic_cast<ToggleButton*> (component);
|
||||
|
||||
String s;
|
||||
|
||||
if (tb->getToggleState())
|
||||
s << memberVariableName << "->setToggleState (true, juce::dontSendNotification);\n";
|
||||
|
||||
s << getColourIntialisationCode (component, memberVariableName)
|
||||
<< '\n';
|
||||
|
||||
code.constructorCode += s;
|
||||
}
|
||||
|
||||
private:
|
||||
class ToggleButtonStateProperty : public ComponentBooleanProperty <ToggleButton>
|
||||
{
|
||||
public:
|
||||
ToggleButtonStateProperty (ToggleButton* button_, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <ToggleButton> ("initial state", "on", "off", button_, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new ToggleStateChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change ToggleButton state");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return component->getToggleState();
|
||||
}
|
||||
|
||||
private:
|
||||
class ToggleStateChangeAction : public ComponentUndoableAction <ToggleButton>
|
||||
{
|
||||
public:
|
||||
ToggleStateChangeAction (ToggleButton* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <ToggleButton> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getToggleState();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setToggleState (newState, dontSendNotification);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setToggleState (oldState, dontSendNotification);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,265 +1,265 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class TreeViewHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
TreeViewHandler()
|
||||
: ComponentTypeHandler ("TreeView", "juce::TreeView", typeid (DemoTreeView), 150, 150)
|
||||
{
|
||||
registerColour (juce::TreeView::backgroundColourId, "background", "backgroundColour");
|
||||
registerColour (juce::TreeView::linesColourId, "lines", "linecol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new DemoTreeView();
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
TreeView* const t = dynamic_cast<TreeView*> (comp);
|
||||
XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
|
||||
e->setAttribute ("rootVisible", t->isRootItemVisible());
|
||||
e->setAttribute ("openByDefault", t->areItemsOpenByDefault());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
TreeView defaultTreeView;
|
||||
TreeView* const t = dynamic_cast<TreeView*> (comp);
|
||||
|
||||
t->setRootItemVisible (xml.getBoolAttribute ("rootVisible", defaultTreeView.isRootItemVisible()));
|
||||
t->setDefaultOpenness (xml.getBoolAttribute ("openByDefault", defaultTreeView.areItemsOpenByDefault()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
auto* t = dynamic_cast<TreeView*> (component);
|
||||
|
||||
props.add (new TreeViewRootItemProperty (t, document));
|
||||
props.add (new TreeViewRootOpennessProperty (t, document));
|
||||
|
||||
addColourProperties (t, document, props);
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* comp) override
|
||||
{
|
||||
return quotedString (comp->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
TreeView defaultTreeView;
|
||||
TreeView* const t = dynamic_cast<TreeView*> (component);
|
||||
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (defaultTreeView.isRootItemVisible() != t->isRootItemVisible())
|
||||
{
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setRootItemVisible ("
|
||||
<< CodeHelpers::boolLiteral (t->isRootItemVisible()) << ");\n";
|
||||
}
|
||||
|
||||
if (defaultTreeView.areItemsOpenByDefault() != t->areItemsOpenByDefault())
|
||||
{
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setDefaultOpenness ("
|
||||
<< CodeHelpers::boolLiteral (t->areItemsOpenByDefault()) << ");\n";
|
||||
}
|
||||
|
||||
code.constructorCode << getColourIntialisationCode (component, memberVariableName);
|
||||
code.constructorCode << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class DemoTreeView : public TreeView
|
||||
{
|
||||
public:
|
||||
DemoTreeView()
|
||||
: TreeView ("new treeview")
|
||||
{
|
||||
setRootItem (new DemoTreeViewItem ("Demo root node", 4));
|
||||
}
|
||||
|
||||
~DemoTreeView()
|
||||
{
|
||||
deleteRootItem();
|
||||
}
|
||||
|
||||
private:
|
||||
class DemoTreeViewItem : public TreeViewItem
|
||||
{
|
||||
public:
|
||||
DemoTreeViewItem (const String& name_, const int numItems)
|
||||
: name (name_)
|
||||
{
|
||||
for (int i = 0; i < numItems; ++i)
|
||||
addSubItem (new DemoTreeViewItem ("Demo sub-node " + String (i), numItems - 1));
|
||||
}
|
||||
|
||||
void paintItem (Graphics& g, int width, int height) override
|
||||
{
|
||||
if (isSelected())
|
||||
g.fillAll (Colours::lightblue);
|
||||
|
||||
g.setColour (Colours::black);
|
||||
g.setFont ((float) height * 0.7f);
|
||||
g.drawText (name, 4, 0, width - 4, height, Justification::centredLeft, true);
|
||||
}
|
||||
|
||||
bool mightContainSubItems() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const String name;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TreeViewRootItemProperty : public ComponentBooleanProperty <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeViewRootItemProperty (TreeView* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TreeView> ("show root item", "Root item visible", "Root item visible", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TreeviewRootChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TreeView root item");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return component->isRootItemVisible();
|
||||
}
|
||||
|
||||
private:
|
||||
class TreeviewRootChangeAction : public ComponentUndoableAction <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeviewRootChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TreeView> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isRootItemVisible();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRootItemVisible (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRootItemVisible (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TreeViewRootOpennessProperty : public ComponentChoiceProperty <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeViewRootOpennessProperty (TreeView* comp, JucerDocument& doc)
|
||||
: ComponentChoiceProperty <TreeView> ("default openness", comp, doc)
|
||||
{
|
||||
choices.add ("Items open by default");
|
||||
choices.add ("Items closed by default");
|
||||
}
|
||||
|
||||
void setIndex (int newIndex)
|
||||
{
|
||||
document.perform (new TreeviewOpennessChangeAction (component, *document.getComponentLayout(), newIndex == 0),
|
||||
"Change TreeView openness");
|
||||
}
|
||||
|
||||
int getIndex() const
|
||||
{
|
||||
return component->areItemsOpenByDefault() ? 0 : 1;
|
||||
}
|
||||
|
||||
private:
|
||||
class TreeviewOpennessChangeAction : public ComponentUndoableAction <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeviewOpennessChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TreeView> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->areItemsOpenByDefault();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setDefaultOpenness (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setDefaultOpenness (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class TreeViewHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
TreeViewHandler()
|
||||
: ComponentTypeHandler ("TreeView", "juce::TreeView", typeid (DemoTreeView), 150, 150)
|
||||
{
|
||||
registerColour (juce::TreeView::backgroundColourId, "background", "backgroundColour");
|
||||
registerColour (juce::TreeView::linesColourId, "lines", "linecol");
|
||||
}
|
||||
|
||||
Component* createNewComponent (JucerDocument*) override
|
||||
{
|
||||
return new DemoTreeView();
|
||||
}
|
||||
|
||||
XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
TreeView* const t = dynamic_cast<TreeView*> (comp);
|
||||
XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout);
|
||||
|
||||
e->setAttribute ("rootVisible", t->isRootItemVisible());
|
||||
e->setAttribute ("openByDefault", t->areItemsOpenByDefault());
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
|
||||
{
|
||||
if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
|
||||
return false;
|
||||
|
||||
TreeView defaultTreeView;
|
||||
TreeView* const t = dynamic_cast<TreeView*> (comp);
|
||||
|
||||
t->setRootItemVisible (xml.getBoolAttribute ("rootVisible", defaultTreeView.isRootItemVisible()));
|
||||
t->setDefaultOpenness (xml.getBoolAttribute ("openByDefault", defaultTreeView.areItemsOpenByDefault()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void getEditableProperties (Component* component, JucerDocument& document,
|
||||
Array<PropertyComponent*>& props, bool multipleSelected) override
|
||||
{
|
||||
ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
|
||||
|
||||
if (multipleSelected)
|
||||
return;
|
||||
|
||||
auto* t = dynamic_cast<TreeView*> (component);
|
||||
|
||||
props.add (new TreeViewRootItemProperty (t, document));
|
||||
props.add (new TreeViewRootOpennessProperty (t, document));
|
||||
|
||||
addColourProperties (t, document, props);
|
||||
}
|
||||
|
||||
String getCreationParameters (GeneratedCode&, Component* comp) override
|
||||
{
|
||||
return quotedString (comp->getName(), false);
|
||||
}
|
||||
|
||||
void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
|
||||
{
|
||||
TreeView defaultTreeView;
|
||||
TreeView* const t = dynamic_cast<TreeView*> (component);
|
||||
|
||||
ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
|
||||
|
||||
if (defaultTreeView.isRootItemVisible() != t->isRootItemVisible())
|
||||
{
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setRootItemVisible ("
|
||||
<< CodeHelpers::boolLiteral (t->isRootItemVisible()) << ");\n";
|
||||
}
|
||||
|
||||
if (defaultTreeView.areItemsOpenByDefault() != t->areItemsOpenByDefault())
|
||||
{
|
||||
code.constructorCode
|
||||
<< memberVariableName << "->setDefaultOpenness ("
|
||||
<< CodeHelpers::boolLiteral (t->areItemsOpenByDefault()) << ");\n";
|
||||
}
|
||||
|
||||
code.constructorCode << getColourIntialisationCode (component, memberVariableName);
|
||||
code.constructorCode << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class DemoTreeView : public TreeView
|
||||
{
|
||||
public:
|
||||
DemoTreeView()
|
||||
: TreeView ("new treeview")
|
||||
{
|
||||
setRootItem (new DemoTreeViewItem ("Demo root node", 4));
|
||||
}
|
||||
|
||||
~DemoTreeView()
|
||||
{
|
||||
deleteRootItem();
|
||||
}
|
||||
|
||||
private:
|
||||
class DemoTreeViewItem : public TreeViewItem
|
||||
{
|
||||
public:
|
||||
DemoTreeViewItem (const String& name_, const int numItems)
|
||||
: name (name_)
|
||||
{
|
||||
for (int i = 0; i < numItems; ++i)
|
||||
addSubItem (new DemoTreeViewItem ("Demo sub-node " + String (i), numItems - 1));
|
||||
}
|
||||
|
||||
void paintItem (Graphics& g, int width, int height) override
|
||||
{
|
||||
if (isSelected())
|
||||
g.fillAll (Colours::lightblue);
|
||||
|
||||
g.setColour (Colours::black);
|
||||
g.setFont ((float) height * 0.7f);
|
||||
g.drawText (name, 4, 0, width - 4, height, Justification::centredLeft, true);
|
||||
}
|
||||
|
||||
bool mightContainSubItems() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const String name;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TreeViewRootItemProperty : public ComponentBooleanProperty <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeViewRootItemProperty (TreeView* comp, JucerDocument& doc)
|
||||
: ComponentBooleanProperty <TreeView> ("show root item", "Root item visible", "Root item visible", comp, doc)
|
||||
{
|
||||
}
|
||||
|
||||
void setState (bool newState)
|
||||
{
|
||||
document.perform (new TreeviewRootChangeAction (component, *document.getComponentLayout(), newState),
|
||||
"Change TreeView root item");
|
||||
}
|
||||
|
||||
bool getState() const
|
||||
{
|
||||
return component->isRootItemVisible();
|
||||
}
|
||||
|
||||
private:
|
||||
class TreeviewRootChangeAction : public ComponentUndoableAction <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeviewRootChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TreeView> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->isRootItemVisible();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRootItemVisible (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setRootItemVisible (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TreeViewRootOpennessProperty : public ComponentChoiceProperty <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeViewRootOpennessProperty (TreeView* comp, JucerDocument& doc)
|
||||
: ComponentChoiceProperty <TreeView> ("default openness", comp, doc)
|
||||
{
|
||||
choices.add ("Items open by default");
|
||||
choices.add ("Items closed by default");
|
||||
}
|
||||
|
||||
void setIndex (int newIndex)
|
||||
{
|
||||
document.perform (new TreeviewOpennessChangeAction (component, *document.getComponentLayout(), newIndex == 0),
|
||||
"Change TreeView openness");
|
||||
}
|
||||
|
||||
int getIndex() const
|
||||
{
|
||||
return component->areItemsOpenByDefault() ? 0 : 1;
|
||||
}
|
||||
|
||||
private:
|
||||
class TreeviewOpennessChangeAction : public ComponentUndoableAction <TreeView>
|
||||
{
|
||||
public:
|
||||
TreeviewOpennessChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
|
||||
: ComponentUndoableAction <TreeView> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->areItemsOpenByDefault();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setDefaultOpenness (newState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
getComponent()->setDefaultOpenness (oldState);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user