https://github.com/libsdl-org/Maelstrom/commit/d2ee1758cb9fb832d003e38d3a4feae38bebef4e
From d2ee1758cb9fb832d003e38d3a4feae38bebef4e Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 29 Oct 2011 18:31:50 -0400
Subject: [PATCH] Switched the controls dialog over to the new UI system
---
MacDialogCheckbox.cpp | 4 -
MacDialogCheckbox.h | 1 -
MacDialogRadioButton.cpp | 84 ++++++++++
MacDialogRadioButton.h | 35 ++++
MaelstromUI.cpp | 6 +-
Makefile.am | 4 +-
UI/UITemplates.xml | 5 +
UI/controls.xml | 84 ++++++++++
controls.cpp | 304 ++++++++++++++++-------------------
controls.h | 49 +++++-
main.cpp | 6 +-
screenlib/UIBaseElement.cpp | 6 +-
screenlib/UIDialog.h | 3 +
screenlib/UIElementRadio.cpp | 24 ++-
screenlib/UIElementRadio.h | 2 +
screenlib/UIPanel.cpp | 13 ++
screenlib/UIPanel.h | 2 +
17 files changed, 454 insertions(+), 178 deletions(-)
create mode 100644 MacDialogRadioButton.cpp
create mode 100644 MacDialogRadioButton.h
create mode 100644 UI/controls.xml
diff --git a/MacDialogCheckbox.cpp b/MacDialogCheckbox.cpp
index 46876a69..e91b2a93 100644
--- a/MacDialogCheckbox.cpp
+++ b/MacDialogCheckbox.cpp
@@ -18,10 +18,6 @@ MacDialogCheckbox::MacDialogCheckbox(UIBaseElement *parent, const char *name) :
SetSize(CHECKBOX_SIZE, CHECKBOX_SIZE);
}
-MacDialogCheckbox::~MacDialogCheckbox()
-{
-}
-
bool
MacDialogCheckbox::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
{
diff --git a/MacDialogCheckbox.h b/MacDialogCheckbox.h
index eb6bc6ac..34e4a712 100644
--- a/MacDialogCheckbox.h
+++ b/MacDialogCheckbox.h
@@ -8,7 +8,6 @@ class MacDialogCheckbox : public UIElementCheckbox
{
public:
MacDialogCheckbox(UIBaseElement *parent, const char *name = "");
- virtual ~MacDialogCheckbox();
virtual bool IsA(UIElementType type) {
return UIElementCheckbox::IsA(type) || type == GetType();
diff --git a/MacDialogRadioButton.cpp b/MacDialogRadioButton.cpp
new file mode 100644
index 00000000..6cd30635
--- /dev/null
+++ b/MacDialogRadioButton.cpp
@@ -0,0 +1,84 @@
+
+#include "screenlib/SDL_FrameBuf.h"
+#include "MacDialogRadioButton.h"
+#include "MacDialogLabel.h"
+
+/* Default checkbox size */
+#define RADIOBUTTON_SIZE 20
+
+UIElementType MacDialogRadioButton::s_elementType;
+
+
+MacDialogRadioButton::MacDialogRadioButton(UIBaseElement *parent, const char *name) :
+ UIElementRadioButton(parent, name)
+{
+ m_color = m_screen->MapRGB(0x00, 0x00, 0x00);
+
+ SetSize(RADIOBUTTON_SIZE, RADIOBUTTON_SIZE);
+}
+
+bool
+MacDialogRadioButton::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
+{
+ rapidxml::xml_attribute<> *attr;
+
+ if (!UIElementRadioButton::Load(node, templates)) {
+ return false;
+ }
+
+ attr = node->first_attribute("text", 0, false);
+ if (attr) {
+ MacDialogLabel *label;
+
+ label = new MacDialogLabel(this, "label");
+ label->SetText(attr->value());
+ label->SetAnchor(TOPLEFT, TOPLEFT, this, 21, 3);
+ AddElement(label);
+
+ /* Extend the sensitive area to encompass the label */
+ SetWidth((label->X()+label->Width()) - X());
+ }
+
+ return true;
+}
+
+void
+MacDialogRadioButton::Draw()
+{
+ int x = X() + 5;
+ int y = Y() + 5;
+
+ /* Draw the circle */
+ m_screen->DrawLine(x+4, y, x+7, y, m_color);
+ m_screen->DrawLine(x+2, y+1, x+3, y+1, m_color);
+ m_screen->DrawLine(x+8, y+1, x+9, y+1, m_color);
+ m_screen->DrawLine(x+1, y+2, x+1, y+3, m_color);
+ m_screen->DrawLine(x+10, y+2, x+10, y+3, m_color);
+ m_screen->DrawLine(x, y+4, x, y+7, m_color);
+ m_screen->DrawLine(x+11, y+4, x+11, y+7, m_color);
+ m_screen->DrawLine(x+1, y+8, x+1, y+9, m_color);
+ m_screen->DrawLine(x+10, y+8, x+10, y+9, m_color);
+ m_screen->DrawLine(x+2, y+10, x+3, y+10, m_color);
+ m_screen->DrawLine(x+8, y+10, x+9, y+10, m_color);
+ m_screen->DrawLine(x+4, y+11, x+7, y+11, m_color);
+
+ if ( IsChecked() ) {
+ /* Draw the spot in the center */
+ x += 3;
+ y += 3;
+
+ m_screen->DrawLine(x+1, y, x+4, y, m_color);
+ ++y;
+ m_screen->DrawLine(x, y, x+5, y, m_color);
+ ++y;
+ m_screen->DrawLine(x, y, x+5, y, m_color);
+ ++y;
+ m_screen->DrawLine(x, y, x+5, y, m_color);
+ ++y;
+ m_screen->DrawLine(x, y, x+5, y, m_color);
+ ++y;
+ m_screen->DrawLine(x+1, y, x+4, y, m_color);
+ }
+
+ UIElementRadioButton::Draw();
+}
diff --git a/MacDialogRadioButton.h b/MacDialogRadioButton.h
new file mode 100644
index 00000000..2076ba8a
--- /dev/null
+++ b/MacDialogRadioButton.h
@@ -0,0 +1,35 @@
+#ifndef _MacDialogRadioButton_h
+#define _MacDialogRadioButton_h
+
+#include "screenlib/UIElementRadio.h"
+
+
+class MacDialogRadioButton : public UIElementRadioButton
+{
+public:
+ MacDialogRadioButton(UIBaseElement *parent, const char *name = "");
+
+ virtual bool IsA(UIElementType type) {
+ return UIElementRadioButton::IsA(type) || type == GetType();
+ }
+
+ virtual bool Load(rapidxml::xml_node<> *node, const UITemplates *templates);
+
+ virtual void Draw();
+
+protected:
+ Uint32 m_color;
+
+protected:
+ static UIElementType s_elementType;
+
+public:
+ static UIElementType GetType() {
+ if (!s_elementType) {
+ s_elementType = GenerateType();
+ }
+ return s_elementType;
+ }
+};
+
+#endif // _MacDialogRadioButton_h
diff --git a/MaelstromUI.cpp b/MaelstromUI.cpp
index 1d14ba0a..880a1d8d 100644
--- a/MaelstromUI.cpp
+++ b/MaelstromUI.cpp
@@ -2,12 +2,14 @@
#include "MaelstromUI.h"
#include "Maelstrom_Globals.h"
#include "main.h"
+#include "controls.h"
#include "netlogic/about.h"
#include "netlogic/game.h"
#include "MacDialog.h"
#include "MacDialogButton.h"
#include "MacDialogCheckbox.h"
#include "MacDialogLabel.h"
+#include "MacDialogRadioButton.h"
#include "UIElementIcon.h"
#include "UIElementKeyButton.h"
#include "UIElementSprite.h"
@@ -158,6 +160,8 @@ MaelstromUI::CreatePanelDelegate(UIPanel *panel, const char *delegate)
return new AboutPanelDelegate(panel);
} else if (strcasecmp(delegate, "GamePanel") == 0) {
return new GamePanelDelegate(panel);
+ } else if (strcasecmp(delegate, "ControlsDialog") == 0) {
+ return new ControlsDialogDelegate(panel);
}
return UIManager::CreatePanelDelegate(panel, delegate);
}
@@ -182,7 +186,7 @@ MaelstromUI::CreateElement(UIBaseElement *parent, const char *type, const char *
} else if (strcasecmp(type, "DialogRadioGroup") == 0) {
return new UIElementRadioGroup(parent, name);
} else if (strcasecmp(type, "DialogRadioButton") == 0) {
- return new UIElementRadioButton(parent, name);
+ return new MacDialogRadioButton(parent, name);
} else if (strcasecmp(type, "KeyButton") == 0) {
return new UIElementKeyButton(parent, name);
} else if (strcasecmp(type, "Icon") == 0) {
diff --git a/Makefile.am b/Makefile.am
index eb1c70e3..c8b09a02 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,7 +39,9 @@ Maelstrom_SOURCES = \
MacDialogCheckbox.cpp \
MacDialogCheckbox.h \
MacDialogLabel.cpp \
- MacDialogLabel.h \
+ MacDialogLabel.h \
+ MacDialogRadioButton.cpp\
+ MacDialogRadioButton.h \
UIElementIcon.cpp \
UIElementIcon.h \
UIElementKeyButton.cpp \
diff --git a/UI/UITemplates.xml b/UI/UITemplates.xml
index eb357f63..7e47e6ec 100644
--- a/UI/UITemplates.xml
+++ b/UI/UITemplates.xml
@@ -86,4 +86,9 @@
</Label>
</Elements>
</KeyButton>
+
+ <Rectangle templateName="ControlKeyBox">
+ <Size w="170" h="20"/>
+ <Color r="0x00" g="0x00" b="0x00"/>
+ </Rectangle>
</UITemplates>
diff --git a/UI/controls.xml b/UI/controls.xml
new file mode 100644
index 00000000..8486206d
--- /dev/null
+++ b/UI/controls.xml
@@ -0,0 +1,84 @@
+<Dialog delegate="ControlsDialog">
+ <Size w="474" h="292"/>
+ <Elements>
+ <Title id="100">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="4" y="4"/>
+ </Icon>
+
+ <Rectangle name="control1_box" template="ControlKeyBox">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="92" y="71"/>
+ </Rectangle>
+ <DialogLabel name="control1">
+ <Anchor anchor="control1_box"/>
+ </DialogLabel>
+ <Rectangle name="control2_box" template="ControlKeyBox">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="control1_box" y="3"/>
+ </Rectangle>
+ <DialogLabel name="control2">
+ <Anchor anchor="control2_box"/>
+ </DialogLabel>
+ <Rectangle name="control3_box" template="ControlKeyBox">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="control2_box" y="3"/>
+ </Rectangle>
+ <DialogLabel name="control3">
+ <Anchor anchor="control3_box"/>
+ </DialogLabel>
+ <Rectangle name="control4_box" template="ControlKeyBox">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="control3_box" y="3"/>
+ </Rectangle>
+ <DialogLabel name="control4">
+ <Anchor anchor="control4_box"/>
+ </DialogLabel>
+ <Rectangle name="control5_box" template="ControlKeyBox">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="control4_box" y="3"/>
+ </Rectangle>
+ <DialogLabel name="control5">
+ <Anchor anchor="control5_box"/>
+ </DialogLabel>
+ <Rectangle name="control6_box" template="ControlKeyBox">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="control5_box" y="3"/>
+ </Rectangle>
+ <DialogLabel name="control6">
+ <Anchor anchor="control6_box"/>
+ </DialogLabel>
+ <Rectangle name="control7_box" template="ControlKeyBox">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="control6_box" y="3"/>
+ </Rectangle>
+ <DialogLabel name="control7">
+ <Anchor anchor="control7_box"/>
+ </DialogLabel>
+
+ <DialogRadioGroup name="controlsRadioGroup">
+ <Elements>
+ <DialogRadioButton text="Fire" id="1">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="control1_box"/>
+ </DialogRadioButton>
+ <DialogRadioButton text="Thrust" id="2">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="control2_box"/>
+ </DialogRadioButton>
+ <DialogRadioButton text="Shield" id="3">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="control3_box"/>
+ </DialogRadioButton>
+ <DialogRadioButton text="Turn Clockwise" id="4">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="control4_box"/>
+ </DialogRadioButton>
+ <DialogRadioButton text="Turn Counter-Clockwise" id="5">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="control5_box"/>
+ </DialogRadioButton>
+ <DialogRadioButton text="Pause" id="6">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="control6_box"/>
+ </DialogRadioButton>
+ <DialogRadioButton text="Abort Game" id="7">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="control7_box"/>
+ </DialogRadioButton>
+ </Elements>
+ </DialogRadioGroup>
+
+ <DialogButton name="cancelButton" text="Cancel">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="291" y="265"/>
+ </DialogButton>
+ <DialogButton text="OK" id="1">
+ <Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="cancelButton"x="25"/>
+ </DialogButton>
+ </Elements>
+</Dialog>
diff --git a/controls.cpp b/controls.cpp
index d92fc8fe..82170413 100644
--- a/controls.cpp
+++ b/controls.cpp
@@ -8,6 +8,9 @@
#include "Maelstrom_Globals.h"
#include "load.h"
#include "dialog.h"
+#include "screenlib/UIDialog.h"
+#include "screenlib/UIElementLabel.h"
+#include "screenlib/UIElementRadio.h"
#define MAELSTROM_DATA ".Maelstrom-data"
@@ -131,186 +134,163 @@ void SaveControls(void)
fclose(data);
}
-#define FIRE_CTL 0
-#define THRUST_CTL 1
-#define SHIELD_CTL 2
-#define TURNR_CTL 3
-#define TURNL_CTL 4
-#define PAUSE_CTL 5
-#define QUIT_CTL 6
-#define NUM_CTLS 7
-
-#define SP 3
-
-#define CTL_DIALOG_WIDTH 482
-#define CTL_DIALOG_HEIGHT 300
-
-Controls newcontrols;
-static struct {
- const char *label;
- int yoffset;
- SDL_Keycode *control;
-} checkboxes[] = {
- { "Fire", 0*BOX_HEIGHT+0*SP, &newcontrols.gFireControl },
- { "Thrust", 1*BOX_HEIGHT+1*SP, &newcontrols.gThrustControl },
- { "Shield", 2*BOX_HEIGHT+2*SP, &newcontrols.gShieldControl },
- { "Turn Clockwise", 3*BOX_HEIGHT+3*SP, &newcontrols.gTurnRControl },
- { "Turn Counter-Clockwise",
- 4*BOX_HEIGHT+4*SP, &newcontrols.gTurnLControl },
- { "Pause", 5*BOX_HEIGHT+5*SP, &newcontrols.gPauseControl },
- { "Abort Game", 6*BOX_HEIGHT+6*SP, &newcontrols.gQuitControl },
-};
-
-static int X=0;
-static int Y=0;
-static SDL_Texture *keynames[NUM_CTLS];
-static int currentbox, valid;
-
-static int OK_callback(void) {
- valid = 1;
- return(1);
-}
-static int Cancel_callback(void) {
- valid = 0;
- return(1);
+bool
+ControlsDialogDelegate::OnLoad()
+{
+ char name[32];
+
+ for (int i = 0; i < SDL_arraysize(m_controlKeys); ++i) {
+ sprintf(name, "control%d", 1+i);
+ m_controlKeys[i] = m_panel->GetElement<UIElementLabel>(name);
+ if (!m_controlKeys[i]) {
+ fprintf(stderr, "Warning: Couldn't find control key label '%s'\n", name);
+ return false;
+ }
+ }
+
+ m_radioGroup = m_panel->GetElement<UIElementRadioGroup>("controlsRadioGroup");
+ if (!m_radioGroup) {
+ fprintf(stderr, "Warning: Couldn't find 'controlsRadioGroup'\n");
+ return false;
+ }
+
+ return true;
}
-static void BoxKeyPress(const SDL_Keysym &key, int *doneflag)
+
+void
+ControlsDialogDelegate::OnShow()
{
- int i;
- SDL_Keycode sym = key.sym;
- char keyname[128];
+ UIElementRadioButton *button;
- if ( sym == *checkboxes[currentbox].control )
- return;
+ button = m_radioGroup->GetRadioButton(1);
+ if (button) {
+ button->SetChecked(true);
+ }
- /* Make sure the key isn't in use! */
- for ( i=0; i<NUM_CTLS; ++i ) {
- if ( sym == *checkboxes[i].control ) {
- sym = *checkboxes[currentbox].control;
-
- /* Clear the current text */
- fontserv->FreeText(keynames[currentbox]);
-
- /* Blit the new message */
- strcpy(keyname, "That key is in use!");
- keynames[currentbox] = fontserv->TextImage(keyname,
- fonts[CHICAGO_12], STYLE_NORM, 0x00, 0x00, 0x00);
- screen->QueueBlit(
- X+96+(BOX_WIDTH-screen->GetImageWidth(keynames[currentbox]))/2,
- Y+75+SP+checkboxes[currentbox].yoffset,
- keynames[currentbox], NOCLIP);
- screen->Update();
- SDL_Delay(1000);
- break;
- }
+ for (int i = 0; i < SDL_arraysize(m_keyinuseTimers); ++i) {
+ m_keyinuseTimers[i] = 0;
}
- /* Clear the current text */
- fontserv->FreeText(keynames[currentbox]);
-
- /* Display the new key */
- *checkboxes[currentbox].control = sym;
- KeyName(*checkboxes[currentbox].control, keyname);
- keynames[currentbox] = fontserv->TextImage(keyname,
- fonts[CHICAGO_12], STYLE_NORM, 0x00, 0x00, 0x00);
- screen->QueueBlit(X+96+(BOX_WIDTH-screen->GetImageWidth(keynames[currentbox]))/2,
- Y+75+SP+checkboxes[currentbox].yoffset,
- keynames[currentbox], NOCLIP);
- screen->Update();
+ m_controls = controls;
+
+ ShowKeyLabels();
}
-void ConfigureControls(void)
+void
+ControlsDialogDelegate::OnHide()
{
-#ifdef FAITHFUL_SPECS
- static char *C_text1 =
- "While playing Maelstrom, CAPS LOCK pauses the game and";
- static char *C_text2 =
- "ESC aborts the game.";
- SDL_Texture *text1, *text2;
-#endif
- MFont *chicago;
- Uint32 black;
- int i;
- char keyname[128];
- Maclike_Dialog *dialog;
- SDL_Texture *splash;
- Mac_Button *cancel, *okay;
- Mac_RadioList *radiobuttons;
- Mac_Dialog *boxes;
+ if (m_panel->IsA(UIDialog::GetType()) &&
+ static_cast<UIDialog*>(m_panel)->GetDialogStatus() > 0) {
+ controls = m_controls;
+ SaveControls();
+ }
+}
+void
+ControlsDialogDelegate::OnTick()
+{
+ for (int i = 0; i < SDL_arraysize(m_keyinuseTimers); ++i) {
+ if (m_keyinuseTimers[i] && (SDL_GetTicks() - m_keyinuseTimers[i]) > 1000) {
+ m_keyinuseTimers[i] = 0;
+ ShowKeyLabel(i);
+ }
+ }
+}
- /* Set up all the components of the dialog box */
- black = screen->MapRGB(0x00, 0x00, 0x00);
- chicago = fonts[CHICAGO_12];
- if ( (splash = Load_Title(screen, 100)) == NULL ) {
- error("Can't load configuration splash!\n");
- return;
+bool
+ControlsDialogDelegate::HandleEvent(const SDL_Event &event)
+{
+ if (event.type == SDL_KEYDOWN) {
+ return true;
}
- X=(SCREEN_WIDTH-CTL_DIALOG_WIDTH)/2;
- Y=(SCREEN_HEIGHT-CTL_DIALOG_HEIGHT)/2;
- dialog = new Maclike_Dialog(X, Y, CTL_DIALOG_WIDTH, CTL_DIALOG_HEIGHT,
- screen);
- dialog->Add_Image(splash, 4, 4);
-#ifdef FAITHFUL_SPECS
- text1 = fontserv->TextImage(C_text1,chicago,STYLE_NORM,0x00,0x00,0x00);
- text2 = fontserv->TextImage(C_text2,chicago,STYLE_NORM,0x00,0x00,0x00);
- dialog->Add_Image(text1, 66, 216);
- dialog->Add_Image(text2, 66, 232);
-#endif
- valid = 0;
- cancel = new Mac_Button(291, 265, BUTTON_WIDTH, BUTTON_HEIGHT,
- "Cancel", chicago, fontserv, Cancel_callback);
- dialog->Add_Dialog(cancel);
- okay = new Mac_Button(291+BUTTON_WIDTH+26, 265,
- BUTTON_WIDTH, BUTTON_HEIGHT,
- "OK", chicago, fontserv, OK_callback);
- dialog->Add_Dialog(okay);
- memcpy(&newcontrols, &controls, sizeof(controls));
- radiobuttons = new Mac_RadioList(¤tbox, X+266, Y+75,
- chicago, fontserv);
- currentbox = FIRE_CTL;
- for ( i=0; i<NUM_CTLS; ++i ) {
- KeyName(*checkboxes[i].control, keyname);
- keynames[i] = fontserv->TextImage(keyname, chicago, STYLE_NORM,
- 0x00, 0x00, 0x00);
- /* Only display "Fire" through "Turn Counter-Clockwise" */
-#ifdef FAITHFUL_SPECS
- if ( i < PAUSE_CTL ) {
-#else
- if ( i < NUM_CTLS ) {
-#endif
- radiobuttons->Add_Radio(263, 71+checkboxes[i].yoffset,
- checkboxes[i].label);
- dialog->Add_Rectangle(92, 71+checkboxes[i].yoffset,
- BOX_WIDTH, BOX_HEIGHT, black);
- dialog->Add_Image(keynames[i],
- 92+(BOX_WIDTH-screen->GetImageWidth(keynames[i]))/2,
- 71+SP+checkboxes[i].yoffset);
+ if (event.type == SDL_KEYUP) {
+ int index;
+ SDL_Keycode key = event.key.keysym.sym;
+
+ index = m_radioGroup->GetValue() - 1;
+
+ /* See if this key is in use */
+ m_keyinuseTimers[index] = 0;
+ for (int i = 0; i < NUM_CTLS; ++i) {
+ if (i != index && key == GetKeycode(i)) {
+ m_keyinuseTimers[index] = SDL_GetTicks();
+ break;
+ }
}
+ if (!m_keyinuseTimers[index]) {
+ SetKeycode(index, key);
+ }
+ ShowKeyLabel(index);
+
+ return true;
}
- dialog->Add_Dialog(radiobuttons);
- boxes = new Mac_Dialog(92, 71);
- boxes->SetKeyPress(BoxKeyPress);
- dialog->Add_Dialog(boxes);
+ return false;
+}
- /* Run the dialog box */
- dialog->Run(EXPAND_STEPS);
+void
+ControlsDialogDelegate::ShowKeyLabel(int index)
+{
+ const char *text;
- /* Clean up and return */
- screen->FreeImage(splash);
-#ifdef FAITHFUL_SPECS
- fontserv->FreeText(text1);
- fontserv->FreeText(text2);
-#endif
- for ( i=0; i<NUM_CTLS; ++i ) {
- fontserv->FreeText(keynames[i]);
+ if (m_keyinuseTimers[index]) {
+ text = "That key is in use!";
+ } else {
+ text = SDL_GetKeyName(GetKeycode(index));
}
- delete dialog;
- if ( valid ) {
- memcpy(&controls, &newcontrols, sizeof(controls));
- SaveControls();
+ m_controlKeys[index]->SetText(text);
+}
+
+SDL_Keycode
+ControlsDialogDelegate::GetKeycode(int index)
+{
+ switch (index) {
+ case FIRE_CTL:
+ return m_controls.gFireControl;
+ case THRUST_CTL:
+ return m_controls.gThrustControl;
+ case SHIELD_CTL:
+ return m_controls.gShieldControl;
+ case TURNR_CTL:
+ return m_controls.gTurnRControl;
+ case TURNL_CTL:
+ return m_controls.gTurnLControl;
+ case PAUSE_CTL:
+ return m_controls.gPauseControl;
+ case QUIT_CTL:
+ return m_controls.gQuitControl;
+ default:
+ return SDLK_UNKNOWN;
+ }
+}
+
+void
+ControlsDialogDelegate::SetKeycode(int index, SDL_Keycode keycode)
+{
+ switch (index) {
+ case FIRE_CTL:
+ m_controls.gFireControl = keycode;
+ break;
+ case THRUST_CTL:
+ m_controls.gThrustControl = keycode;
+ break;
+ case SHIELD_CTL:
+ m_controls.gShieldControl = keycode;
+ break;
+ case TURNR_CTL:
+ m_controls.gTurnRControl = keycode;
+ break;
+ case TURNL_CTL:
+ m_controls.gTurnLControl = keycode;
+ break;
+ case PAUSE_CTL:
+ m_controls.gPauseControl = keycode;
+ break;
+ case QUIT_CTL:
+ m_controls.gQuitControl = keycode;
+ break;
+ default:
+ break;
}
- return;
}
static void HandleEvent(SDL_Event *event)
diff --git a/controls.h b/controls.h
index 916ddcaa..f9816c1c 100644
--- a/controls.h
+++ b/controls.h
@@ -1,11 +1,13 @@
+#ifndef _controls_h
+#define _controls_h
+
// Functions from controls.cc
#ifdef USE_JOYSTICK
extern void CalibrateJoystick(char *joystick);
#endif
extern void LoadControls(void);
extern void SaveControls(void);
-extern void ConfigureControls(void);
extern int PollEvent(SDL_Event *event, int timeout);
extern void HandleEvents(int timeout);
extern int DropEvents(void);
@@ -31,3 +33,48 @@ typedef struct {
SDL_Keycode gQuitControl;
} Controls;
+
+class UIElementLabel;
+class UIElementRadioGroup;
+
+class ControlsDialogDelegate : public UIPanelDelegate
+{
+public:
+ ControlsDialogDelegate(UIPanel *panel) : UIPanelDelegate(panel) { }
+
+ virtual bool OnLoad();
+ virtual void OnShow();
+ virtual void OnHide();
+ virtual void OnTick();
+ virtual bool HandleEvent(const SDL_Event &event);
+
+protected:
+ void ShowKeyLabel(int index);
+ void ShowKeyLabels() {
+ for (int i = 0; i < NUM_CTLS; ++i) {
+ ShowKeyLabel(i);
+ }
+ }
+
+ SDL_Keycode GetKeycode(int index);
+ void SetKeycode(int index, SDL_Keycode keycode);
+
+protected:
+ enum {
+ FIRE_CTL,
+ THRUST_CTL,
+ SHIELD_CTL,
+ TURNR_CTL,
+ TURNL_CTL,
+ PAUSE_CTL,
+ QUIT_CTL,
+ NUM_CTLS
+ };
+
+ Controls m_controls;
+ UIElementLabel *m_controlKeys[NUM_CTLS];
+ UIElementRadioGroup *m_radioGroup;
+ Uint32 m_keyinuseTimers[NUM_CTLS];
+};
+
+#endif /* _controls_h */
diff --git a/main.cpp b/main.cpp
index a73ccead..e29d239b 100644
--- a/main.cpp
+++ b/main.cpp
@@ -41,10 +41,6 @@ static void RunDoAbout(void)
{
ui->ShowPanel(PANEL_ABOUT);
}
-static void RunConfigureControls(void)
-{
- ConfigureControls();
-}
static void RunPlayGame(void)
{
gStartLives = 3;
@@ -358,7 +354,7 @@ MainPanelDelegate::OnLoad()
}
button = m_panel->GetElement<UIElementButton>("ControlsButton");
if (button) {
- button->SetClickCallback(RunConfigureControls);
+ button->SetButtonDelegate(new UIDialogLauncher(ui, DIALOG_CONTROLS));
}
button = m_panel->GetElement<UIElementButton>("ZapButton");
if (button) {
diff --git a/screenlib/UIBaseElement.cpp b/screenlib/UIBaseElement.cpp
index f6a93a0b..5f9b8412 100644
--- a/screenlib/UIBaseElement.cpp
+++ b/screenlib/UIBaseElement.cpp
@@ -87,7 +87,11 @@ UIBaseElement::GetAnchorElement(const char *name)
{
if (name) {
if (m_parent) {
- return m_parent->GetElement(name);
+ UIArea *element = m_parent->GetElement(name);
+ if (!element) {
+ element = m_parent->GetAnchorElement(name);
+ }
+ return element;
} else {
return NULL;
}
diff --git a/screenlib/UIDialog.h b/screenlib/UIDialog.h
index 22bc79ee..9e8d60eb 100644
--- a/screenlib/UIDialog.h
+++ b/screenlib/UIDialog.h
@@ -55,6 +55,9 @@ class UIDialog : public UIPanel
void SetDialogStatus(int status) {
m_status = status;
}
+ int GetDialogStatus() const {
+ return m_status;
+ }
virtual void Show();
virtual void Hide();
diff --git a/screenlib/UIElementRadio.cpp b/screenlib/UIElementRadio.cpp
index 763db024..601c8ecc 100644
--- a/screenlib/UIElementRadio.cpp
+++ b/screenlib/UIElementRadio.cpp
@@ -10,12 +10,32 @@ UIElementRadioGroup::UIElementRadioGroup(UIBaseElement *parent, const char *name
m_value = -1;
}
+UIElementRadioButton *
+UIElementRadioGroup::GetRadioButton(int id)
+{
+ UIElementRadioButton *button;
+
+ for (unsigned i = 0; i < m_elements.length(); ++i) {
+ if (!m_elements[i]->IsA(UIElementRadioButton::GetType())) {
+ continue;
+ }
+
+ button = static_cast<UIElementRadioButton*>(m_elements[i]);
+ if (button->GetID() == id) {
+ return button;
+ }
+ }
+ return NULL;
+}
+
void
UIElementRadioGroup::RadioButtonChecked(UIElementRadioButton *button)
{
for (unsigned i = 0; i < m_elements.length(); ++i) {
- if (m_elements[i] != button &&
- m_elements[i]->IsA(UIElementRadioButton::GetType())) {
+ if (!m_elements[i]->IsA(UIElementRadioButton::GetType())) {
+ continue;
+ }
+ if (m_elements[i] != button) {
static_cast<UIElementRadioButton*>(m_elements[i])->SetChecked(false);
}
}
diff --git a/screenlib/UIElementRadio.h b/screenlib/UIElementRadio.h
index 0c336a17..08eb29b0 100644
--- a/screenlib/UIElementRadio.h
+++ b/screenlib/UIElementRadio.h
@@ -45,6 +45,8 @@ class UIElementRadioGroup : public UIElement
return UIElement::IsA(type) || type == GetType();
}
+ UIElementRadioButton *GetRadioButton(int id);
+
void RadioButtonChecked(UIElementRadioButton *button);
int GetValue() const {
diff --git a/screenlib/UIPanel.cpp b/screenlib/UIPanel.cpp
index 87e3502f..fca8e1df 100644
--- a/screenlib/UIPanel.cpp
+++ b/screenlib/UIPanel.cpp
@@ -134,3 +134,16 @@ UIPanel::Draw()
m_delegate->OnDraw();
}
}
+
+bool
+UIPanel::HandleEvent(const SDL_Event &event)
+{
+ if (UIBaseElement::HandleEvent(event)) {
+ return true;
+ }
+
+ if (m_delegate) {
+ return m_delegate->HandleEvent(event);
+ }
+ return false;
+}
diff --git a/screenlib/UIPanel.h b/screenlib/UIPanel.h
index d334568d..d4cbb7ed 100644
--- a/screenlib/UIPanel.h
+++ b/screenlib/UIPanel.h
@@ -44,6 +44,7 @@ class UIPanelDelegate
virtual void OnHide() { }
virtual void OnTick() { }
virtual void OnDraw() { }
+ virtual bool HandleEvent(const SDL_Event &event) { return false; }
protected:
UIPanel *m_panel;
@@ -73,6 +74,7 @@ class UIPanel : public UIBaseElement
void HideAll();
virtual void Draw();
+ virtual bool HandleEvent(const SDL_Event &event);
protected:
bool m_fullscreen;