From f555b900b0d0d631245f776c90da3194322674d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Thu, 21 Jul 2016 14:02:46 +0300 Subject: [PATCH] Fixed|Widgets|libappfw: Drawing the focus indicator The focus indicator should not be drawn after everything else, because that would ignore clipping and blurring. --- .../include/de/framework/guirootwidget.h | 3 +++ doomsday/sdk/libappfw/src/guirootwidget.cpp | 23 +++++++++++-------- doomsday/sdk/libappfw/src/guiwidget.cpp | 8 +++++++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/doomsday/sdk/libappfw/include/de/framework/guirootwidget.h b/doomsday/sdk/libappfw/include/de/framework/guirootwidget.h index 54ed46fa04..3ab6cdc23a 100644 --- a/doomsday/sdk/libappfw/include/de/framework/guirootwidget.h +++ b/doomsday/sdk/libappfw/include/de/framework/guirootwidget.h @@ -31,6 +31,7 @@ namespace de { class GuiWidget; +class FocusWidget; /** * Graphical root widget. @@ -96,6 +97,8 @@ class LIBAPPFW_PUBLIC GuiRootWidget : public RootWidget GuiWidget const *guiFind(String const &name) const; + FocusWidget &focusIndicator(); + // Events. void update(); void draw(); diff --git a/doomsday/sdk/libappfw/src/guirootwidget.cpp b/doomsday/sdk/libappfw/src/guirootwidget.cpp index 015c9337ef..206560efa2 100644 --- a/doomsday/sdk/libappfw/src/guirootwidget.cpp +++ b/doomsday/sdk/libappfw/src/guirootwidget.cpp @@ -132,8 +132,9 @@ DENG2_PIMPL(GuiRootWidget) self.audienceForChildAddition() += this; self.audienceForFocusChange() += this; + // The focus indicator exists outside the widget tree. focusIndicator = new FocusWidget; - self.add(focusIndicator); + focusIndicator->setRoot(thisPublic); } ~Impl() @@ -143,9 +144,11 @@ DENG2_PIMPL(GuiRootWidget) // Tell all widgets to release their resource allocations. The base // class destructor will destroy all widgets, but this class governs // shared GL resources, so we'll ask the widgets to do this now. + focusIndicator->deinitialize(); self.notifyTree(&Widget::deinitialize); // Destroy GUI widgets while the shared resources are still available. + GuiWidget::destroy(focusIndicator); self.clearTree(); } @@ -188,9 +191,6 @@ DENG2_PIMPL(GuiRootWidget) // Make sure newly added children know the view size. child.viewResized(); child.notifyTree(&Widget::viewResized); - - // Keep the focus at the top. - self.moveChildToLast(*focusIndicator); } void focusedWidgetChanged(Widget *focused) @@ -361,6 +361,11 @@ GuiWidget const *GuiRootWidget::guiFind(String const &name) const return find(name)->maybeAs(); } +FocusWidget &GuiRootWidget::focusIndicator() +{ + return *d->focusIndicator; +} + void GuiRootWidget::update() { if (window().canvas().isGLReady()) @@ -369,6 +374,7 @@ void GuiRootWidget::update() window().canvas().makeCurrent(); RootWidget::update(); + d->focusIndicator->update(); // Request a window draw so that the updated content becomes visible. window().as().draw(); @@ -377,6 +383,8 @@ void GuiRootWidget::update() void GuiRootWidget::draw() { + d->focusIndicator->initialize(); + if (d->noFramesDrawnYet) { // Widgets may not yet be ready on the first frame; make sure @@ -398,11 +406,8 @@ void GuiRootWidget::draw() void GuiRootWidget::drawUntil(Widget &until) { - NotifyArgs args(&Widget::draw); - args.conditionFunc = &Widget::isVisible; - args.preNotifyFunc = &Widget::preDrawChildren; - args.postNotifyFunc = &Widget::postDrawChildren; - args.until = &until; + NotifyArgs args = notifyArgsForDraw(); + args.until = &until; notifyTree(args); } diff --git a/doomsday/sdk/libappfw/src/guiwidget.cpp b/doomsday/sdk/libappfw/src/guiwidget.cpp index 1282592440..a8240bdbc8 100644 --- a/doomsday/sdk/libappfw/src/guiwidget.cpp +++ b/doomsday/sdk/libappfw/src/guiwidget.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -1002,6 +1003,13 @@ void GuiWidget::postDrawChildren() { GLState::pop(); } + + // Focus indicator is an overlay. + auto &rootWidget = root(); + if (rootWidget.focus() && rootWidget.focus()->parent() == this) + { + rootWidget.focusIndicator().draw(); + } } } // namespace de