From 313ed0004a818e1104562c262b0c1561d6415621 Mon Sep 17 00:00:00 2001 From: jules Date: Fri, 16 Nov 2007 19:12:38 +0000 Subject: [PATCH] --- extras/the jucer/build/vc8/jucer.vcproj | 8 +- .../components/jucer_ImageButtonHandler.h | 554 ++++++++++++++++++ .../src/model/jucer_ComponentLayout.h | 4 +- .../the jucer/src/model/jucer_ObjectTypes.cpp | 3 + .../jucer_ImageResourceProperty.h | 44 +- 5 files changed, 600 insertions(+), 13 deletions(-) create mode 100644 extras/the jucer/src/model/components/jucer_ImageButtonHandler.h diff --git a/extras/the jucer/build/vc8/jucer.vcproj b/extras/the jucer/build/vc8/jucer.vcproj index 8af2a09851..d31e192223 100644 --- a/extras/the jucer/build/vc8/jucer.vcproj +++ b/extras/the jucer/build/vc8/jucer.vcproj @@ -315,6 +315,10 @@ RelativePath="..\..\src\model\components\jucer_ButtonHandler.h" > + + @@ -387,10 +391,6 @@ - - diff --git a/extras/the jucer/src/model/components/jucer_ImageButtonHandler.h b/extras/the jucer/src/model/components/jucer_ImageButtonHandler.h new file mode 100644 index 0000000000..b84535dd02 --- /dev/null +++ b/extras/the jucer/src/model/components/jucer_ImageButtonHandler.h @@ -0,0 +1,554 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCER_TEXTBUTTONHANDLER_JUCEHEADER__x +#define __JUCER_TEXTBUTTONHANDLER_JUCEHEADER__x + +#include "jucer_ButtonHandler.h" +#include "../../properties/jucer_ComponentColourProperty.h" +#include "../paintelements/jucer_ImageResourceProperty.h" + + +//============================================================================== +/** +*/ +class ImageButtonHandler : public ButtonHandler +{ +public: + enum ImageRole + { + normalImage = 0, + overImage = 1, + downImage = 2 + }; + + //============================================================================== + ImageButtonHandler() + : ButtonHandler ("Image Button", "ImageButton", typeid (ImageButton), 150, 24) + { + } + + //============================================================================== + Component* createNewComponent (JucerDocument*) + { + return new ImageButton (T("new button")); + } + + void getEditableProperties (Component* component, JucerDocument& document, Array & properties) + { + ButtonHandler::getEditableProperties (component, document, properties); + + addColourProperties (component, document, properties); + + ImageButton* const ib = (ImageButton*) component; + + ComponentLayout& layout = *document.getComponentLayout(); + + properties.add (new ImageButtonProportionProperty (layout, ib)); + + properties.add (new ImageButtonResourceProperty (layout, ib, normalImage, "normal image")); + properties.add (new ImageButtonOpacityProperty (layout, ib, "opacity", normalImage)); + properties.add (new ImageButtonColourProperty (layout, ib, "overlay col.", normalImage)); + + properties.add (new ImageButtonResourceProperty (layout, ib, overImage, "over image")); + properties.add (new ImageButtonOpacityProperty (layout, ib, "opacity", overImage)); + properties.add (new ImageButtonColourProperty (layout, ib, "overlay col.", overImage)); + + properties.add (new ImageButtonResourceProperty (layout, ib, downImage, "down image")); + properties.add (new ImageButtonOpacityProperty (layout, ib, "opacity", downImage)); + properties.add (new ImageButtonColourProperty (layout, ib, "overlay col.", downImage)); + } + + XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) + { + XmlElement* e = ButtonHandler::createXmlFor (comp, layout); + + ImageButton* const ib = (ImageButton*) comp; + + e->setAttribute (T("keepProportions"), doesImageKeepProportions (ib)); + + e->setAttribute (T("resourceNormal"), getImageResource (ib, normalImage)); + e->setAttribute (T("opacityNormal"), getImageOpacity (ib, normalImage)); + e->setAttribute (T("colourNormal"), getImageColour (ib, normalImage).toString()); + + e->setAttribute (T("resourceOver"), getImageResource (ib, overImage)); + e->setAttribute (T("opacityOver"), getImageOpacity (ib, overImage)); + e->setAttribute (T("colourOver"), getImageColour (ib, overImage).toString()); + + e->setAttribute (T("resourceDown"), getImageResource (ib, downImage)); + e->setAttribute (T("opacityDown"), getImageOpacity (ib, downImage)); + e->setAttribute (T("colourDown"), getImageColour (ib, downImage).toString()); + + return e; + } + + bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) + { + if (! ButtonHandler::restoreFromXml (xml, comp, layout)) + return false; + + ImageButton* const ib = (ImageButton*) comp; + ComponentLayout& l = const_cast (*layout); + + setImageKeepProportions (l, ib, xml.getBoolAttribute (T("keepProportions"), true), false); + + setImageResource (l, ib, normalImage, xml.getStringAttribute (T("resourceNormal"), String::empty), false); + setImageOpacity (l, ib, normalImage, (float) xml.getDoubleAttribute (T("opacityNormal"), 1.0f), false); + setImageColour (l, ib, normalImage, Colour::fromString (xml.getStringAttribute (T("colourNormal"), T("0"))), false); + + setImageResource (l, ib, overImage, xml.getStringAttribute (T("resourceOver"), String::empty), false); + setImageOpacity (l, ib, overImage, (float) xml.getDoubleAttribute (T("opacityOver"), 1.0f), false); + setImageColour (l, ib, overImage, Colour::fromString (xml.getStringAttribute (T("colourOver"), T("0"))), false); + + setImageResource (l, ib, downImage, xml.getStringAttribute (T("resourceDown"), String::empty), false); + setImageOpacity (l, ib, downImage, (float) xml.getDoubleAttribute (T("opacityDown"), 1.0f), false); + setImageColour (l, ib, downImage, Colour::fromString (xml.getStringAttribute (T("colourDown"), T("0"))), false); + + return true; + } + + void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) + { + ButtonHandler::fillInCreationCode (code, component, memberVariableName); + + ImageButton* const ib = dynamic_cast (component); + + String s; + + s << getColourIntialisationCode (component, memberVariableName) + << T('\n'); + + const String indent (String::repeatedString (T(" "), memberVariableName.length() + 13)); + + s << memberVariableName << "->setImages (false, true, " + << boolToString (doesImageKeepProportions (ib)) << ",\n" + << indent + << getImageCreationCode (ib, normalImage) << ", " + << valueToFloat (getImageOpacity (ib, normalImage)) << ", " + << colourToCode (getImageColour (ib, normalImage)) << ",\n" + << indent + << getImageCreationCode (ib, overImage) << ", " + << valueToFloat (getImageOpacity (ib, overImage)) << ", " + << colourToCode (getImageColour (ib, overImage)) << ",\n" + << indent + << getImageCreationCode (ib, downImage) << ", " + << valueToFloat (getImageOpacity (ib, downImage)) << ", " + << colourToCode (getImageColour (ib, downImage)) + << ");\n"; + + code.constructorCode += s; + } + + static const String getImageCreationCode (ImageButton* ib, const ImageRole role) + { + const String resName (getImageResource (ib, role)); + + if (resName.isEmpty()) + return "0"; + + return "ImageCache::getFromMemory (" + resName + ", " + resName + "Size)"; + } + + //============================================================================== + class ImageButtonResourceProperty : public ImageResourceProperty + { + public: + ImageButtonResourceProperty (ComponentLayout& layout_, ImageButton* const owner_, const ImageRole role_, const String& name) + : ImageResourceProperty (*layout_.getDocument(), owner_, name, true), + role (role_), + layout (layout_) + { + } + + //============================================================================== + void setResource (const String& newName) + { + setImageResource (layout, element, role, newName, true); + } + + const String getResource() const + { + return getImageResource (element, role); + } + + private: + const ImageRole role; + ComponentLayout& layout; + }; + + class SetImageResourceAction : public ComponentUndoableAction + { + public: + SetImageResourceAction (ImageButton* const button, + ComponentLayout& layout_, + const ImageRole role_, + const String& newResource_) + : ComponentUndoableAction (button, layout_), + newResource (newResource_), + role (role_), + layout (layout_) + { + oldResource = ImageButtonHandler::getImageResource (button, role_); + } + + bool perform() + { + showCorrectTab(); + ImageButtonHandler::setImageResource (layout, getComponent(), role, newResource, false); + return true; + } + + bool undo() + { + showCorrectTab(); + ImageButtonHandler::setImageResource (layout, getComponent(), role, oldResource, false); + return true; + } + + private: + String newResource, oldResource; + const ImageRole role; + ComponentLayout& layout; + }; + + //============================================================================== + static void setImageResource (ComponentLayout& layout, ImageButton* button, const ImageRole role, const String& newName, const bool undoable) + { + jassert (role < 3); + + if (role < 3 && getImageResource (button, role) != newName) + { + if (undoable) + { + layout.getDocument()->perform (new SetImageResourceAction (button, layout, role, newName), + T("Change image resource")); + } + else + { + button->setComponentProperty ("resource" + String ((int) role), newName); + updateButtonImages (*layout.getDocument(), button); + layout.changed(); + } + } + } + + static const String getImageResource (ImageButton* button, const ImageRole role) + { + jassert (role < 3); + return button->getComponentProperty ("resource" + String ((int) role), false); + } + + //============================================================================== + class SetImageKeepsPropAction : public ComponentUndoableAction + { + public: + SetImageKeepsPropAction (ImageButton* const button, + ComponentLayout& layout_, + const bool newState_) + : ComponentUndoableAction (button, layout_), + layout (layout_), + newState (newState_) + { + oldState = ImageButtonHandler::doesImageKeepProportions (button); + } + + bool perform() + { + showCorrectTab(); + ImageButtonHandler::setImageKeepProportions (layout, getComponent(), newState, false); + return true; + } + + bool undo() + { + showCorrectTab(); + ImageButtonHandler::setImageKeepProportions (layout, getComponent(), oldState, false); + return true; + } + + private: + bool newState, oldState; + ComponentLayout& layout; + }; + + static bool doesImageKeepProportions (ImageButton* button) + { + return button->getComponentPropertyBool ("keepImageProp", false, true); + } + + static void setImageKeepProportions (ComponentLayout& layout, ImageButton* button, const bool newState, const bool undoable) + { + if (undoable) + { + layout.perform (new SetImageKeepsPropAction (button, layout, newState), "change imagebutton proportion mode"); + } + else + { + button->setComponentProperty ("keepImageProp", newState); + updateButtonImages (*layout.getDocument(), button); + layout.changed(); + } + } + + class ImageButtonProportionProperty : public ComponentBooleanProperty + { + public: + ImageButtonProportionProperty (ComponentLayout& layout_, ImageButton* const owner_) + : ComponentBooleanProperty ("proportional", "maintain image proportions", "scale to fit", + owner_, *layout_.getDocument()), + layout (layout_) + { + } + + //============================================================================== + void setState (const bool newState) + { + setImageKeepProportions (layout, component, newState, true); + } + + bool getState() const + { + return doesImageKeepProportions (component); + } + + private: + ComponentLayout& layout; + }; + + //============================================================================== + class SetImageOpacityAction : public ComponentUndoableAction + { + public: + SetImageOpacityAction (ImageButton* const button, + ComponentLayout& layout_, + const ImageRole role_, + const float newState_) + : ComponentUndoableAction (button, layout_), + role (role_), + layout (layout_), + newState (newState_) + { + oldState = ImageButtonHandler::getImageOpacity (button, role_); + } + + bool perform() + { + showCorrectTab(); + ImageButtonHandler::setImageOpacity (layout, getComponent(), role, newState, false); + return true; + } + + bool undo() + { + showCorrectTab(); + ImageButtonHandler::setImageOpacity (layout, getComponent(), role, oldState, false); + return true; + } + + private: + const ImageRole role; + float newState, oldState; + ComponentLayout& layout; + }; + + static float getImageOpacity (ImageButton* button, const ImageRole role) + { + return (float) button->getComponentPropertyDouble ("imageOpacity" + String ((int) role), false, 1.0f); + } + + static void setImageOpacity (ComponentLayout& layout, ImageButton* button, const ImageRole role, const float opacity, const bool undoable) + { + if (undoable) + { + layout.perform (new SetImageOpacityAction (button, layout, role, opacity), "change imagebutton opacity"); + } + else + { + button->setComponentProperty ("imageOpacity" + String ((int) role), opacity); + updateButtonImages (*layout.getDocument(), button); + layout.changed(); + } + } + + class ImageButtonOpacityProperty : public SliderPropertyComponent + { + public: + ImageButtonOpacityProperty (ComponentLayout& layout_, ImageButton* const owner_, + const String& name, const ImageRole role_) + : SliderPropertyComponent (name, 0.0, 1.0, 0.0), + owner (owner_), + layout (layout_), + role (role_) + { + } + + //============================================================================== + void setValue (const double newValue) + { + setImageOpacity (layout, owner, role, (float) newValue, true); + } + + const double getValue() const + { + return getImageOpacity (owner, role); + } + + private: + ImageButton* const owner; + ComponentLayout& layout; + const ImageRole role; + }; + + //============================================================================== + class SetImageColourAction : public ComponentUndoableAction + { + public: + SetImageColourAction (ImageButton* const button, + ComponentLayout& layout_, + const ImageRole role_, + const Colour& newState_) + : ComponentUndoableAction (button, layout_), + role (role_), + layout (layout_), + newState (newState_) + { + oldState = ImageButtonHandler::getImageColour (button, role_); + } + + bool perform() + { + showCorrectTab(); + ImageButtonHandler::setImageColour (layout, getComponent(), role, newState, false); + return true; + } + + bool undo() + { + showCorrectTab(); + ImageButtonHandler::setImageColour (layout, getComponent(), role, oldState, false); + return true; + } + + private: + const ImageRole role; + Colour newState, oldState; + ComponentLayout& layout; + }; + + static const Colour getImageColour (ImageButton* button, const ImageRole role) + { + return Colour::fromString (button->getComponentProperty ("imageColour" + String ((int) role), "0")); + } + + static void setImageColour (ComponentLayout& layout, ImageButton* button, const ImageRole role, const Colour& colour, const bool undoable) + { + if (undoable) + { + layout.perform (new SetImageColourAction (button, layout, role, colour), "change imagebutton colour"); + } + else + { + button->setComponentProperty ("imageColour" + String ((int) role), colour.toString()); + updateButtonImages (*layout.getDocument(), button); + layout.changed(); + } + } + + class ImageButtonColourProperty : public ColourPropertyComponent, + public ChangeListener + { + public: + ImageButtonColourProperty (ComponentLayout& layout_, ImageButton* const owner_, + const String& name, const ImageRole role_) + : ColourPropertyComponent (name, false), + owner (owner_), + layout (layout_), + role (role_) + { + layout_.getDocument()->addChangeListener (this); + } + + ~ImageButtonColourProperty() + { + layout.getDocument()->removeChangeListener (this); + } + + //============================================================================== + void setColour (const Colour& newColour) + { + setImageColour (layout, owner, role, newColour, true); + } + + const Colour getColour() const + { + return getImageColour (owner, role); + } + + void resetToDefault() {} + + void changeListenerCallback (void*) + { + refresh(); + } + + private: + ImageButton* const owner; + ComponentLayout& layout; + const ImageRole role; + }; + + //============================================================================== + static void updateButtonImages (JucerDocument& document, ImageButton* const ib) + { + Image* norm = document.getResources().getImageFromCache (getImageResource (ib, normalImage)); + Image* over = document.getResources().getImageFromCache (getImageResource (ib, overImage)); + Image* down = document.getResources().getImageFromCache (getImageResource (ib, downImage)); + + ib->setImages (false, true, doesImageKeepProportions (ib), + norm, + getImageOpacity (ib, normalImage), + getImageColour (ib, normalImage), + over, + getImageOpacity (ib, overImage), + getImageColour (ib, overImage), + down, + getImageOpacity (ib, downImage), + getImageColour (ib, downImage)); + } + + //============================================================================== + juce_UseDebuggingNewOperator + +private: +}; + + +#endif // __JUCER_TEXTBUTTONHANDLER_JUCEHEADER__ diff --git a/extras/the jucer/src/model/jucer_ComponentLayout.h b/extras/the jucer/src/model/jucer_ComponentLayout.h index 1207919af8..b57c3b7a6d 100644 --- a/extras/the jucer/src/model/jucer_ComponentLayout.h +++ b/extras/the jucer/src/model/jucer_ComponentLayout.h @@ -120,6 +120,8 @@ public: void fillInGeneratedCode (GeneratedCode& code) const; + void perform (UndoableAction* action, const String& actionName); + private: JucerDocument* document; OwnedArray components; @@ -128,8 +130,6 @@ private: const String getUnusedMemberName (String nameRoot, Component* comp) const; - void perform (UndoableAction* action, const String& actionName); - friend class FrontBackCompAction; friend class DeleteCompAction; void moveComponentZOrder (int oldIndex, int newIndex); diff --git a/extras/the jucer/src/model/jucer_ObjectTypes.cpp b/extras/the jucer/src/model/jucer_ObjectTypes.cpp index b229b4ced5..aeb51b4749 100644 --- a/extras/the jucer/src/model/jucer_ObjectTypes.cpp +++ b/extras/the jucer/src/model/jucer_ObjectTypes.cpp @@ -58,6 +58,7 @@ #include "components/jucer_TabbedComponentHandler.h" #include "components/jucer_TreeViewHandler.h" #include "components/jucer_GenericComponentHandler.h" +#include "components/jucer_ImageButtonHandler.h" namespace ObjectTypes { @@ -257,6 +258,7 @@ static ViewportHandler viewport; static TabbedComponentHandler tabbedComp; static TreeViewHandler treeview; static GenericComponentHandler genericHandler; +static ImageButtonHandler imageButtonHandler; static ComponentTypeHandler* const compTypes[] = { @@ -273,6 +275,7 @@ static ComponentTypeHandler* const compTypes[] = &tabbedComp, &treeview, &genericHandler, + &imageButtonHandler, 0 }; diff --git a/extras/the jucer/src/model/paintelements/jucer_ImageResourceProperty.h b/extras/the jucer/src/model/paintelements/jucer_ImageResourceProperty.h index a165def6af..ebd0d893cf 100644 --- a/extras/the jucer/src/model/paintelements/jucer_ImageResourceProperty.h +++ b/extras/the jucer/src/model/paintelements/jucer_ImageResourceProperty.h @@ -43,20 +43,45 @@ class ImageResourceProperty : public ChoicePropertyComponent, private ChangeListener { public: - ImageResourceProperty (ElementType* const element_, const String& name) + ImageResourceProperty (JucerDocument& document_, + ElementType* const element_, + const String& name, + const bool allowChoiceOfNoResource_) : ChoicePropertyComponent (name), - element (element_) + element (element_), + document (document_), + allowChoiceOfNoResource (allowChoiceOfNoResource_) { choices.add (T("-- create a new image resource -- ")); choices.add (String::empty); - choices.addArray (element_->getDocument()->getResources().getResourceNames()); + if (allowChoiceOfNoResource_) + choices.add (T("<< none >>")); + choices.addArray (document_.getResources().getResourceNames()); - element_->getDocument()->addChangeListener (this); + document_.addChangeListener (this); + } + + ImageResourceProperty (ElementType* const element_, + const String& name, + const bool allowChoiceOfNoResource_ = false) + : ChoicePropertyComponent (name), + element (element_), + document (*element_->getDocument()), + allowChoiceOfNoResource (allowChoiceOfNoResource_) + { + choices.add (T("-- create a new image resource -- ")); + choices.add (String::empty); + if (allowChoiceOfNoResource_) + choices.add (T("<< none >>")); + + choices.addArray (document.getResources().getResourceNames()); + + document.addChangeListener (this); } ~ImageResourceProperty() { - element->getDocument()->removeChangeListener (this); + document.removeChangeListener (this); } //============================================================================== @@ -69,7 +94,7 @@ public: { if (newIndex == 0) { - String resource (element->getDocument()->getResources() + String resource (document.getResources() .browseForResource (T("Select an image file to add as a resource"), T("*.jpg;*.jpeg;*.png;*.gif;*.svg"), File::nonexistent, @@ -80,7 +105,10 @@ public: } else { - setResource (choices [newIndex]); + if (choices[newIndex] == T("<< none >>") && allowChoiceOfNoResource) + setResource (String::empty); + else + setResource (choices [newIndex]); } } @@ -99,6 +127,8 @@ public: protected: ElementType* const element; + JucerDocument& document; + const bool allowChoiceOfNoResource; };