https://github.com/libsdl-org/Maelstrom/commit/313b1f1c7290fba0c46da0d713731c5391f463ec
From 313b1f1c7290fba0c46da0d713731c5391f463ec Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 16 Dec 2012 23:17:03 -0800
Subject: [PATCH] Make sure that dropdowns close no matter where else we click
---
screenlib/UIElementDropdown.cpp | 10 ++++++++++
screenlib/UIElementDropdown.h | 2 +-
screenlib/UIManager.cpp | 34 ++++++++++++++++++++++++++++++++-
screenlib/UIManager.h | 5 +++++
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/screenlib/UIElementDropdown.cpp b/screenlib/UIElementDropdown.cpp
index c2c088dd..3b158a5a 100644
--- a/screenlib/UIElementDropdown.cpp
+++ b/screenlib/UIElementDropdown.cpp
@@ -19,6 +19,7 @@
3. This notice may not be removed or altered from any source distribution.
*/
+#include "UIManager.h"
#include "UIElementDropdown.h"
UIElementType UIElementDropdown::s_elementType;
@@ -30,6 +31,11 @@ UIElementDropdown::UIElementDropdown(UIBaseElement *parent, const char *name, UI
m_showingElements = true;
}
+UIElementDropdown::~UIElementDropdown()
+{
+ GetUI()->ReleaseEvents(this);
+}
+
bool
UIElementDropdown::FinishLoading()
{
@@ -76,6 +82,8 @@ UIElementDropdown::OnClick()
void
UIElementDropdown::ShowElements()
{
+ GetUI()->CaptureEvents(this);
+
for (unsigned int i = 0; i < m_elements.length(); ++i) {
m_elements[i]->Show();
}
@@ -85,6 +93,8 @@ UIElementDropdown::ShowElements()
void
UIElementDropdown::HideElements()
{
+ GetUI()->ReleaseEvents(this);
+
for (unsigned int i = 0; i < m_elements.length(); ++i) {
m_elements[i]->Hide();
}
diff --git a/screenlib/UIElementDropdown.h b/screenlib/UIElementDropdown.h
index 0e6707ea..850b4b8b 100644
--- a/screenlib/UIElementDropdown.h
+++ b/screenlib/UIElementDropdown.h
@@ -30,7 +30,7 @@ class UIElementDropdown : public UIElementButton
DECLARE_TYPESAFE_CLASS(UIElementButton)
public:
UIElementDropdown(UIBaseElement *parent, const char *name, UIDrawEngine *drawEngine);
- virtual ~UIElementDropdown() { }
+ virtual ~UIElementDropdown();
override bool FinishLoading();
diff --git a/screenlib/UIManager.cpp b/screenlib/UIManager.cpp
index 3b1319cf..8801cf09 100644
--- a/screenlib/UIManager.cpp
+++ b/screenlib/UIManager.cpp
@@ -305,6 +305,26 @@ UIManager::DeletePanel(UIPanel *panel)
}
}
+void
+UIManager::CaptureEvents(UIBaseElement *element)
+{
+ if (!IsCapturingEvents(element)) {
+ m_eventCapture.add(element);
+ }
+}
+
+void
+UIManager::ReleaseEvents(UIBaseElement *element)
+{
+ m_eventCapture.remove(element);
+}
+
+bool
+UIManager::IsCapturingEvents(UIBaseElement *element)
+{
+ return m_eventCapture.find(element);
+}
+
void
UIManager::HideDialogs()
{
@@ -394,6 +414,8 @@ UIManager::Draw(bool fullUpdate)
bool
UIManager::HandleEvent(const SDL_Event &event)
{
+ unsigned int i;
+
if (event.type == SDL_WINDOWEVENT &&
event.window.event == SDL_WINDOWEVENT_RESIZED &&
m_screen->Resizable()) {
@@ -413,7 +435,17 @@ UIManager::HandleEvent(const SDL_Event &event)
// In case it's not called any other time...
Poll();
- for (unsigned i = m_visible.length(); i--; ) {
+ for (i = m_eventCapture.length(); i--; ) {
+ UIBaseElement *element = m_eventCapture[i];
+
+ for (int drawLevel = NUM_DRAWLEVELS; drawLevel--; ) {
+ if (element->DispatchEvent(event, (DRAWLEVEL)drawLevel)) {
+ return true;
+ }
+ }
+ }
+
+ for (i = m_visible.length(); i--; ) {
UIPanel *panel = m_visible[i];
for (int drawLevel = NUM_DRAWLEVELS; drawLevel--; ) {
diff --git a/screenlib/UIManager.h b/screenlib/UIManager.h
index 4e29335f..8d52fd11 100644
--- a/screenlib/UIManager.h
+++ b/screenlib/UIManager.h
@@ -111,6 +111,10 @@ class UIManager : public UIArea, public UIFontInterface, public UIImageInterface
return m_panelTransition;
}
+ void CaptureEvents(UIBaseElement *element);
+ void ReleaseEvents(UIBaseElement *element);
+ bool IsCapturingEvents(UIBaseElement *element);
+
void HideDialogs();
void SetCondition(const char *token, bool isTrue = true);
@@ -149,6 +153,7 @@ class UIManager : public UIArea, public UIFontInterface, public UIImageInterface
array<UIPanel *> m_panels;
array<UIPanel *> m_visible;
array<UIPanel *> m_delete;
+ array<UIBaseElement *> m_eventCapture;
PANEL_TRANSITION_TYPE m_panelTransition;
HashTable *m_conditions;
};