https://github.com/libsdl-org/Maelstrom/commit/7f877fc4007774668d71bf5b06c3e0c34e401024
From 7f877fc4007774668d71bf5b06c3e0c34e401024 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 29 Oct 2011 01:14:08 -0400
Subject: [PATCH] Added dialog buttons
---
MaelstromUI.cpp | 3 +
Makefile.am | 2 +
UI/dawn.xml | 5 ++
UIDialogButton.cpp | 185 +++++++++++++++++++++++++++++++++++++++
UIDialogButton.h | 45 ++++++++++
screenlib/SDL_FrameBuf.h | 5 ++
6 files changed, 245 insertions(+)
create mode 100644 UIDialogButton.cpp
create mode 100644 UIDialogButton.h
diff --git a/MaelstromUI.cpp b/MaelstromUI.cpp
index c8586a0f..d3797ccc 100644
--- a/MaelstromUI.cpp
+++ b/MaelstromUI.cpp
@@ -6,6 +6,7 @@
#include "netlogic/about.h"
#include "netlogic/game.h"
#include "utils/hashtable.h"
+#include "UIDialogButton.h"
#include "UIDialogLabel.h"
#include "UIElementIcon.h"
#include "UIElementKeyButton.h"
@@ -161,6 +162,8 @@ MaelstromUI::CreateElement(UIBaseElement *parent, const char *type)
return new UIElementLabel(parent);
} else if (strcasecmp(type, "DialogLabel") == 0) {
return new UIDialogLabel(parent);
+ } else if (strcasecmp(type, "DialogButton") == 0) {
+ return new UIDialogButton(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 af7fafae..8ddca93e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,6 +34,8 @@ Maelstrom_SOURCES = \
scores.h \
UIDialog.cpp \
UIDialog.h \
+ UIDialogButton.cpp \
+ UIDialogButton.h \
UIDialogLabel.cpp \
UIDialogLabel.h \
UIElementIcon.cpp \
diff --git a/UI/dawn.xml b/UI/dawn.xml
index 0f8a0020..1aeddd61 100644
--- a/UI/dawn.xml
+++ b/UI/dawn.xml
@@ -23,5 +23,10 @@
<DialogLabel name="line6" text="dawn.">
<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMRIGHT" anchor="line5" x="2" y="2"/>
</DialogLabel>
+
+ <DialogButton text="OK" default="true" closeDialog="true">
+ <Size w="90"/>
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="210" y="160"/>
+ </DialogButton>
</Elements>
</Dialog>
diff --git a/UIDialogButton.cpp b/UIDialogButton.cpp
new file mode 100644
index 00000000..f3663b0f
--- /dev/null
+++ b/UIDialogButton.cpp
@@ -0,0 +1,185 @@
+
+#include "screenlib/SDL_FrameBuf.h"
+#include "screenlib/UIManager.h"
+#include "UIDialogButton.h"
+#include "UIDialogLabel.h"
+
+/* Default dialog button size */
+#define BUTTON_WIDTH 75
+#define BUTTON_HEIGHT 19
+
+
+UIElementType UIDialogButton::s_elementType;
+
+
+UIDialogButton::UIDialogButton(UIBaseElement *parent, const char *name) :
+ UIElementButton(parent, name)
+{
+ m_default = false;
+ m_closeDialog = false;
+
+ m_colors[0] = m_screen->MapRGB(0xFF, 0xFF, 0xFF);
+ m_colors[1] = m_screen->MapRGB(0x00, 0x00, 0x00);
+
+ SetSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+}
+
+UIDialogButton::~UIDialogButton()
+{
+}
+
+bool
+UIDialogButton::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
+{
+ rapidxml::xml_attribute<> *attr;
+
+ if (!UIElementButton::Load(node, templates)) {
+ return false;
+ }
+
+ attr = node->first_attribute("default", 0, false);
+ if (attr) {
+ const char *value = attr->value();
+
+ if (*value == '1' || *value == 't' || *value == 'T') {
+ m_default = true;
+ }
+ }
+
+ attr = node->first_attribute("closeDialog", 0, false);
+ if (attr) {
+ const char *value = attr->value();
+
+ if (*value == '1' || *value == 't' || *value == 'T') {
+ m_closeDialog = true;
+ }
+ }
+
+ attr = node->first_attribute("text", 0, false);
+ if (attr) {
+ UIDialogLabel *label;
+
+ label = new UIDialogLabel(this, "label");
+ label->SetText(attr->value());
+ AddElement(label);
+ }
+
+ return true;
+}
+
+void
+UIDialogButton::Draw()
+{
+ Uint32 bg, fg;
+ int x, y, maxx, maxy;
+
+ /* The colors are inverted when the mouse is pressed */
+ bg = m_colors[m_mousePressed];
+ fg = m_colors[!m_mousePressed];
+
+ /* First draw the background */
+ m_screen->FillRect(X(), Y(), Width(), Height(), bg);
+
+ /* Draw the beveled edge */
+ x = X();
+ maxx = x+Width()-1;
+ y = Y();
+ maxy = y+Height()-1;
+
+ /* Top and upper corners */
+ m_screen->DrawLine(x+3, y, maxx-3, y, fg);
+ m_screen->DrawLine(x+1, y+1, x+2, y+1, fg);
+ m_screen->DrawLine(maxx-2, y+1, maxx-1, y+1, fg);
+ m_screen->DrawLine(x+1, y+2, x+1, y+2, fg);
+ m_screen->DrawLine(maxx-1, y+2, maxx-1, y+2, fg);
+
+ /* Sides */
+ m_screen->DrawLine(x, y+3, x, maxy-3, fg);
+ m_screen->DrawLine(maxx, y+3, maxx, maxy-3, fg);
+
+ /* Bottom and lower corners */
+ m_screen->DrawLine(x+1, maxy-2, x+1, maxy-2, fg);
+ m_screen->DrawLine(maxx-1, maxy-2, maxx-1, maxy-2, fg);
+ m_screen->DrawLine(x+1, maxy-1, x+2, maxy-1, fg);
+ m_screen->DrawLine(maxx-2, maxy-1, maxx-1, maxy-1, fg);
+ m_screen->DrawLine(x+3, maxy, maxx-3, maxy, fg);
+
+ if (m_default) {
+ /* Show the thick edge */
+ x = X()-4;
+ maxx = x+4+Width()+4-1;
+ y = Y()-4;
+ maxy = y+4+Height()+4-1;
+
+ /* The edge always uses the real foreground color */
+ fg = m_colors[1];
+
+ m_screen->DrawLine(x+5, y, maxx-5, y, fg);
+ m_screen->DrawLine(x+3, y+1, maxx-3, y+1, fg);
+ m_screen->DrawLine(x+2, y+2, maxx-2, y+2, fg);
+ m_screen->DrawLine(x+1, y+3, x+5, y+3, fg);
+ m_screen->DrawLine(maxx-5, y+3, maxx-1, y+3, fg);
+ m_screen->DrawLine(x+1, y+4, x+3, y+4, fg);
+ m_screen->DrawLine(maxx-3, y+4, maxx-1, y+4, fg);
+ m_screen->DrawLine(x, y+5, x+3, y+5, fg);
+ m_screen->DrawLine(maxx-3, y+5, maxx, y+5, fg);
+
+ m_screen->DrawLine(x, y+6, x, maxy-6, fg);
+ m_screen->DrawLine(maxx, y+6, maxx, maxy-6, fg);
+ m_screen->DrawLine(x+1, y+6, x+1, maxy-6, fg);
+ m_screen->DrawLine(maxx-1, y+6, maxx-1, maxy-6, fg);
+ m_screen->DrawLine(x+2, y+6, x+2, maxy-6, fg);
+ m_screen->DrawLine(maxx-2, y+6, maxx-2, maxy-6, fg);
+
+ m_screen->DrawLine(x, maxy-5, x+3, maxy-5, fg);
+ m_screen->DrawLine(maxx-3, maxy-5, maxx, maxy-5, fg);
+ m_screen->DrawLine(x+1, maxy-4, x+3, maxy-4, fg);
+ m_screen->DrawLine(maxx-3, maxy-4, maxx-1, maxy-4, fg);
+ m_screen->DrawLine(x+1, maxy-3, x+5, maxy-3, fg);
+ m_screen->DrawLine(maxx-5, maxy-3, maxx-1, maxy-3, fg);
+ m_screen->DrawLine(x+2, maxy-2, maxx-2, maxy-2, fg);
+ m_screen->DrawLine(x+3, maxy-1, maxx-3, maxy-1, fg);
+ m_screen->DrawLine(x+5, maxy, maxx-5, maxy, fg);
+ }
+
+ UIElementButton::Draw();
+}
+
+void
+UIDialogButton::OnMouseDown()
+{
+ SetElementColor(m_colors[0]);
+
+ UIElementButton::OnMouseDown();
+}
+
+void
+UIDialogButton::OnMouseUp()
+{
+ SetElementColor(m_colors[1]);
+
+ UIElementButton::OnMouseUp();
+}
+
+void
+UIDialogButton::OnClick()
+{
+ UIElementButton::OnClick();
+
+ if (m_closeDialog) {
+ GetUI()->HidePanel(GetUI()->GetCurrentPanel());
+ }
+}
+
+void
+UIDialogButton::SetElementColor(Uint32 color)
+{
+ Uint8 R, G, B;
+
+ m_screen->GetRGB(color, &R, &G, &B);
+ for (unsigned i = 0; i < m_elements.length(); ++i) {
+ if (m_elements[i]->IsA(UIElementLabel::GetType())) {
+ static_cast<UIElementLabel*>(m_elements[i])->SetTextColor(R, G, B);
+ }
+ }
+}
diff --git a/UIDialogButton.h b/UIDialogButton.h
new file mode 100644
index 00000000..0e872e67
--- /dev/null
+++ b/UIDialogButton.h
@@ -0,0 +1,45 @@
+#ifndef _UIDialogButton_h
+#define _UIDialogButton_h
+
+#include "screenlib/UIElementButton.h"
+
+
+class UIDialogButton : public UIElementButton
+{
+public:
+ UIDialogButton(UIBaseElement *parent, const char *name = "");
+ virtual ~UIDialogButton();
+
+ virtual bool IsA(UIElementType type) {
+ return UIElementButton::IsA(type) || type == GetType();
+ }
+
+ virtual bool Load(rapidxml::xml_node<> *node, const UITemplates *templates);
+
+ virtual void Draw();
+
+ virtual void OnMouseDown();
+ virtual void OnMouseUp();
+ virtual void OnClick();
+
+protected:
+ Uint32 m_colors[2];
+ bool m_default;
+ bool m_closeDialog;
+
+protected:
+ void SetElementColor(Uint32 color);
+
+protected:
+ static UIElementType s_elementType;
+
+public:
+ static UIElementType GetType() {
+ if (!s_elementType) {
+ s_elementType = GenerateType();
+ }
+ return s_elementType;
+ }
+};
+
+#endif // _UIDialogButton_h
diff --git a/screenlib/SDL_FrameBuf.h b/screenlib/SDL_FrameBuf.h
index 1a440be8..08e72641 100644
--- a/screenlib/SDL_FrameBuf.h
+++ b/screenlib/SDL_FrameBuf.h
@@ -54,6 +54,11 @@ class FrameBuf : public ErrorBase {
Uint32 MapRGB(Uint8 R, Uint8 G, Uint8 B) {
return (0xFF000000 | ((Uint32)R << 16) | ((Uint32)G << 8) | B);
}
+ void GetRGB(Uint32 color, Uint8 *R, Uint8 *G, Uint8 *B) {
+ *R = (Uint8)((color >> 16) & 0xFF);
+ *G = (Uint8)((color >> 8) & 0xFF);
+ *B = (Uint8)((color >> 0) & 0xFF);
+ }
/* Set the blit clipping rectangle */
void ClipBlit(SDL_Rect *cliprect) {
clip = *cliprect;