Maelstrom: Close dialogs if desired before dispatching actions (which may reopen dialogs)

https://github.com/libsdl-org/Maelstrom/commit/a4db4c3b5a57a1aed8aa4e02ad3c127a3e321bb6

From a4db4c3b5a57a1aed8aa4e02ad3c127a3e321bb6 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 1 Dec 2012 13:54:00 -0800
Subject: [PATCH] Close dialogs if desired before dispatching actions (which
 may reopen dialogs)

---
 screenlib/UIDialogButton.cpp | 5 +++--
 screenlib/UIManager.cpp      | 6 ++++++
 screenlib/UIManager.h        | 1 +
 screenlib/UIPanel.cpp        | 7 ++++++-
 utils/array.h                | 2 +-
 5 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/screenlib/UIDialogButton.cpp b/screenlib/UIDialogButton.cpp
index c05431dc..71b65f2e 100644
--- a/screenlib/UIDialogButton.cpp
+++ b/screenlib/UIDialogButton.cpp
@@ -69,9 +69,10 @@ UIDialogButton::OnClick()
 		static_cast<UIDialog*>(panel)->SetDialogStatus(m_statusID);
 	}
 
-	UIElementButton::OnClick();
-
+	// Hide before doing the action (which may change the current panel)
 	if (m_closeDialog && panel) {
 		GetUI()->HidePanel(panel);
 	}
+
+	UIElementButton::OnClick();
 }
diff --git a/screenlib/UIManager.cpp b/screenlib/UIManager.cpp
index a2a64c02..40199a3d 100644
--- a/screenlib/UIManager.cpp
+++ b/screenlib/UIManager.cpp
@@ -218,6 +218,12 @@ UIManager::GetCurrentPanel()
 	return NULL;
 }
 
+bool
+UIManager::IsShown(UIPanel *panel) const
+{
+	return (panel && m_visible.find(panel));
+}
+
 void
 UIManager::ShowPanel(UIPanel *panel)
 {
diff --git a/screenlib/UIManager.h b/screenlib/UIManager.h
index 7d294ecc..39a558dc 100644
--- a/screenlib/UIManager.h
+++ b/screenlib/UIManager.h
@@ -89,6 +89,7 @@ class UIManager : public UIArea, public UIFontInterface, public UIImageInterface
 		m_panels.remove(panel);
 	}
 
+	bool IsShown(UIPanel *panel) const;
 	void ShowPanel(UIPanel *panel);
 	void ShowPanel(const char *name) {
 		ShowPanel(GetPanel(name));
diff --git a/screenlib/UIPanel.cpp b/screenlib/UIPanel.cpp
index fda2a7e0..b0c8b971 100644
--- a/screenlib/UIPanel.cpp
+++ b/screenlib/UIPanel.cpp
@@ -200,7 +200,12 @@ UIPanel::Action(UIBaseElement *sender, const char *action)
 	}
 
 	// Dialogs pass actions to their parents
-	UIPanel *panel = m_ui->GetPrevPanel(this);
+	UIPanel *panel;
+	if (m_ui->IsShown(this)) {
+		panel = m_ui->GetPrevPanel(this);
+	} else {
+		panel = m_ui->GetCurrentPanel();
+	}
 	if (panel) {
 		panel->Action(sender, action);
 	} else {
diff --git a/utils/array.h b/utils/array.h
index 539efed8..b7fe9050 100644
--- a/utils/array.h
+++ b/utils/array.h
@@ -33,7 +33,7 @@ class array
 	array() : m_len(0), m_max(1), m_data((T*)malloc(sizeof(T))) { }
 	~array() { free(m_data); }
 
-	bool find(const T& item) {
+	bool find(const T& item) const {
 		for (unsigned i = 0; i < m_len; ++i) {
 			if (m_data[i] == item) {
 				return true;