Maelstrom: Added the concept of the disabled state.

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

From e5ece41e8c85065cbcc0a5b00ff7b815fc28a1b8 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 2 Nov 2011 23:24:23 -0400
Subject: [PATCH] Added the concept of the disabled state.

---
 MacDialog.cpp               |  8 +++----
 screenlib/UIBaseElement.cpp | 48 +++++++++++++++++++++++++++++++++++++
 screenlib/UIBaseElement.h   | 10 ++++++++
 screenlib/UIDrawEngine.cpp  |  8 +++----
 screenlib/UIElement.cpp     | 31 ++++++++++++++++++++++++
 screenlib/UIElement.h       | 11 +++++++++
 6 files changed, 108 insertions(+), 8 deletions(-)

diff --git a/MacDialog.cpp b/MacDialog.cpp
index 0e0a3458..0c014161 100644
--- a/MacDialog.cpp
+++ b/MacDialog.cpp
@@ -170,7 +170,7 @@ MacDialogButton::OnDraw()
 	// Do the normal drawing
 	MacDialogDrawEngine::OnDraw();
 
-	color = m_element->GetColor();
+	color = m_element->GetCurrentColor();
 
 	// Draw the beveled edge
 	x = m_element->X();
@@ -277,7 +277,7 @@ MacDialogCheckbox::OnDraw()
 
 	MacDialogDrawEngine::OnDraw();
 
-	color = m_element->GetColor();
+	color = m_element->GetCurrentColor();
 	x = m_element->X();
 	y = m_element->Y();
 
@@ -313,7 +313,7 @@ MacDialogRadioButton::OnDraw()
 
 	MacDialogDrawEngine::OnDraw();
 
-	color = m_element->GetColor();
+	color = m_element->GetCurrentColor();
 	x = m_element->X() + 5;
 	y = m_element->Y() + 5;
 
@@ -403,7 +403,7 @@ MacDialogEditbox::OnDraw()
 		// Draw the cursor
 		int x = m_element->GetTextArea()->X() + m_element->GetTextArea()->Width();
 
-		m_screen->DrawLine(x, m_element->Y()+3, x, m_element->Y()+3+m_element->Height()-6-1, m_element->GetColor());
+		m_screen->DrawLine(x, m_element->Y()+3, x, m_element->Y()+3+m_element->Height()-6-1, m_element->GetCurrentColor());
 	}
 }
 
diff --git a/screenlib/UIBaseElement.cpp b/screenlib/UIBaseElement.cpp
index 637a8e80..7bb1c988 100644
--- a/screenlib/UIBaseElement.cpp
+++ b/screenlib/UIBaseElement.cpp
@@ -38,6 +38,8 @@ UIBaseElement::UIBaseElement(UIManager *ui, const char *name) :
 	m_parent = NULL;
 	m_name = SDL_strdup(name);
 	m_shown = true;
+	m_disabled = false;
+	m_parentDisabled = false;
 }
 
 UIBaseElement::UIBaseElement(UIBaseElement *parent, const char *name) :
@@ -48,6 +50,8 @@ UIBaseElement::UIBaseElement(UIBaseElement *parent, const char *name) :
 	m_parent = parent;
 	m_name = SDL_strdup(name);
 	m_shown = true;
+	m_disabled = false;
+	m_parentDisabled = parent->IsDisabled();
 }
 
 UIBaseElement::~UIBaseElement()
@@ -77,6 +81,11 @@ UIBaseElement::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 
 	LoadBool(node, "show", m_shown);
 
+	bool disabled;
+	if (LoadBool(node, "disabled", disabled)) {
+		SetDisabled(disabled);
+	}
+
 	child = node->first_node("elements", 0, false);
 	if (child) {
 		if (!LoadElements(child, templates)) {
@@ -109,6 +118,42 @@ UIBaseElement::GetAnchorElement(const char *name)
 	}
 }
 
+void
+UIBaseElement::SetDisabled(bool disabled)
+{
+	if (disabled == m_disabled) {
+		return;
+	}
+
+	bool wasDisabled = IsDisabled();
+	m_disabled = disabled;
+	if (wasDisabled != IsDisabled()) {
+		UpdateDisabledState();
+	}
+}
+
+void
+UIBaseElement::SetParentDisabled(bool disabled)
+{
+	if (disabled == m_parentDisabled) {
+		return;
+	}
+
+	bool wasDisabled = IsDisabled();
+	m_parentDisabled = disabled;
+	if (wasDisabled != IsDisabled()) {
+		UpdateDisabledState();
+	}
+}
+
+void
+UIBaseElement::UpdateDisabledState()
+{
+	for (unsigned i = 0; i < m_elements.length(); ++i) {
+		m_elements[i]->SetParentDisabled(IsDisabled());
+	}
+}
+
 void
 UIBaseElement::Draw()
 {
@@ -123,6 +168,9 @@ bool
 UIBaseElement::HandleEvent(const SDL_Event &event)
 {
 	for (unsigned i = m_elements.length(); i--; ) {
+		if (m_elements[i]->IsDisabled()) {
+			continue;
+		}
 		if (m_elements[i]->HandleEvent(event)) {
 			return true;
 		}
diff --git a/screenlib/UIBaseElement.h b/screenlib/UIBaseElement.h
index 7643da50..ce7cc04e 100644
--- a/screenlib/UIBaseElement.h
+++ b/screenlib/UIBaseElement.h
@@ -131,6 +131,12 @@ class UIBaseElement : public UIArea
 		return m_shown;
 	}
 
+	void SetDisabled(bool disabled);
+	void SetParentDisabled(bool disabled);
+	bool IsDisabled() const {
+		return m_disabled || m_parentDisabled;
+	}
+
 	virtual void Draw();
 	virtual bool HandleEvent(const SDL_Event &event);
 
@@ -140,6 +146,8 @@ class UIBaseElement : public UIArea
 	UIBaseElement *m_parent;
 	char *m_name;
 	bool m_shown;
+	bool m_disabled;
+	bool m_parentDisabled;
 	array<UIBaseElement *> m_elements;
 
 protected:
@@ -148,6 +156,8 @@ class UIBaseElement : public UIArea
 
 	bool LoadElements(rapidxml::xml_node<> *node, const UITemplates *templates);
 
+	virtual void UpdateDisabledState();
+
 protected:
 	static UIElementType s_elementTypeIndex;
 	static UIElementType s_elementType;
diff --git a/screenlib/UIDrawEngine.cpp b/screenlib/UIDrawEngine.cpp
index fd21a474..991c158c 100644
--- a/screenlib/UIDrawEngine.cpp
+++ b/screenlib/UIDrawEngine.cpp
@@ -121,7 +121,7 @@ UIDrawEngine::OnDraw()
 	if (m_element->HasBorder()) {
 		m_screen->DrawRect(m_element->X(), m_element->Y(),
 				m_element->Width(), m_element->Height(),
-				m_element->GetColor());
+				m_element->GetCurrentColor());
 	}
 
 	SDL_Texture *image = m_element->GetImage();
@@ -141,7 +141,7 @@ UIDrawEngine::OnDraw()
 
 			m_screen->QueueBlit(area->X()+x, area->Y()+y, m_textImage, NOCLIP);
 
-			m_screen->GetRGB(m_element->GetColor(), &r, &g, &b);
+			m_screen->GetRGB(m_element->GetCurrentColor(), &r, &g, &b);
 			SDL_SetTextureColorMod(m_textImage, r, g, b);
 		}
 		m_screen->QueueBlit(area->X(), area->Y(), m_textImage, NOCLIP);
@@ -158,7 +158,7 @@ UIDrawEngine::OnColorChanged()
 						m_element->GetFontName(),
 						m_element->GetFontSize(),
 						m_element->GetFontStyle(),
-						m_element->GetColor());
+						m_element->GetCurrentColor());
 	}
 }
 
@@ -183,7 +183,7 @@ UIDrawEngine::OnTextChanged()
 						m_element->GetFontName(),
 						m_element->GetFontSize(),
 						m_element->GetFontStyle(),
-						m_element->GetColor());
+						m_element->GetCurrentColor());
 
 		w = m_screen->GetImageWidth(m_textImage);
 		h = m_screen->GetImageHeight(m_textImage);
diff --git a/screenlib/UIElement.cpp b/screenlib/UIElement.cpp
index dc52c22e..a084cc40 100644
--- a/screenlib/UIElement.cpp
+++ b/screenlib/UIElement.cpp
@@ -53,6 +53,7 @@ UIElement::UIElement(UIBaseElement *parent, const char *name, UIDrawEngine *draw
 	m_fill = false;
 	m_fillColor = m_screen->MapRGB(0x00, 0x00, 0x00);
 	m_color = m_screen->MapRGB(0xFF, 0xFF, 0xFF);
+	m_disabledColor = m_screen->MapRGB(0x80, 0x80, 0x80);
 	m_fontName = NULL;
 	m_fontSize = 0;
 	m_fontStyle = UIFONT_STYLE_NORMAL;
@@ -359,6 +360,36 @@ UIElement::SetColor(Uint32 color)
 
 	m_color = color;
 
+	if (!IsDisabled() && m_drawEngine) {
+		m_drawEngine->OnColorChanged();
+	}
+}
+
+void
+UIElement::SetDisabledColor(Uint8 R, Uint8 G, Uint8 B)
+{
+	SetDisabledColor(m_screen->MapRGB(R, G, B));
+}
+
+void
+UIElement::SetDisabledColor(Uint32 color)
+{
+	if (color == m_disabledColor) {
+		return;
+	}
+
+	m_disabledColor = color;
+
+	if (IsDisabled() && m_drawEngine) {
+		m_drawEngine->OnColorChanged();
+	}
+}
+
+void
+UIElement::UpdateDisabledState()
+{
+	UIBaseElement::UpdateDisabledState();
+
 	if (m_drawEngine) {
 		m_drawEngine->OnColorChanged();
 	}
diff --git a/screenlib/UIElement.h b/screenlib/UIElement.h
index a3b49271..7acbd906 100644
--- a/screenlib/UIElement.h
+++ b/screenlib/UIElement.h
@@ -74,6 +74,14 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
 	Uint32 GetColor() const {
 		return m_color;
 	}
+	void SetDisabledColor(Uint8 R, Uint8 G, Uint8 B);
+	void SetDisabledColor(Uint32 color);
+	Uint32 GetDisabledColor() const {
+		return m_disabledColor;
+	}
+	Uint32 GetCurrentColor() const {
+		return IsDisabled() ? GetDisabledColor() : GetColor();
+	}
 
 	// Text information
 	void SetFont(const char *fontName, int fontSize, UIFontStyle fontStyle);
@@ -138,6 +146,7 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
 	bool m_fill;
 	Uint32 m_fillColor;
 	Uint32 m_color;
+	Uint32 m_disabledColor;
 	char *m_fontName;
 	int m_fontSize;
 	UIFontStyle m_fontStyle;
@@ -157,6 +166,8 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
 	bool LoadColor(rapidxml::xml_node<> *node, const char *name, Uint32 &value);
 	bool ParseFont(char *text);
 	bool ParseImage(const char *file);
+
+	override void UpdateDisabledState();
 };
 
 #endif // _UIElement_h