Maelstrom: Added a checkbox dialog element

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

From d0977efcc028a1ea79a978f45a6008d789c28a93 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 29 Oct 2011 03:10:32 -0400
Subject: [PATCH] Added a checkbox dialog element

---
 MaelstromUI.cpp              |  3 ++
 Makefile.am                  |  2 +
 UIDialogButton.cpp           |  1 +
 UIDialogCheckbox.cpp         | 73 ++++++++++++++++++++++++++++++++++++
 UIDialogCheckbox.h           | 43 +++++++++++++++++++++
 screenlib/UIArea.cpp         | 12 ++++++
 screenlib/UIArea.h           |  2 +
 screenlib/UIElementLabel.cpp |  7 +++-
 screenlib/UIElementLabel.h   |  1 +
 9 files changed, 142 insertions(+), 2 deletions(-)
 create mode 100644 UIDialogCheckbox.cpp
 create mode 100644 UIDialogCheckbox.h

diff --git a/MaelstromUI.cpp b/MaelstromUI.cpp
index 0517833c..c4b3c25f 100644
--- a/MaelstromUI.cpp
+++ b/MaelstromUI.cpp
@@ -7,6 +7,7 @@
 #include "netlogic/game.h"
 #include "utils/hashtable.h"
 #include "UIDialogButton.h"
+#include "UIDialogCheckbox.h"
 #include "UIDialogLabel.h"
 #include "UIElementIcon.h"
 #include "UIElementKeyButton.h"
@@ -163,6 +164,8 @@ MaelstromUI::CreateElement(UIBaseElement *parent, const char *type)
 		return new UIDialogLabel(parent);
 	} else if (strcasecmp(type, "DialogButton") == 0) {
 		return new UIDialogButton(parent);
+	} else if (strcasecmp(type, "DialogCheckbox") == 0) {
+		return new UIDialogCheckbox(parent);
 	} else if (strcasecmp(type, "KeyButton") == 0) {
 		return new UIElementKeyButton(parent);
 	} else if (strcasecmp(type, "Icon") == 0) {
diff --git a/Makefile.am b/Makefile.am
index 8ddca93e..8534756b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,6 +36,8 @@ Maelstrom_SOURCES =		\
 	UIDialog.h		\
 	UIDialogButton.cpp	\
 	UIDialogButton.h	\
+	UIDialogCheckbox.cpp	\
+	UIDialogCheckbox.h	\
 	UIDialogLabel.cpp	\
 	UIDialogLabel.h		\
 	UIElementIcon.cpp	\
diff --git a/UIDialogButton.cpp b/UIDialogButton.cpp
index 1f2f9d0c..abef44a5 100644
--- a/UIDialogButton.cpp
+++ b/UIDialogButton.cpp
@@ -50,6 +50,7 @@ UIDialogButton::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 
 		label = new UIDialogLabel(this, "label");
 		label->SetText(attr->value());
+		label->SetTextColor(m_colors[1]);
 		AddElement(label);
 	}
 
diff --git a/UIDialogCheckbox.cpp b/UIDialogCheckbox.cpp
new file mode 100644
index 00000000..771eac7c
--- /dev/null
+++ b/UIDialogCheckbox.cpp
@@ -0,0 +1,73 @@
+
+#include "screenlib/SDL_FrameBuf.h"
+#include "UIDialogCheckbox.h"
+#include "UIDialogLabel.h"
+
+/* Default checkbox size */
+#define CHECKBOX_SIZE	12
+
+
+UIElementType UIDialogCheckbox::s_elementType;
+
+
+UIDialogCheckbox::UIDialogCheckbox(UIBaseElement *parent, const char *name) :
+	UIElementButton(parent, name)
+{
+	m_checked = false;
+
+	m_color = m_screen->MapRGB(0x00, 0x00, 0x00);
+
+	SetSize(CHECKBOX_SIZE, CHECKBOX_SIZE);
+}
+
+UIDialogCheckbox::~UIDialogCheckbox()
+{
+}
+
+bool
+UIDialogCheckbox::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
+{
+	rapidxml::xml_attribute<> *attr;
+
+	if (!UIElementButton::Load(node, templates)) {
+		return false;
+	}
+
+	LoadBool(node, "checked", m_checked);
+
+	attr = node->first_attribute("text", 0, false);
+	if (attr) {
+		UIDialogLabel *label;
+
+		label = new UIDialogLabel(this, "label");
+		label->SetText(attr->value());
+		label->SetTextColor(m_color);
+		label->SetAnchor(TOPLEFT, TOPRIGHT, this, 3, -2);
+		AddElement(label);
+	}
+
+	return true;
+}
+
+void
+UIDialogCheckbox::Draw()
+{
+	m_screen->DrawRect(X(), Y(), Width(), Height(), m_color);
+
+	if ( m_checked ) {
+		m_screen->DrawLine(X(), Y(),
+				X()+Width()-1, Y()+Height()-1, m_color);
+		m_screen->DrawLine(X(), Y()+Height()-1,
+					X()+Width()-1, Y(), m_color);
+	}
+
+	UIElementButton::Draw();
+}
+
+void
+UIDialogCheckbox::OnClick()
+{
+	UIElementButton::OnClick();
+
+	m_checked = !m_checked;
+}
diff --git a/UIDialogCheckbox.h b/UIDialogCheckbox.h
new file mode 100644
index 00000000..35042aa1
--- /dev/null
+++ b/UIDialogCheckbox.h
@@ -0,0 +1,43 @@
+#ifndef _UIDialogCheckbox_h
+#define _UIDialogCheckbox_h
+
+#include "screenlib/UIElementButton.h"
+
+
+class UIDialogCheckbox : public UIElementButton
+{
+public:
+	UIDialogCheckbox(UIBaseElement *parent, const char *name = "");
+	virtual ~UIDialogCheckbox();
+
+	virtual bool IsA(UIElementType type) {
+		return UIElementButton::IsA(type) || type == GetType();
+	}
+
+	bool IsChecked() const {
+		return m_checked;
+	}
+
+	virtual bool Load(rapidxml::xml_node<> *node, const UITemplates *templates);
+
+	virtual void Draw();
+
+	virtual void OnClick();
+
+protected:
+	Uint32 m_color;
+	bool m_checked;
+
+protected:
+	static UIElementType s_elementType;
+
+public:
+	static UIElementType GetType() {
+		if (!s_elementType) {
+			s_elementType = GenerateType();
+		}
+		return s_elementType;
+	}
+};
+
+#endif // _UIDialogCheckbox_h
diff --git a/screenlib/UIArea.cpp b/screenlib/UIArea.cpp
index 0f1fdefc..32986a03 100644
--- a/screenlib/UIArea.cpp
+++ b/screenlib/UIArea.cpp
@@ -133,6 +133,18 @@ UIArea::SetHeight(int h)
 	}
 }
 
+void
+UIArea::SetAnchor(AnchorLocation from, AnchorLocation to, UIArea *anchor,
+						int offsetX, int offsetY)
+{
+	m_anchor.element = anchor;
+	m_anchor.anchorFrom = from;
+	m_anchor.anchorTo = to;
+	m_anchor.offsetX = offsetX;
+	m_anchor.offsetY = offsetY;
+	CalculateAnchor();
+}
+
 bool
 UIArea::LoadBool(rapidxml::xml_node<> *node, const char *name, bool &value)
 {
diff --git a/screenlib/UIArea.h b/screenlib/UIArea.h
index 09489ef1..e5f839ff 100644
--- a/screenlib/UIArea.h
+++ b/screenlib/UIArea.h
@@ -68,6 +68,8 @@ class UIArea : public ErrorBase
 	void SetSize(int w, int h);
 	void SetWidth(int w);
 	void SetHeight(int h);
+	void SetAnchor(AnchorLocation from, AnchorLocation to, UIArea *anchor,
+					int offsetX = 0, int offsetY = 0);
 
 	bool ContainsPoint(int x, int y) const {
 		return (x >= m_rect.x && x < m_rect.x+m_rect.w &&
diff --git a/screenlib/UIElementLabel.cpp b/screenlib/UIElementLabel.cpp
index 6f4484a3..7bdcad4f 100644
--- a/screenlib/UIElementLabel.cpp
+++ b/screenlib/UIElementLabel.cpp
@@ -122,9 +122,12 @@ UIElementLabel::SetText(const char *text)
 void
 UIElementLabel::SetTextColor(Uint8 R, Uint8 G, Uint8 B)
 {
-	Uint32 color;
+	SetTextColor(m_screen->MapRGB(R, G, B));
+}
 
-	color = m_screen->MapRGB(R, G, B);
+void
+UIElementLabel::SetTextColor(Uint32 color)
+{
 	if (color == m_color) {
 		return;
 	}
diff --git a/screenlib/UIElementLabel.h b/screenlib/UIElementLabel.h
index 6c53e874..8e7f1472 100644
--- a/screenlib/UIElementLabel.h
+++ b/screenlib/UIElementLabel.h
@@ -41,6 +41,7 @@ class UIElementLabel : public UIElement
 
 	void SetText(const char *text);
 	void SetTextColor(Uint8 R, Uint8 G, Uint8 B);
+	void SetTextColor(Uint32 color);
 
 	virtual void Draw();