From 54ff2f6fec70e66d7a8b4a96b28fa7d46f2304a3 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 15 Dec 2012 23:21:27 +0300 Subject: Allow hide popup list if focus lost. --- src/gui/focushandler.cpp | 9 +++++++++ src/gui/focushandler.h | 8 +++++--- src/gui/gui.cpp | 10 ++++++++++ src/gui/gui.h | 6 +++++- src/gui/widgets/popuplist.cpp | 26 ++++++++++++++++++++++++-- src/gui/widgets/popuplist.h | 4 ++++ 6 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/gui/focushandler.cpp b/src/gui/focushandler.cpp index ce40c3a7c..80bc0a04f 100644 --- a/src/gui/focushandler.cpp +++ b/src/gui/focushandler.cpp @@ -22,6 +22,8 @@ #include "gui/focushandler.h" +#include "gui/gui.h" + #include "gui/widgets/window.h" #include "debug.h" @@ -100,3 +102,10 @@ void FocusHandler::checkForWindow() } } } + +void FocusHandler::distributeFocusGainedEvent(const gcn::Event &focusEvent) +{ + if (gui) + gui->distributeGlobalFocusGainedEvent(focusEvent); + gcn::FocusHandler::distributeFocusGainedEvent(focusEvent); +} diff --git a/src/gui/focushandler.h b/src/gui/focushandler.h index e881c9aea..12a639c0e 100644 --- a/src/gui/focushandler.h +++ b/src/gui/focushandler.h @@ -60,15 +60,17 @@ class FocusHandler final : public gcn::FocusHandler * Removes a widget from the focus handler. Also makes sure no dangling * pointers remain in modal focus stack. */ - void remove(gcn::Widget *widget); + void remove(gcn::Widget *widget) override; /** * Overloaded to allow windows to move to the top when one of their * widgets is tabbed to when tabbing through focusable elements. */ - void tabNext(); + void tabNext() override; - void tabPrevious(); + void tabPrevious() override; + + void distributeFocusGainedEvent(const gcn::Event &focusEvent) override; private: /** diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 7b2da4bff..0c703d5ef 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -706,3 +706,13 @@ void Gui::removeGlobalFocusListener(gcn::FocusListener* focusListener) { mFocusListeners.remove(focusListener); } + +void Gui::distributeGlobalFocusGainedEvent(const gcn::Event &focusEvent) +{ + for (FocusListenerIterator iter = mFocusListeners.begin(); + iter != mFocusListeners.end(); + ++ iter) + { + (*iter)->focusGained(focusEvent); + } +} diff --git a/src/gui/gui.h b/src/gui/gui.h index 04b6ddba3..0efa25c1d 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -26,6 +26,7 @@ #include "resources/cursor.h" #include "resources/image.h" +#include #include #include "localconsts.h" @@ -146,6 +147,8 @@ class Gui final : public gcn::Gui void removeGlobalFocusListener(gcn::FocusListener* focusListener); + void distributeGlobalFocusGainedEvent(const gcn::Event &focusEvent); + protected: void handleMouseMoved(const gcn::MouseInput &mouseInput); @@ -168,7 +171,8 @@ class Gui final : public gcn::Gui int mMouseInactivityTimer; int mCursorType; - typedef std::list FocusListenerList; + typedef std::list FocusListenerList; + typedef FocusListenerList::iterator FocusListenerIterator; FocusListenerList mFocusListeners; }; diff --git a/src/gui/widgets/popuplist.cpp b/src/gui/widgets/popuplist.cpp index e32cd5b70..eb711ddeb 100644 --- a/src/gui/widgets/popuplist.cpp +++ b/src/gui/widgets/popuplist.cpp @@ -20,6 +20,8 @@ #include "gui/widgets/popuplist.h" +#include "gui/gui.h" + #include "gui/widgets/dropdown.h" #include "gui/widgets/listbox.h" #include "gui/widgets/scrollarea.h" @@ -46,6 +48,14 @@ PopupList::PopupList(DropDown *const widget, if (getParent()) getParent()->addFocusListener(this); + if (gui) + gui->addGlobalFocusListener(this); +} + +PopupList::~PopupList() +{ + if (gui) + gui->removeGlobalFocusListener(this); } void PopupList::show(int x, int y) @@ -106,10 +116,22 @@ void PopupList::valueChanged(const gcn::SelectionEvent& event A_UNUSED) setVisible(false); } +void PopupList::focusGained(const gcn::Event& event A_UNUSED) +{ + const gcn::Widget *const source = event.getSource(); + if (source == this || source == mListBox + || source == mScrollArea || source == mDropDown) + { + return; + } + + if (mDropDown) + mDropDown->updateSelection(); + setVisible(false); +} + void PopupList::focusLost(const gcn::Event& event A_UNUSED) { - logger->log("lost focus"); if (mDropDown) mDropDown->updateSelection(); -// setVisible(false); } diff --git a/src/gui/widgets/popuplist.h b/src/gui/widgets/popuplist.h index f0b195a47..a74d82c20 100644 --- a/src/gui/widgets/popuplist.h +++ b/src/gui/widgets/popuplist.h @@ -43,6 +43,8 @@ class PopupList final : public Popup, PopupList(DropDown *const widget, gcn::ListModel *const listModel); + ~PopupList(); + A_DELETE_COPY(PopupList) void show(int x, int y); @@ -62,6 +64,8 @@ class PopupList final : public Popup, void valueChanged(const gcn::SelectionEvent& event); + void focusGained(const gcn::Event& event A_UNUSED); + void focusLost(const gcn::Event& event A_UNUSED); private: -- cgit v1.2.3-60-g2f50