Maelstrom: Added support for element backgrounds

https://github.com/libsdl-org/Maelstrom/commit/54cdc35c54647d79dcdc0bc530d5f9d15e5da419

From 54cdc35c54647d79dcdc0bc530d5f9d15e5da419 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 23 Nov 2012 20:42:14 -0800
Subject: [PATCH] Added support for element backgrounds

---
 game/MaelstromUI.cpp         | 24 ++++++++++++++++++++++
 game/MaelstromUI.h           |  2 ++
 screenlib/UIDrawEngine.cpp   |  5 +++++
 screenlib/UIElement.cpp      | 40 ++++++++++++++++++++++++++++++++++--
 screenlib/UIElement.h        | 10 ++++++++-
 screenlib/UIImageInterface.h |  3 +++
 6 files changed, 81 insertions(+), 3 deletions(-)

diff --git a/game/MaelstromUI.cpp b/game/MaelstromUI.cpp
index ecfe8cd6..27df7cfb 100644
--- a/game/MaelstromUI.cpp
+++ b/game/MaelstromUI.cpp
@@ -197,6 +197,30 @@ MaelstromUI::FreeImage(UITexture *texture)
 	Free_Texture(screen, texture);
 }
 
+UITexture *
+MaelstromUI::CreateBackground(const char *name)
+{
+    UITexture *background;
+
+    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
+
+    background = CreateImage(name);
+    if (background) {
+        int gridSize = background->Width() / 3;
+        background->SetStretchGrid(gridSize);
+    }
+
+    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
+
+    return background;
+}
+
+void
+MaelstromUI::FreeBackground(UITexture *texture)
+{
+    FreeImage(texture);
+}
+
 void
 MaelstromUI::PlaySound(int soundID)
 {
diff --git a/game/MaelstromUI.h b/game/MaelstromUI.h
index cd2279ea..ac08e6c1 100644
--- a/game/MaelstromUI.h
+++ b/game/MaelstromUI.h
@@ -44,6 +44,8 @@ class MaelstromUI : public UIManager
 	//
 	virtual UITexture *CreateImage(const char *name);
 	virtual void FreeImage(UITexture *texture);
+	virtual UITexture *CreateBackground(const char *name);
+	virtual void FreeBackground(UITexture *texture);
 
 	//
 	// UISoundInterface
diff --git a/screenlib/UIDrawEngine.cpp b/screenlib/UIDrawEngine.cpp
index ebd5c3dc..fe567d77 100644
--- a/screenlib/UIDrawEngine.cpp
+++ b/screenlib/UIDrawEngine.cpp
@@ -118,6 +118,11 @@ UIDrawEngine::OnDraw()
 				m_element->GetFillColor());
 	}
 
+	UITexture *background = m_element->GetBackground();
+	if (background) {
+		background->Draw(m_screen, m_element->X(), m_element->Y(), m_element->Width(), m_element->Height());
+	}
+
 	if (m_element->HasBorder()) {
 		m_screen->DrawRect(m_element->X(), m_element->Y(),
 				m_element->Width(), m_element->Height(),
diff --git a/screenlib/UIElement.cpp b/screenlib/UIElement.cpp
index 3b4a3f3f..ff2b3e48 100644
--- a/screenlib/UIElement.cpp
+++ b/screenlib/UIElement.cpp
@@ -47,6 +47,7 @@ UIElement::UIElement(UIBaseElement *parent, const char *name, UIDrawEngine *draw
 	m_textShadowOffset.x = 0;
 	m_textShadowOffset.y = 0;
 	m_textShadowColor = m_screen->MapRGB(0x00, 0x00, 0x00);
+	m_background = NULL;
 	m_image = NULL;
 	m_mouseEnabled = false;
 	m_mouseInside = false;
@@ -73,6 +74,9 @@ UIElement::~UIElement()
 	if (m_textBinding) {
 		SDL_free(m_textBinding);
 	}
+	if (m_background && !m_background->IsLocked()) {
+		m_ui->FreeBackground(m_background);
+	}
 	if (m_image && !m_image->IsLocked()) {
 		m_ui->FreeImage(m_image);
 	}
@@ -173,6 +177,14 @@ UIElement::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 		}
 	}
 
+	attr = node->first_attribute("background", 0, false);
+	if (attr) {
+		if (!SetBackground(attr->value())) {
+			SDL_Log("Warning: Couldn't load background '%s'", attr->value());
+			return false;
+		}
+	}
+
 	attr = node->first_attribute("image", 0, false);
 	if (attr) {
 		if (!SetImage(attr->value())) {
@@ -482,11 +494,35 @@ UIElement::SetTextShadowColor(Uint32 color)
 }
 
 bool
-UIElement::SetImage(const char *file)
+UIElement::SetBackground(const char *name)
+{
+	UITexture *background;
+
+	background = m_ui->CreateBackground(name);
+	if (!background) {
+		return false;
+	}
+
+	SetBackground(background);
+
+	return true;
+}
+
+void
+UIElement::SetBackground(UITexture *background)
+{
+	if (m_background && !m_background->IsLocked()) {
+		m_ui->FreeBackground(m_background);
+	}
+	m_background = background;
+}
+
+bool
+UIElement::SetImage(const char *name)
 {
 	UITexture *image;
 
-	image = m_ui->CreateImage(file);
+	image = m_ui->CreateImage(name);
 	if (!image) {
 		return false;
 	}
diff --git a/screenlib/UIElement.h b/screenlib/UIElement.h
index 1092a77e..5791097b 100644
--- a/screenlib/UIElement.h
+++ b/screenlib/UIElement.h
@@ -167,8 +167,15 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
 		return m_textShadowColor;
 	}
 
+	// Background
+	bool SetBackground(const char *name);
+	void SetBackground(UITexture *background);
+	UITexture *GetBackground() const {
+		return m_background;
+	}
+
 	// Image information
-	bool SetImage(const char *file);
+	bool SetImage(const char *name);
 	void SetImage(UITexture *image);
 	UITexture *GetImage() const {
 		return m_image;
@@ -217,6 +224,7 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
 	SDL_Point m_textOffset;
 	SDL_Point m_textShadowOffset;
 	Uint32 m_textShadowColor;
+	UITexture *m_background;
 	UITexture *m_image;
 	UIArea m_imageArea;
 	bool m_mouseEnabled;
diff --git a/screenlib/UIImageInterface.h b/screenlib/UIImageInterface.h
index 4f7e25cb..75430aae 100644
--- a/screenlib/UIImageInterface.h
+++ b/screenlib/UIImageInterface.h
@@ -29,6 +29,9 @@ class UIImageInterface
 public:
 	virtual UITexture *CreateImage(const char *name) = 0;
 	virtual void FreeImage(UITexture *texture) = 0;
+
+	virtual UITexture *CreateBackground(const char *name) = 0;
+	virtual void FreeBackground(UITexture *texture) = 0;
 };
 
 #endif // _UIImageInterface_h