From e4ce3fef4ce00864162b246c062d83e5bcc29ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Mon, 10 Mar 2014 19:10:25 +0200 Subject: [PATCH] libappfw: Inverted "info style" for MessageDialog and ButtonWidget DialogContentStylist was also made somewhat more intelligent. --- .../include/de/dialogs/messagedialog.h | 2 + .../de/framework/dialogcontentstylist.h | 18 +++- .../include/de/widgets/auxbuttonwidget.h | 3 + .../include/de/widgets/buttonwidget.h | 6 +- .../include/de/widgets/dialogwidget.h | 3 +- .../libappfw/include/de/widgets/popupwidget.h | 4 + .../libappfw/src/dialogcontentstylist.cpp | 70 ++++++++++--- .../libappfw/src/dialogs/messagedialog.cpp | 15 +++ .../libappfw/src/widgets/auxbuttonwidget.cpp | 99 +++++++++++++++---- .../libappfw/src/widgets/buttonwidget.cpp | 26 ++++- .../libappfw/src/widgets/dialogwidget.cpp | 15 ++- doomsday/libappfw/src/widgets/popupwidget.cpp | 18 +++- doomsday/libdeng2/include/de/data/zeroed.h | 6 ++ 13 files changed, 234 insertions(+), 51 deletions(-) diff --git a/doomsday/libappfw/include/de/dialogs/messagedialog.h b/doomsday/libappfw/include/de/dialogs/messagedialog.h index d2b878a6c1..5dba93f2e1 100644 --- a/doomsday/libappfw/include/de/dialogs/messagedialog.h +++ b/doomsday/libappfw/include/de/dialogs/messagedialog.h @@ -31,6 +31,8 @@ class LIBAPPFW_PUBLIC MessageDialog : public DialogWidget public: MessageDialog(String const &name = ""); + void useInfoStyle(); + LabelWidget &title(); LabelWidget &message(); diff --git a/doomsday/libappfw/include/de/framework/dialogcontentstylist.h b/doomsday/libappfw/include/de/framework/dialogcontentstylist.h index b56d8bb2c8..e0bebc25c5 100644 --- a/doomsday/libappfw/include/de/framework/dialogcontentstylist.h +++ b/doomsday/libappfw/include/de/framework/dialogcontentstylist.h @@ -22,12 +22,11 @@ #include "../libappfw.h" #include "../ui/Stylist" -#include +#include namespace de { class DialogWidget; -class GuiWidget; /** * Sets the style for widgets in a dialog. @@ -43,15 +42,28 @@ class LIBAPPFW_PUBLIC DialogContentStylist ~DialogContentStylist(); + void clear(); + void setContainer(GuiWidget &container); + /** + * Adds a new container without detaching from the existing one(s). + * + * @param container New container to style. + */ + void addContainer(GuiWidget &container); + + void setInfoStyle(bool useInfoStyle); + + void setAdjustMargins(bool yes); + void applyStyle(GuiWidget &widget); // Observes when new children are added. void widgetChildAdded(Widget &child); private: - GuiWidget *_container; + DENG2_PRIVATE(d) }; } // namespace de diff --git a/doomsday/libappfw/include/de/widgets/auxbuttonwidget.h b/doomsday/libappfw/include/de/widgets/auxbuttonwidget.h index 266864276c..8b9784c8d7 100644 --- a/doomsday/libappfw/include/de/widgets/auxbuttonwidget.h +++ b/doomsday/libappfw/include/de/widgets/auxbuttonwidget.h @@ -36,6 +36,9 @@ class LIBAPPFW_PUBLIC AuxButtonWidget : public ButtonWidget void useNormalStyle(); void useInvertedStyle(); +protected: + void updateStyle(); + private: DENG2_PRIVATE(d) }; diff --git a/doomsday/libappfw/include/de/widgets/buttonwidget.h b/doomsday/libappfw/include/de/widgets/buttonwidget.h index ce7322fc57..cd7e4ca7ae 100644 --- a/doomsday/libappfw/include/de/widgets/buttonwidget.h +++ b/doomsday/libappfw/include/de/widgets/buttonwidget.h @@ -66,6 +66,10 @@ class LIBAPPFW_PUBLIC ButtonWidget : public LabelWidget ModulateColor }; + void useInfoStyle(); + + bool isUsingInfoStyle() const; + /** * Text color to use in the Hover state. The default is to use the normal text * color of the button (label). @@ -97,9 +101,9 @@ class LIBAPPFW_PUBLIC ButtonWidget : public LabelWidget void update(); bool handleEvent(Event const &event); - protected: void updateModelViewProjection(GLUniform &uMvp); + void updateStyle(); private: DENG2_PRIVATE(d) diff --git a/doomsday/libappfw/include/de/widgets/dialogwidget.h b/doomsday/libappfw/include/de/widgets/dialogwidget.h index da68c00700..5c2beef21d 100644 --- a/doomsday/libappfw/include/de/widgets/dialogwidget.h +++ b/doomsday/libappfw/include/de/widgets/dialogwidget.h @@ -26,6 +26,7 @@ namespace de { class GuiRootWidget; +class DialogContentStylist; /** * Popup dialog. @@ -151,7 +152,7 @@ class LIBAPPFW_PUBLIC DialogWidget : public PopupWidget * * @return Widget for dialog's extra buttons. */ - //MenuWidget &extraButtons(); + MenuWidget &extraButtonsMenu(); ui::Data &buttons(); diff --git a/doomsday/libappfw/include/de/widgets/popupwidget.h b/doomsday/libappfw/include/de/widgets/popupwidget.h index 48b9227ca7..b68fb0d069 100644 --- a/doomsday/libappfw/include/de/widgets/popupwidget.h +++ b/doomsday/libappfw/include/de/widgets/popupwidget.h @@ -84,6 +84,10 @@ class LIBAPPFW_PUBLIC PopupWidget : public PanelWidget */ void useInfoStyle(); + bool isUsingInfoStyle(); + + Background infoStyleBackground() const; + // Events. bool handleEvent(Event const &event); diff --git a/doomsday/libappfw/src/dialogcontentstylist.cpp b/doomsday/libappfw/src/dialogcontentstylist.cpp index ebbca8dc09..de4b78d537 100644 --- a/doomsday/libappfw/src/dialogcontentstylist.cpp +++ b/doomsday/libappfw/src/dialogcontentstylist.cpp @@ -22,39 +22,69 @@ #include "de/LabelWidget" #include "de/LineEditWidget" #include "de/AuxButtonWidget" +#include namespace de { -DialogContentStylist::DialogContentStylist() : _container(0) +DENG2_PIMPL_NOREF(DialogContentStylist) +{ + QList containers; + bool useInfoStyle; + bool adjustMargins; + + Instance() + : useInfoStyle(false) + , adjustMargins(true) + {} +}; + +DialogContentStylist::DialogContentStylist() : d(new Instance) {} -DialogContentStylist::DialogContentStylist(DialogWidget &dialog) : _container(0) +DialogContentStylist::DialogContentStylist(DialogWidget &dialog) : d(new Instance) { setContainer(dialog.area()); } -DialogContentStylist::DialogContentStylist(GuiWidget &container) : _container(0) +DialogContentStylist::DialogContentStylist(GuiWidget &container) : d(new Instance) { setContainer(container); } DialogContentStylist::~DialogContentStylist() { - if(_container) + clear(); +} + +void DialogContentStylist::clear() +{ + foreach(GuiWidget *w, d->containers) { - _container->audienceForChildAddition() -= this; + w->audienceForChildAddition() -= this; } + d->containers.clear(); } void DialogContentStylist::setContainer(GuiWidget &container) { - if(_container) - { - _container->audienceForChildAddition() -= this; - } + clear(); + addContainer(container); +} - _container = &container; - _container->audienceForChildAddition() += this; +void DialogContentStylist::addContainer(GuiWidget &container) +{ + d->containers << &container; + container.audienceForChildAddition() += this; +} + +void DialogContentStylist::setInfoStyle(bool useInfoStyle) +{ + d->useInfoStyle = useInfoStyle; +} + +void DialogContentStylist::setAdjustMargins(bool yes) +{ + d->adjustMargins = yes; } void DialogContentStylist::widgetChildAdded(Widget &child) @@ -64,9 +94,12 @@ void DialogContentStylist::widgetChildAdded(Widget &child) void DialogContentStylist::applyStyle(GuiWidget &w) { - if(!w.is()) + if(d->adjustMargins) { - w.margins().set("dialog.gap"); + if(!w.is()) + { + w.margins().set("dialog.gap"); + } } // All label-based widgets should expand on their own. @@ -75,6 +108,15 @@ void DialogContentStylist::applyStyle(GuiWidget &w) lab->setSizePolicy(ui::Expand, ui::Expand); } + // Button background override? + if(ButtonWidget *but = w.maybeAs()) + { + if(d->useInfoStyle) + { + but->useInfoStyle(); + } + } + // Toggles should have no background. if(ToggleWidget *tog = w.maybeAs()) { @@ -83,7 +125,7 @@ void DialogContentStylist::applyStyle(GuiWidget &w) if(LineEditWidget *ed = w.maybeAs()) { - ed->rule().setInput(Rule::Width, _container->style().rules().rule("editor.width")); + ed->rule().setInput(Rule::Width, d->containers.first()->style().rules().rule("editor.width")); } } diff --git a/doomsday/libappfw/src/dialogs/messagedialog.cpp b/doomsday/libappfw/src/dialogs/messagedialog.cpp index dee9a709b7..dc0fe01cbc 100644 --- a/doomsday/libappfw/src/dialogs/messagedialog.cpp +++ b/doomsday/libappfw/src/dialogs/messagedialog.cpp @@ -18,6 +18,7 @@ #include "de/MessageDialog" #include "de/SequentialLayout" +#include "de/DialogContentStylist" namespace de { @@ -27,6 +28,7 @@ DENG_GUI_PIMPL(MessageDialog) { LabelWidget *title; LabelWidget *message; + DialogContentStylist buttonStylist; Instance(Public *i) : Base(i) { @@ -73,6 +75,19 @@ MessageDialog::MessageDialog(String const &name) , d(new Instance(this)) {} +void MessageDialog::useInfoStyle() +{ + DialogWidget::useInfoStyle(); + + title().setTextColor("inverted.accent"); + message().setTextColor("inverted.text"); + + d->buttonStylist.addContainer(buttonsMenu()); + d->buttonStylist.addContainer(extraButtonsMenu()); + d->buttonStylist.setAdjustMargins(false); + d->buttonStylist.setInfoStyle(true); +} + LabelWidget &MessageDialog::title() { return *d->title; diff --git a/doomsday/libappfw/src/widgets/auxbuttonwidget.cpp b/doomsday/libappfw/src/widgets/auxbuttonwidget.cpp index bb832ce139..6327564b01 100644 --- a/doomsday/libappfw/src/widgets/auxbuttonwidget.cpp +++ b/doomsday/libappfw/src/widgets/auxbuttonwidget.cpp @@ -24,8 +24,11 @@ DENG_GUI_PIMPL(AuxButtonWidget) , DENG2_OBSERVES(ButtonWidget, StateChange) { ButtonWidget *aux; + bool inverted; - Instance(Public *i) : Base(i) + Instance(Public *i) + : Base(i) + , inverted(false) { self.add(aux = new ButtonWidget); aux->setFont("small"); @@ -57,22 +60,82 @@ DENG_GUI_PIMPL(AuxButtonWidget) switch(state) { case ButtonWidget::Up: - setAuxBorderColorf(style().colors().colorf("accent")); - aux->setTextColor("accent"); + if(!isInverted()) + { + setAuxBorderColorf(style().colors().colorf("accent")); + aux->setTextColor("accent"); + } + else + { + setAuxBorderColorf(style().colors().colorf("inverted.accent")); + aux->setTextColor("inverted.accent"); + } break; case ButtonWidget::Hover: - setAuxBorderColorf(style().colors().colorf("text")); - aux->setTextColor("text"); + if(!isInverted()) + { + setAuxBorderColorf(style().colors().colorf("text")); + aux->setTextColor("text"); + } + else + { + setAuxBorderColorf(style().colors().colorf("inverted.text")); + aux->setTextColor("inverted.text"); + } break; case ButtonWidget::Down: - setAuxBorderColorf(style().colors().colorf(""), - style().colors().colorf("inverted.background")); - aux->setTextColor("inverted.text"); + if(!isInverted()) + { + setAuxBorderColorf(style().colors().colorf(""), + style().colors().colorf("inverted.background")); + aux->setTextColor("inverted.text"); + } + else + { + setAuxBorderColorf(style().colors().colorf(""), + style().colors().colorf("background")); + aux->setTextColor("text"); + } break; } } + + bool isInverted() const + { + return inverted ^ self.isUsingInfoStyle(); + } + + void updateStyle() + { + if(isInverted()) + { + applyInvertedStyle(); + } + else + { + applyNormalStyle(); + } + } + + void applyNormalStyle() + { + self.setBackgroundColor("background"); + self.setTextColor("text"); + aux->setTextColor("accent"); + aux->setHoverTextColor("text", ButtonWidget::ReplaceColor); + setAuxBorderColorf(style().colors().colorf("accent")); + } + + void applyInvertedStyle() + { + self.setBackgroundColor("inverted.background"); + self.setTextColor("inverted.text"); + aux->setTextColor("inverted.text"); + aux->setHoverTextColor("inverted.text", ButtonWidget::ReplaceColor); + setAuxBorderColorf(style().colors().colorf("inverted.text")); + } }; AuxButtonWidget::AuxButtonWidget(String const &name) @@ -88,20 +151,20 @@ ButtonWidget &AuxButtonWidget::auxiliary() void AuxButtonWidget::useNormalStyle() { - setBackgroundColor("background"); - setTextColor("text"); - d->aux->setTextColor("accent"); - d->aux->setHoverTextColor("text", ButtonWidget::ReplaceColor); - d->setAuxBorderColorf(style().colors().colorf("accent")); + d->inverted = false; + d->updateStyle(); } void AuxButtonWidget::useInvertedStyle() { - setBackgroundColor("inverted.background"); - setTextColor("inverted.text"); - d->aux->setTextColor("inverted.text"); - d->aux->setHoverTextColor("inverted.text", ButtonWidget::ReplaceColor); - d->setAuxBorderColorf(style().colors().colorf("inverted.text")); + d->inverted = true; + d->updateStyle(); +} + +void AuxButtonWidget::updateStyle() +{ + ButtonWidget::updateStyle(); + //d->updateStyle(); } } // namespace de diff --git a/doomsday/libappfw/src/widgets/buttonwidget.cpp b/doomsday/libappfw/src/widgets/buttonwidget.cpp index 13c319ca67..390df3df06 100644 --- a/doomsday/libappfw/src/widgets/buttonwidget.cpp +++ b/doomsday/libappfw/src/widgets/buttonwidget.cpp @@ -32,6 +32,7 @@ DENG2_OBSERVES(Action, Triggered) DotPath originalTextColor; DotPath bgColorId; HoverColorMode hoverColorMode; + bool infoStyle; Action *action; Animation scale; Animation frameOpacity; @@ -42,6 +43,7 @@ DENG2_OBSERVES(Action, Triggered) , state(Up) , bgColorId("background") , hoverColorMode(ReplaceColor) + , infoStyle(false) , action(0) , scale(1.f) , frameOpacity(.08f, Animation::Linear) @@ -150,7 +152,9 @@ DENG2_OBSERVES(Action, Triggered) if(bg.type == Background::GradientFrame) { bg.solidFill = style().colors().colorf(bgColorId); - bg.color = Vector4f(1, 1, 1, frameOpacity); + /// @todo Make this Style-able. -jk + bg.color = infoStyle? Vector4f(0, 0, 0, frameOpacity) : + Vector4f(1, 1, 1, frameOpacity); self.set(bg); } } @@ -188,6 +192,20 @@ DENG2_AUDIENCE_METHOD(ButtonWidget, Triggered) ButtonWidget::ButtonWidget(String const &name) : LabelWidget(name), d(new Instance(this)) {} +void ButtonWidget::useInfoStyle() +{ + d->infoStyle = true; + setTextColor("inverted.text"); + setHoverTextColor("inverted.text", ReplaceColor); + setBackgroundColor("inverted.background"); + updateStyle(); +} + +bool ButtonWidget::isUsingInfoStyle() const +{ + return d->infoStyle; +} + void ButtonWidget::setHoverTextColor(DotPath const &hoverTextId, HoverColorMode mode) { d->hoverTextColor = hoverTextId; @@ -296,6 +314,12 @@ void ButtonWidget::updateModelViewProjection(GLUniform &uMvp) } } +void ButtonWidget::updateStyle() +{ + LabelWidget::updateStyle(); + d->updateBackground(); +} + void ButtonWidget::update() { LabelWidget::update(); diff --git a/doomsday/libappfw/src/widgets/dialogwidget.cpp b/doomsday/libappfw/src/widgets/dialogwidget.cpp index 0257a07635..019c844f99 100644 --- a/doomsday/libappfw/src/widgets/dialogwidget.cpp +++ b/doomsday/libappfw/src/widgets/dialogwidget.cpp @@ -389,7 +389,11 @@ public ChildWidgetOrganizer::IFilter void updateBackground() { Background bg = self.background(); - if(Style::appStyle().isBlurringAllowed()) + if(self.isUsingInfoStyle()) + { + bg = self.infoStyleBackground(); + } + else if(Style::appStyle().isBlurringAllowed()) { /// @todo Should use the Style for this. bg.type = Background::BlurredWithBorderGlow; @@ -433,17 +437,10 @@ MenuWidget &DialogWidget::buttonsMenu() return *d->buttons; } -/* -MenuWidget &DialogWidget::buttons() -{ - return *d->buttons; -} - -MenuWidget &DialogWidget::extraButtons() +MenuWidget &DialogWidget::extraButtonsMenu() { return *d->extraButtons; } -*/ ui::Data &DialogWidget::buttons() { diff --git a/doomsday/libappfw/src/widgets/popupwidget.cpp b/doomsday/libappfw/src/widgets/popupwidget.cpp index 7b820ceb5d..959ae14444 100644 --- a/doomsday/libappfw/src/widgets/popupwidget.cpp +++ b/doomsday/libappfw/src/widgets/popupwidget.cpp @@ -130,10 +130,7 @@ DENG_GUI_PIMPL(PopupWidget) if(useInfoStyle) { - self.set(Background(st.colors().colorf("popup.info.background"), - Background::BorderGlow, - st.colors().colorf("popup.info.glow"), - st.rules().rule("glow").valuei())); + self.set(self.infoStyleBackground()); } else { @@ -267,6 +264,19 @@ void PopupWidget::useInfoStyle() d->updateStyle(); } +bool PopupWidget::isUsingInfoStyle() +{ + return d->useInfoStyle; +} + +GuiWidget::Background PopupWidget::infoStyleBackground() const +{ + return Background(style().colors().colorf("popup.info.background"), + Background::BorderGlow, + style().colors().colorf("popup.info.glow"), + style().rules().rule("glow").valuei()); +} + bool PopupWidget::handleEvent(Event const &event) { if(!isOpen()) return false; diff --git a/doomsday/libdeng2/include/de/data/zeroed.h b/doomsday/libdeng2/include/de/data/zeroed.h index 2afb2dcae4..f80986812c 100644 --- a/doomsday/libdeng2/include/de/data/zeroed.h +++ b/doomsday/libdeng2/include/de/data/zeroed.h @@ -40,6 +40,12 @@ class Zeroed value = v; return *this; } + Type operator -> () { + return value; + } + Type const operator -> () const { + return value; + } public: Type value;