summaryrefslogtreecommitdiff
path: root/src/gui/charselectdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/charselectdialog.cpp')
-rw-r--r--src/gui/charselectdialog.cpp269
1 files changed, 149 insertions, 120 deletions
diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp
index 0489a6cb..dd2368ef 100644
--- a/src/gui/charselectdialog.cpp
+++ b/src/gui/charselectdialog.cpp
@@ -25,6 +25,7 @@
#include "localplayer.h"
#include "main.h"
#include "units.h"
+#include "log.h"
#include "gui/changeemaildialog.h"
#include "gui/changepassworddialog.h"
@@ -56,6 +57,7 @@
#include <guichan/font.hpp>
#include <string>
+#include <cassert>
/**
* Listener for confirming character deletion.
@@ -63,48 +65,45 @@
class CharDeleteConfirm : public ConfirmDialog
{
public:
- CharDeleteConfirm(CharSelectDialog *m):
+ CharDeleteConfirm(CharSelectDialog *m, int index):
ConfirmDialog(_("Confirm Character Delete"),
_("Are you sure you want to delete this character?"), m),
- master(m)
+ mMaster(m),
+ mIndex(index)
{
}
void action(const gcn::ActionEvent &event)
{
- //ConfirmDialog::action(event);
if (event.getId() == "yes")
- {
- master->attemptCharDelete();
- }
+ mMaster->attemptCharacterDelete(mIndex);
+
ConfirmDialog::action(event);
}
private:
- CharSelectDialog *master;
+ CharSelectDialog *mMaster;
+ int mIndex;
};
-class CharEntry : public Container
+class CharacterDisplay : public Container
{
public:
- CharEntry(CharSelectDialog *m, char slot, LocalPlayer *chr);
+ CharacterDisplay(CharSelectDialog *charSelectDialog);
- char getSlot() const
- { return mSlot; }
+ void setCharacter(Net::Character *character);
- LocalPlayer *getChar() const
+ Net::Character *getCharacter() const
{ return mCharacter; }
- void setChar(LocalPlayer *chr);
-
void requestFocus();
+ void setActive(bool active);
+
+ private:
void update();
- protected:
- friend class CharSelectDialog;
- char mSlot;
- LocalPlayer *mCharacter;
+ Net::Character *mCharacter;
PlayerBox *mPlayerBox;
Label *mName;
@@ -114,10 +113,11 @@ class CharEntry : public Container
Button *mDelete;
};
-CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo,
- LoginData *loginData):
+CharSelectDialog::CharSelectDialog(LoginData *loginData):
Window(_("Account and Character Management")),
- mCharInfo(charInfo),
+ mLocked(false),
+ mUnregisterButton(0),
+ mChangeEmailButton(0),
mLoginData(loginData),
mCharHandler(Net::getCharHandler())
{
@@ -128,12 +128,6 @@ CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo,
mChangePasswordButton = new Button(_("Change Password"), "change_password",
this);
- for (int i = 0; i < MAX_CHARACTER_COUNT; i++)
- {
- charInfo->select(i);
- mCharEntries[i] = new CharEntry(this, i, charInfo->getEntry());
- }
-
int optionalActions = Net::getLoginHandler()->supportedOptionalActions();
ContainerPlacer place;
@@ -144,79 +138,85 @@ CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo,
if (optionalActions & Net::LoginHandler::Unregister)
{
- gcn::Button *unregisterButton = new Button(_("Unregister"),
- "unregister", this);
- place(3, 1, unregisterButton);
+ mUnregisterButton = new Button(_("Unregister"),
+ "unregister", this);
+ place(3, 1, mUnregisterButton);
}
place(0, 2, mChangePasswordButton);
if (optionalActions & Net::LoginHandler::ChangeEmail)
{
- gcn::Button *changeEmailButton = new Button(_("Change Email"),
- "change_email", this);
- place(3, 2, changeEmailButton);
+ mChangeEmailButton = new Button(_("Change Email"),
+ "change_email", this);
+ place(3, 2, mChangeEmailButton);
}
place = getPlacer(0, 1);
- place(0, 0, mCharEntries[0]);
- place(1, 0, mCharEntries[1]);
- place(2, 0, mCharEntries[2]);
+
+ for (int i = 0; i < MAX_CHARACTER_COUNT; i++) {
+ mCharacterEntries[i] = new CharacterDisplay(this);
+ place(i, 0, mCharacterEntries[i]);
+ }
reflowLayout();
addKeyListener(this);
center();
- mCharEntries[0]->requestFocus();
+ mCharacterEntries[0]->requestFocus();
setVisible(true);
Net::getCharHandler()->setCharSelectDialog(this);
}
+CharSelectDialog::~CharSelectDialog()
+{
+}
+
void CharSelectDialog::action(const gcn::ActionEvent &event)
{
+ // Check if a button of a character was pressed
const gcn::Widget *sourceParent = event.getSource()->getParent();
+ int selected = -1;
+ for (unsigned i = 0; i < MAX_CHARACTER_COUNT; ++i)
+ if (mCharacterEntries[i] == sourceParent)
+ selected = i;
- // Update which character is selected when applicable
- if (const CharEntry *entry = dynamic_cast<const CharEntry*>(sourceParent))
- mCharInfo->select(entry->getSlot());
+ const std::string &eventId = event.getId();
- if (event.getId() == "use")
- {
- chooseSelected();
- }
- else if (event.getId() == "switch")
+ if (selected != -1)
{
- mCharInfo->clear();
- state = STATE_SWITCH_LOGIN;
- }
- else if (event.getId() == "new")
- {
- if (!(mCharInfo->getEntry()))
+ if (eventId == "use")
+ {
+ attemptCharacterSelect(selected);
+ }
+ else if (eventId == "new" && !mCharacterEntries[selected]->getCharacter())
{
// Start new character dialog
CharCreateDialog *charCreateDialog =
- new CharCreateDialog(this, mCharInfo->getPos());
+ new CharCreateDialog(this, selected);
mCharHandler->setCharCreateDialog(charCreateDialog);
}
- }
- else if (event.getId() == "delete")
- {
- if (mCharInfo->getEntry())
+ else if (eventId == "delete"
+ && mCharacterEntries[selected]->getCharacter())
{
- new CharDeleteConfirm(this);
+ new CharDeleteConfirm(this, selected);
}
}
- else if (event.getId() == "change_password")
+ else if (eventId == "switch")
+ {
+ state = STATE_SWITCH_LOGIN;
+ }
+ else if (eventId == "change_password")
{
state = STATE_CHANGEPASSWORD;
}
- else if (event.getId() == "change_email")
+ else if (eventId == "change_email")
{
state = STATE_CHANGEEMAIL;
}
- else if (event.getId() == "unregister")
+ else if (eventId == "unregister")
{
state = STATE_UNREGISTER;
}
@@ -228,90 +228,111 @@ void CharSelectDialog::keyPressed(gcn::KeyEvent &keyEvent)
if (key.getValue() == Key::ESCAPE)
{
- action(gcn::ActionEvent(mSwitchLoginButton, mSwitchLoginButton->getActionEventId()));
+ action(gcn::ActionEvent(mSwitchLoginButton,
+ mSwitchLoginButton->getActionEventId()));
}
}
-void CharSelectDialog::attemptCharDelete()
+/**
+ * Communicate character deletion to the server.
+ */
+void CharSelectDialog::attemptCharacterDelete(int index)
{
- mCharHandler->deleteCharacter(mCharInfo->getPos(), mCharInfo->getEntry());
- mCharInfo->lock();
+ if (mLocked)
+ return;
+
+ mCharHandler->deleteCharacter(mCharacterEntries[index]->getCharacter());
+ lock();
}
-void CharSelectDialog::attemptCharSelect()
+/**
+ * Communicate character selection to the server.
+ */
+void CharSelectDialog::attemptCharacterSelect(int index)
{
- mCharHandler->chooseCharacter(mCharInfo->getPos(), mCharInfo->getEntry());
- mCharInfo->lock();
+ if (mLocked)
+ return;
+
+ mCharHandler->chooseCharacter(mCharacterEntries[index]->getCharacter());
+ lock();
}
-bool CharSelectDialog::selectByName(const std::string &name)
+void CharSelectDialog::setCharacters(const Net::Characters &characters)
{
- if (mCharInfo->isLocked())
- return false;
-
- unsigned int oldPos = mCharInfo->getPos();
+ // Reset previous characters
+ for (int i = 0; i < MAX_CHARACTER_COUNT; ++i)
+ mCharacterEntries[i]->setCharacter(0);
- mCharInfo->select(0);
- do
+ Net::Characters::const_iterator i, i_end = characters.end();
+ for (i = characters.begin(); i != i_end; ++i)
{
- LocalPlayer *player = mCharInfo->getEntry();
-
- if (player && player->getName() == name)
- {
- mCharEntries[mCharInfo->getPos()]->requestFocus();
- return true;
+ Net::Character *character = *i;
+ if (character->slot >= MAX_CHARACTER_COUNT) {
+ logger->log("Warning: slot out of range: %d", character->slot);
+ continue;
}
- mCharInfo->next();
- } while (mCharInfo->getPos());
+ mCharacterEntries[character->slot]->setCharacter(character);
+ }
+}
- mCharInfo->select(oldPos);
+void CharSelectDialog::lock()
+{
+ assert(!mLocked);
+ setLocked(true);
+}
- return false;
+void CharSelectDialog::unlock()
+{
+ setLocked(false);
}
-bool CharSelectDialog::chooseSelected()
+void CharSelectDialog::setLocked(bool locked)
{
- if (!mCharInfo->getSize())
- return false;
+ mLocked = locked;
- setVisible(false);
- attemptCharSelect();
+ mSwitchLoginButton->setEnabled(!locked);
+ mChangePasswordButton->setEnabled(!locked);
+ if (mUnregisterButton)
+ mUnregisterButton->setEnabled(!locked);
+ if (mChangeEmailButton)
+ mChangeEmailButton->setEnabled(!locked);
- return true;
+ for (int i = 0; i < MAX_CHARACTER_COUNT; ++i)
+ mCharacterEntries[i]->setActive(!mLocked);
}
-void CharSelectDialog::update(int slot)
+bool CharSelectDialog::selectByName(const std::string &name,
+ SelectAction action)
{
- if (slot >= 0 && slot < MAX_CHARACTER_COUNT)
- {
- mCharInfo->select(slot);
- mCharEntries[slot]->setChar(mCharInfo->getEntry());
- mCharEntries[slot]->requestFocus();
- }
- else
- {
- int slot = mCharInfo->getPos();
- for (int i = 0; i < MAX_CHARACTER_COUNT; i++)
- {
- mCharInfo->select(slot);
- mCharEntries[slot]->setChar(mCharInfo->getEntry());
+ if (mLocked)
+ return false;
+
+ for (unsigned i = 0; i < MAX_CHARACTER_COUNT; ++i) {
+ if (Net::Character *character = mCharacterEntries[i]->getCharacter()) {
+ if (character->dummy->getName() == name) {
+ mCharacterEntries[i]->requestFocus();
+ if (action == Choose)
+ attemptCharacterSelect(i);
+ return true;
+ }
}
- mCharInfo->select(slot);
}
+
+ return false;
}
-CharEntry::CharEntry(CharSelectDialog *m, char slot, LocalPlayer *chr):
- mSlot(slot),
- mCharacter(chr),
- mPlayerBox(new PlayerBox(chr))
+
+CharacterDisplay::CharacterDisplay(CharSelectDialog *charSelectDialog):
+ mCharacter(0),
+ mPlayerBox(new PlayerBox)
{
- mButton = new Button("wwwwwwwww", "go", m);
+ mButton = new Button("wwwwwwwww", "go", charSelectDialog);
mName = new Label("wwwwwwwwwwwwwwwwwwwwwwww");
mLevel = new Label("(888)");
mMoney = new Label("wwwwwwwww");
- mDelete = new Button(_("Delete"), "delete", m);
+ mDelete = new Button(_("Delete"), "delete", charSelectDialog);
LayoutHelper h(this);
ContainerPlacer place = h.getPlacer(0, 0);
@@ -337,29 +358,37 @@ CharEntry::CharEntry(CharSelectDialog *m, char slot, LocalPlayer *chr):
mMoney->getHeight() + mButton->getHeight() + mDelete->getHeight());
}
-void CharEntry::setChar(LocalPlayer *chr)
+void CharacterDisplay::setCharacter(Net::Character *character)
{
- mCharacter = chr;
-
- mPlayerBox->setPlayer(chr);
+ if (mCharacter == character)
+ return;
+ mCharacter = character;
+ mPlayerBox->setPlayer(character ? character->dummy : 0);
update();
}
-void CharEntry::requestFocus()
+void CharacterDisplay::requestFocus()
{
mButton->requestFocus();
}
-void CharEntry::update()
+void CharacterDisplay::setActive(bool active)
+{
+ mButton->setEnabled(active);
+ mDelete->setEnabled(active);
+}
+
+void CharacterDisplay::update()
{
if (mCharacter)
{
+ const LocalPlayer *character = mCharacter->dummy;
mButton->setCaption(_("Choose"));
mButton->setActionEventId("use");
- mName->setCaption(strprintf("%s", mCharacter->getName().c_str()));
- mLevel->setCaption(strprintf("Level %d", mCharacter->getLevel()));
- mMoney->setCaption(Units::formatCurrency(mCharacter->getMoney()));
+ mName->setCaption(strprintf("%s", character->getName().c_str()));
+ mLevel->setCaption(strprintf("Level %d", character->getLevel()));
+ mMoney->setCaption(Units::formatCurrency(character->getMoney()));
mDelete->setVisible(true);
}