From b024b9df44b4a95600bde12945a8abe2808ea61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Wed, 27 Jul 2016 14:16:20 +0300 Subject: [PATCH] Widgets: Setting input focus depending on the context Added a method for offering focus to widgets. This is used for setting the appropriate focus when a popup is opened (e.g., menu, dialog). IssueID #2131 --- .../libappfw/include/de/widgets/dialogwidget.h | 7 ++++--- .../libappfw/include/de/widgets/menuwidget.h | 5 +++-- .../include/de/widgets/popupmenuwidget.h | 9 +++++---- .../libappfw/include/de/widgets/popupwidget.h | 11 ++++++----- .../sdk/libappfw/src/widgets/dialogwidget.cpp | 7 +++++-- .../sdk/libappfw/src/widgets/focuswidget.cpp | 18 +----------------- .../sdk/libappfw/src/widgets/menuwidget.cpp | 16 ++++++++++++++++ .../libappfw/src/widgets/popupmenuwidget.cpp | 5 +++++ .../sdk/libappfw/src/widgets/popupwidget.cpp | 13 +++++++++---- .../sdk/libcore/include/de/widgets/widget.h | 1 + doomsday/sdk/libcore/src/widgets/widget.cpp | 3 +++ 11 files changed, 58 insertions(+), 37 deletions(-) diff --git a/doomsday/sdk/libappfw/include/de/widgets/dialogwidget.h b/doomsday/sdk/libappfw/include/de/widgets/dialogwidget.h index cf474a7a75..89b527b14a 100644 --- a/doomsday/sdk/libappfw/include/de/widgets/dialogwidget.h +++ b/doomsday/sdk/libappfw/include/de/widgets/dialogwidget.h @@ -230,8 +230,9 @@ class LIBAPPFW_PUBLIC DialogWidget : public PopupWidget ui::ActionItem *defaultActionItem(); // Events. - void update(); - bool handleEvent(Event const &event); + void offerFocus() override; + void update() override; + bool handleEvent(Event const &event) override; public slots: void accept(int result = 1); @@ -242,7 +243,7 @@ public slots: void rejected(int result); protected: - void preparePanelForOpening(); + void preparePanelForOpening() override; /** * Derived classes can override this to do additional tasks before diff --git a/doomsday/sdk/libappfw/include/de/widgets/menuwidget.h b/doomsday/sdk/libappfw/include/de/widgets/menuwidget.h index 98d9d3d872..70e58434bc 100644 --- a/doomsday/sdk/libappfw/include/de/widgets/menuwidget.h +++ b/doomsday/sdk/libappfw/include/de/widgets/menuwidget.h @@ -173,8 +173,9 @@ class LIBAPPFW_PUBLIC MenuWidget : public ScrollAreaWidget, public IAssetGroup Rule const &contentHeight() const; // Events. - void update(); - bool handleEvent(Event const &event); + void offerFocus() override; + void update() override; + bool handleEvent(Event const &event) override; public slots: void dismissPopups(); diff --git a/doomsday/sdk/libappfw/include/de/widgets/popupmenuwidget.h b/doomsday/sdk/libappfw/include/de/widgets/popupmenuwidget.h index f5373696aa..ef62a710c9 100644 --- a/doomsday/sdk/libappfw/include/de/widgets/popupmenuwidget.h +++ b/doomsday/sdk/libappfw/include/de/widgets/popupmenuwidget.h @@ -44,12 +44,13 @@ class LIBAPPFW_PUBLIC PopupMenuWidget : public PopupWidget void setColorTheme(ColorTheme theme); // Events. - void update(); + void offerFocus() override; + void update() override; protected: - void glMakeGeometry(DefaultVertexBuf::Builder &verts); - void preparePanelForOpening(); - void panelClosing(); + void glMakeGeometry(DefaultVertexBuf::Builder &verts) override; + void preparePanelForOpening() override; + void panelClosing() override; private: DENG2_PRIVATE(d) diff --git a/doomsday/sdk/libappfw/include/de/widgets/popupwidget.h b/doomsday/sdk/libappfw/include/de/widgets/popupwidget.h index 59654649b3..79165b0a0a 100644 --- a/doomsday/sdk/libappfw/include/de/widgets/popupwidget.h +++ b/doomsday/sdk/libappfw/include/de/widgets/popupwidget.h @@ -112,14 +112,15 @@ class LIBAPPFW_PUBLIC PopupWidget : public PanelWidget ButtonWidget &closeButton(); // Events. - bool handleEvent(Event const &event); + void offerFocus() override; + bool handleEvent(Event const &event) override; protected: - void glMakeGeometry(DefaultVertexBuf::Builder &verts); - void updateStyle(); + void glMakeGeometry(DefaultVertexBuf::Builder &verts) override; + void updateStyle() override; - virtual void preparePanelForOpening(); - virtual void panelDismissed(); + virtual void preparePanelForOpening() override; + virtual void panelDismissed() override; private: DENG2_PRIVATE(d) diff --git a/doomsday/sdk/libappfw/src/widgets/dialogwidget.cpp b/doomsday/sdk/libappfw/src/widgets/dialogwidget.cpp index 858aaf406a..aefdd27311 100644 --- a/doomsday/sdk/libappfw/src/widgets/dialogwidget.cpp +++ b/doomsday/sdk/libappfw/src/widgets/dialogwidget.cpp @@ -579,6 +579,11 @@ ui::ActionItem *DialogWidget::defaultActionItem() return const_cast(d->findDefaultAction()); } +void DialogWidget::offerFocus() +{ + root().setFocus(d->findDefaultButton()); +} + void DialogWidget::update() { PopupWidget::update(); @@ -682,8 +687,6 @@ void DialogWidget::prepare() // Mouse needs to be untrapped for the user to be access the dialog. d->untrapper.reset(new Untrapper(root().window())); - root().setFocus(d->findDefaultButton()); - if (openingDirection() == ui::NoDirection) { // Center the dialog. diff --git a/doomsday/sdk/libappfw/src/widgets/focuswidget.cpp b/doomsday/sdk/libappfw/src/widgets/focuswidget.cpp index 039f1fe89f..c9e9ba4f59 100644 --- a/doomsday/sdk/libappfw/src/widgets/focuswidget.cpp +++ b/doomsday/sdk/libappfw/src/widgets/focuswidget.cpp @@ -42,18 +42,6 @@ DENG2_PIMPL(FocusWidget) void flash() { - // Flashing depends on the reference widget's visibility. - //float const maxOpacity = (reference? reference->visibleOpacity() : 1.f); - if (reference) - { - self.show(reference->isVisible()); - } - - /*if (color.target() == 0) - { - color.setValue(.8f * maxOpacity, FLASH_SPAN + .1, .1); - } - else*/ if (color.target() > .5f) { color.setValue(0, FLASH_SPAN); @@ -98,11 +86,7 @@ void FocusWidget::stopFlashing() void FocusWidget::update() { setOpacity(d->reference? d->reference->visibleOpacity() : 0.f); - - if (isVisible()) - { - set(Background(Background::GradientFrame, d->currentColor(), 6)); - } + set(Background(Background::GradientFrame, d->currentColor(), 6)); LabelWidget::update(); } diff --git a/doomsday/sdk/libappfw/src/widgets/menuwidget.cpp b/doomsday/sdk/libappfw/src/widgets/menuwidget.cpp index 9e7a2c455e..a024670f10 100644 --- a/doomsday/sdk/libappfw/src/widgets/menuwidget.cpp +++ b/doomsday/sdk/libappfw/src/widgets/menuwidget.cpp @@ -593,6 +593,22 @@ Rule const &MenuWidget::contentHeight() const return *d->outContentHeight; } +void MenuWidget::offerFocus() +{ + foreach (Widget *w, childWidgets()) + { + if (GuiWidget const *widget = w->maybeAs()) + { + if (!widget->behavior().testFlag(Hidden) && + widget->behavior().testFlag(Focusable)) + { + root().setFocus(w); + return; + } + } + } +} + ChildWidgetOrganizer &MenuWidget::organizer() { return d->organizer; diff --git a/doomsday/sdk/libappfw/src/widgets/popupmenuwidget.cpp b/doomsday/sdk/libappfw/src/widgets/popupmenuwidget.cpp index c4d191a641..8e03f382f3 100644 --- a/doomsday/sdk/libappfw/src/widgets/popupmenuwidget.cpp +++ b/doomsday/sdk/libappfw/src/widgets/popupmenuwidget.cpp @@ -439,6 +439,11 @@ void PopupMenuWidget::setColorTheme(ColorTheme theme) d->updateButtonColors(); } +void PopupMenuWidget::offerFocus() +{ + menu().offerFocus(); +} + void PopupMenuWidget::update() { PopupWidget::update(); diff --git a/doomsday/sdk/libappfw/src/widgets/popupwidget.cpp b/doomsday/sdk/libappfw/src/widgets/popupwidget.cpp index 91dd140b08..672caad926 100644 --- a/doomsday/sdk/libappfw/src/widgets/popupwidget.cpp +++ b/doomsday/sdk/libappfw/src/widgets/popupwidget.cpp @@ -350,6 +350,14 @@ ButtonWidget &PopupWidget::closeButton() return *d->close; } +void PopupWidget::offerFocus() +{ + if (d->close) + { + root().setFocus(d->close); + } +} + GuiWidget::Background PopupWidget::infoStyleBackground() const { return Background(style().colors().colorf("popup.info.background"), @@ -479,10 +487,7 @@ void PopupWidget::preparePanelForOpening() d->updateLayout(); - if (d->close) - { - root().setFocus(d->close); - } + offerFocus(); } void PopupWidget::panelDismissed() diff --git a/doomsday/sdk/libcore/include/de/widgets/widget.h b/doomsday/sdk/libcore/include/de/widgets/widget.h index a9426f6e84..2fa9adc726 100644 --- a/doomsday/sdk/libcore/include/de/widgets/widget.h +++ b/doomsday/sdk/libcore/include/de/widgets/widget.h @@ -300,6 +300,7 @@ class DENG2_PUBLIC Widget virtual void viewResized(); virtual void focusGained(); virtual void focusLost(); + virtual void offerFocus(); virtual void update(); virtual void draw(); virtual void preDrawChildren(); diff --git a/doomsday/sdk/libcore/src/widgets/widget.cpp b/doomsday/sdk/libcore/src/widgets/widget.cpp index 00a9a221d2..4fe6a8f917 100644 --- a/doomsday/sdk/libcore/src/widgets/widget.cpp +++ b/doomsday/sdk/libcore/src/widgets/widget.cpp @@ -764,6 +764,9 @@ void Widget::focusGained() void Widget::focusLost() {} +void Widget::offerFocus() +{} + void Widget::update() {}