From 76c98ce0c8e78778f73d6a5728441897e134fb9e Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 22 Apr 2013 12:16:20 +0300 Subject: Improve a bit look in character selection window. Add selection skin for playerbox. New theme file: playerboxselected.xml --- src/gui/charcreatedialog.cpp | 3 +- src/gui/charselectdialog.cpp | 534 ++++++++------------------------ src/gui/charselectdialog.h | 17 +- src/gui/equipmentwindow.cpp | 3 +- src/gui/widgets/characterdisplay.cpp | 83 +++++ src/gui/widgets/characterdisplay.h | 79 +++++ src/gui/widgets/characterviewbase.h | 65 ++++ src/gui/widgets/characterviewnormal.cpp | 85 +++++ src/gui/widgets/characterviewnormal.h | 50 +++ src/gui/widgets/characterviewsmall.cpp | 112 +++++++ src/gui/widgets/characterviewsmall.h | 54 ++++ src/gui/widgets/playerbox.cpp | 52 +++- src/gui/widgets/playerbox.h | 16 +- 13 files changed, 724 insertions(+), 429 deletions(-) create mode 100644 src/gui/widgets/characterdisplay.cpp create mode 100644 src/gui/widgets/characterdisplay.h create mode 100644 src/gui/widgets/characterviewbase.h create mode 100644 src/gui/widgets/characterviewnormal.cpp create mode 100644 src/gui/widgets/characterviewnormal.h create mode 100644 src/gui/widgets/characterviewsmall.cpp create mode 100644 src/gui/widgets/characterviewsmall.h (limited to 'src/gui') diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index 4f5a7e811..b8134313e 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -105,7 +105,8 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *const parent, mRace(0), mPlayer(new Being(0, ActorSprite::PLAYER, static_cast(mRace), nullptr)), - mPlayerBox(new PlayerBox(mPlayer, "charcreate_playerbox.xml")), + mPlayerBox(new PlayerBox(mPlayer, "charcreate_playerbox.xml", + "charcreate_selectedplayerbox.xml")), mHairStyle(0), mHairColor(0), mSlot(slot), diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp index 6b6036cd3..4afe7ae38 100644 --- a/src/gui/charselectdialog.cpp +++ b/src/gui/charselectdialog.cpp @@ -24,40 +24,26 @@ #include "client.h" #include "units.h" -#include "keydata.h" #include "keyevent.h" -#include "gui/changeemaildialog.h" -#include "gui/changepassworddialog.h" #include "gui/charcreatedialog.h" #include "gui/confirmdialog.h" #include "gui/logindialog.h" #include "gui/okdialog.h" #include "gui/textdialog.h" -#include "gui/unregisterdialog.h" #include "gui/widgets/button.h" +#include "gui/widgets/characterdisplay.h" +#include "gui/widgets/characterviewnormal.h" +#include "gui/widgets/characterviewsmall.h" #include "gui/widgets/container.h" -#include "gui/widgets/label.h" #include "gui/widgets/layout.h" -#include "gui/widgets/layouthelper.h" -#include "gui/widgets/playerbox.h" -#include "gui/widgets/textfield.h" #include "net/logindata.h" #include "net/loginhandler.h" -#include "net/messageout.h" -#include "net/net.h" - -#include "resources/colordb.h" #include "utils/gettext.h" -#include -#include - -#include - #include "debug.h" // Character slots per row in the dialog @@ -93,179 +79,22 @@ class CharDeleteConfirm final : public ConfirmDialog int mIndex; }; -class CharacterDisplay final : public Container -{ - public: - CharacterDisplay(const Widget2 *const widget, - CharSelectDialog *const charSelectDialog); - - A_DELETE_COPY(CharacterDisplay) - - void setCharacter(Net::Character *const character); - - Net::Character *getCharacter() const - { return mCharacter; } - - void requestFocus(); - - void setActive(const bool active); - - bool isSelectFocused() const - { return mButton->isFocused(); } - - bool isDeleteFocused() const - { return mDelete->isFocused(); } - - void focusSelect() - { mFocusHandler->requestFocus(mButton); } - - void focusDelete() - { mFocusHandler->requestFocus(mDelete); } - - private: - void update(); - - Net::Character *mCharacter; - - PlayerBox *mPlayerBox; - Label *mName; - Label *mLevel; - Label *mMoney; - Button *mButton; - Button *mDelete; -}; - -class CharacterViewBase : public Container, - public gcn::ActionListener -{ - public: - CharacterViewBase(CharSelectDialog *const widget) : - Container(widget), - gcn::ActionListener(), - mSelected(0) - { - } - - A_DELETE_COPY(CharacterViewBase) - - virtual ~CharacterViewBase() - { } - - virtual void show(const int i) = 0; - - virtual void resize() = 0; - - int getSelected() - { - return mSelected; - } - - protected: - int mSelected; -}; - -class CharacterViewSmall final : public CharacterViewBase -{ - public: - CharacterViewSmall(CharSelectDialog *const widget, - std::vector *const entries) : - CharacterViewBase(widget), - mSelectedEntry(nullptr), - mPrevious(new Button(this, "<", "prev", this)), - mNext(new Button(this, ">", "next", this)), - mNumber(new Label(this, "??")), - mCharacterEntries(entries) - { - addKeyListener(widget); - if (entries) - { - FOR_EACHP (std::vector::iterator, - it, entries) - { - CharacterDisplay *character = *it; - add(character); - } - show(0); - } - add(mPrevious); - add(mNext); - add(mNumber); - - setHeight(200); - } - - A_DELETE_COPY(CharacterViewSmall) - - void show(const int i) - { - const int sz = static_cast(mCharacterEntries->size()); - if (mSelectedEntry) - mSelectedEntry->setVisible(false); - if (i >= sz) - mSelected = 0; - else if (i < 0) - mSelected = mCharacterEntries->size() - 1; - else - mSelected = i; - mSelectedEntry = (*mCharacterEntries)[mSelected]; - mSelectedEntry->setVisible(true); - mNumber->setCaption(strprintf("%d / %d", mSelected + 1, sz)); - mNumber->adjustSize(); - } - - void resize() - { - const CharacterDisplay *const firtChar = (*mCharacterEntries)[0]; - const int x = (getWidth() - firtChar->getWidth()) / 2; - const int y = (getHeight() - firtChar->getHeight()) / 2; - FOR_EACHP (std::vector::iterator, - it, mCharacterEntries) - { - (*it)->setPosition(x, y); - } - const int y2 = (getHeight() - mPrevious->getHeight()) / 2; - const int y3 = y2 - 55; - mPrevious->setPosition(x - mPrevious->getWidth() - 10, y3); - mNext->setPosition(getWidth() - x + 10, y3); - mNumber->setPosition(10, y2); - } - - void action(const gcn::ActionEvent &event) override - { - const std::string &eventId = event.getId(); - if (eventId == "next") - { - mSelected ++; - show(mSelected); - } - else if (eventId == "prev") - { - mSelected --; - show(mSelected); - } - } - - private: - CharacterDisplay *mSelectedEntry; - Button *mPrevious; - Button *mNext; - Label *mNumber; - std::vector *mCharacterEntries; -}; - CharSelectDialog::CharSelectDialog(LoginData *const data): - Window(_("Account and Character Management"), false, nullptr, "char.xml"), + Window(strprintf(_("Account %s (last login time %s)"), + data->username.c_str(), data->lastLogin.c_str()), + false, nullptr, "char.xml"), gcn::ActionListener(), gcn::KeyListener(), mLocked(false), mLoginData(data), - mAccountNameLabel(new Label(this, mLoginData->username)), - mLastLoginLabel(new Label(this, mLoginData->lastLogin)), mSwitchLoginButton(new Button(this, _("Switch Login"), "switch", this)), mChangePasswordButton(new Button(this, _("Change Password"), "change_password", this)), mUnregisterButton(nullptr), mChangeEmailButton(nullptr), + mPlayButton(new Button(this, _("Play"), "use", this)), + mInfoButton(new Button(this, _("Info"), "info", this)), + mDeleteButton(new Button(this, _("Delete"), "delete", this)), mCharacterView(nullptr), mCharacterEntries(0), mCharServerHandler(Net::getCharServerHandler()), @@ -275,6 +104,7 @@ CharSelectDialog::CharSelectDialog(LoginData *const data): || mainGraphics->getHeight() < 485) { setCloseButton(true); + setFocusable(true); const int optionalActions = Net::getLoginHandler() ->supportedOptionalActions(); @@ -282,62 +112,69 @@ CharSelectDialog::CharSelectDialog(LoginData *const data): ContainerPlacer placer; placer = getPlacer(0, 0); - placer(0, 0, mAccountNameLabel, 2); - placer(2, 0, mLastLoginLabel); - placer(0, 1, mSwitchLoginButton); + placer(0, 0, mSwitchLoginButton); int n = 1; if (optionalActions & Net::LoginHandler::Unregister) { mUnregisterButton = new Button(this, _("Unregister"), "unregister", this); - placer(n, 1, mUnregisterButton); + placer(n, 0, mUnregisterButton); n ++; } - placer(n, 1, mChangePasswordButton); + placer(n, 0, mChangePasswordButton); n ++; if (optionalActions & Net::LoginHandler::ChangeEmail) { mChangeEmailButton = new Button(this, _("Change Email"), "change_email", this); - placer(n, 1, mChangeEmailButton); + placer(n, 0, mChangeEmailButton); n ++; } - placer = getPlacer(0, 1); + placer(n, 0, mDeleteButton); + n ++; + placer(n, 0, mInfoButton); + n ++; + + for (int i = 0; i < static_cast(mLoginData->characterSlots); i++) + { + CharacterDisplay *const character + = new CharacterDisplay(this, this); + character->setVisible(false); + mCharacterEntries.push_back(character); + } + + placer(0, 2, mPlayButton); + if (!mSmallScreen) { - for (int i = 0; i < static_cast(mLoginData->characterSlots); i++) - { - mCharacterEntries.push_back(new CharacterDisplay(this, this)); - placer(i % SLOTS_PER_ROW, static_cast(i) / SLOTS_PER_ROW, - mCharacterEntries[i]); - } + mCharacterView = new CharacterViewNormal( + this, &mCharacterEntries, mPadding); + placer(0, 1, mCharacterView, 10); + reflowLayout(410 + 2 * mPadding); } else { - for (int i = 0; i < static_cast(mLoginData->characterSlots); i++) - { - CharacterDisplay *const character - = new CharacterDisplay(this, this); - character->setVisible(false); - mCharacterEntries.push_back(character); - } - mCharacterView = new CharacterViewSmall(this, &mCharacterEntries); + setCaption(strprintf(_("Account %s"), mLoginData->username.c_str())); + mCharacterView = new CharacterViewSmall( + this, &mCharacterEntries, mPadding); mCharacterView->setWidth(mainGraphics->getWidth() - 2 * getPadding()); - placer(0, 0, mCharacterView); + placer(0, 1, mCharacterView, 10); + reflowLayout(); } - reflowLayout(); addKeyListener(this); center(); setVisible(true); + requestFocus(); Net::getCharServerHandler()->setCharSelectDialog(this); - focusCharacter(0); + mCharacterView->show(0); + updateState(); } CharSelectDialog::~CharSelectDialog() @@ -349,40 +186,31 @@ void CharSelectDialog::action(const gcn::ActionEvent &event) // Check if a button of a character was pressed const gcn::Widget *const sourceParent = event.getSource()->getParent(); int selected = -1; - if (mCharacterView) + for (unsigned int i = 0, sz = static_cast( + mCharacterEntries.size()); i < sz; ++i) { - selected = mCharacterView->getSelected(); - } - else - { - for (unsigned int i = 0, sz = static_cast( - mCharacterEntries.size()); i < sz; ++i) + if (mCharacterEntries[i] == sourceParent) { - if (mCharacterEntries[i] == sourceParent) - { - selected = i; - break; - } + selected = i; + mCharacterView->show(i); + updateState(); + break; } } + if (selected == -1) + selected = mCharacterView->getSelected(); const std::string &eventId = event.getId(); if (selected >= 0) { - if (eventId == "use" && mCharacterEntries[selected]->getCharacter()) + if (eventId == "select") { - attemptCharacterSelect(selected); -// Net::getCharServerHandler()->clear(); - return; + logger->log("select"); } - else if (eventId == "new" && - !mCharacterEntries[selected]->getCharacter()) + else if (eventId == "use") { - // Start new character dialog - CharCreateDialog *const charCreateDialog = - new CharCreateDialog(this, selected); - mCharServerHandler->setCharCreateDialog(charCreateDialog); + use(selected); return; } else if (eventId == "delete" @@ -391,6 +219,30 @@ void CharSelectDialog::action(const gcn::ActionEvent &event) new CharDeleteConfirm(this, selected); return; } + else if (eventId == "info") + { + Net::Character *const character = mCharacterEntries[ + selected]->getCharacter(); + if (!character) + return; + + const LocalPlayer *const data = character->dummy; + if (!data) + return; + + const std::string msg = strprintf( + _("Hp: %u/%u\nMp: %u/%u\nLevel: %u\n" + "Experience: %u\nMoney: %s"), + character->data.mAttributes[PlayerInfo::HP], + character->data.mAttributes[PlayerInfo::MAX_HP], + character->data.mAttributes[PlayerInfo::MP], + character->data.mAttributes[PlayerInfo::MAX_MP], + character->data.mAttributes[PlayerInfo::LEVEL], + character->data.mAttributes[PlayerInfo::EXP], + Units::formatCurrency( + character->data.mAttributes[PlayerInfo::MONEY]).c_str()); + new OkDialog(data->getName().c_str(), msg.c_str(), DIALOG_SILENCE); + } } if (eventId == "switch") { @@ -426,6 +278,20 @@ void CharSelectDialog::action(const gcn::ActionEvent &event) } } +void CharSelectDialog::use(const int selected) +{ + if (mCharacterEntries[selected]->getCharacter()) + { + attemptCharacterSelect(selected); + } + else + { + CharCreateDialog *const charCreateDialog = + new CharCreateDialog(this, selected); + mCharServerHandler->setCharCreateDialog(charCreateDialog); + } +} + void CharSelectDialog::keyPressed(gcn::KeyEvent &keyEvent) { const int actionId = static_cast(&keyEvent)->getActionId(); @@ -439,34 +305,30 @@ void CharSelectDialog::keyPressed(gcn::KeyEvent &keyEvent) case Input::KEY_GUI_RIGHT: { - if (mCharacterView) - return; keyEvent.consume(); - int idx; - int idx2; - if (getFocusedContainer(idx, idx2)) + int idx = mCharacterView->getSelected(); + if (idx >= 0) { idx ++; if (idx == SLOTS_PER_ROW) break; - setFocusedContainer(idx, idx2); + mCharacterView->show(idx); + updateState(); } break; } case Input::KEY_GUI_LEFT: { - if (mCharacterView) - return; keyEvent.consume(); - int idx; - int idx2; - if (getFocusedContainer(idx, idx2)) + int idx = mCharacterView->getSelected(); + if (idx >= 0) { if (!idx || idx == SLOTS_PER_ROW) break; idx --; - setFocusedContainer(idx, idx2); + mCharacterView->show(idx); + updateState(); } break; } @@ -474,25 +336,14 @@ void CharSelectDialog::keyPressed(gcn::KeyEvent &keyEvent) case Input::KEY_GUI_UP: { keyEvent.consume(); - int idx; - int idx2; - if (getFocusedContainer(idx, idx2)) + int idx = mCharacterView->getSelected(); + if (idx >= 0) { - if (idx < SLOTS_PER_ROW && !idx2) + if (idx < SLOTS_PER_ROW) break; - if (idx2 > 0) - { - idx2 = 0; - } - else if (!mCharacterView) - { - idx -= SLOTS_PER_ROW; - if (mCharacterEntries[idx]->getCharacter()) - idx2 = 1; - else - idx2 = 0; - } - setFocusedContainer(idx, idx2); + idx -= SLOTS_PER_ROW; + mCharacterView->show(idx); + updateState(); } break; } @@ -500,25 +351,14 @@ void CharSelectDialog::keyPressed(gcn::KeyEvent &keyEvent) case Input::KEY_GUI_DOWN: { keyEvent.consume(); - int idx; - int idx2; - if (getFocusedContainer(idx, idx2)) + int idx = mCharacterView->getSelected(); + if (idx >= 0) { - if (idx >= SLOTS_PER_ROW && idx2) + if (idx >= SLOTS_PER_ROW) break; - if (idx2 > 0) - { - idx += SLOTS_PER_ROW; - idx2 = 0; - } - else if (!mCharacterView) - { - if (mCharacterEntries[idx]->getCharacter()) - idx2 = 1; - else - idx += SLOTS_PER_ROW; - } - setFocusedContainer(idx, idx2); + idx += SLOTS_PER_ROW; + mCharacterView->show(idx); + updateState(); } break; } @@ -526,50 +366,20 @@ void CharSelectDialog::keyPressed(gcn::KeyEvent &keyEvent) case Input::KEY_GUI_DELETE: { keyEvent.consume(); - int idx; - int idx2; - if (getFocusedContainer(idx, idx2) - && mCharacterEntries[idx]->getCharacter()) - { + int idx = mCharacterView->getSelected(); + if (idx >= 0 && mCharacterEntries[idx]->getCharacter()) new CharDeleteConfirm(this, idx); - } break; } - default: - break; - } -} - -bool CharSelectDialog::getFocusedContainer(int &container, int &idx) -{ - for (int f = 0; f < static_cast(mLoginData->characterSlots); f ++) - { - if (mCharacterEntries[f]->isSelectFocused()) + case Input::KEY_GUI_SELECT: { - container = f; - idx = 0; - return true; - } - else if (mCharacterEntries[f]->isDeleteFocused()) - { - container = f; - idx = 1; - return true; + keyEvent.consume(); + use(mCharacterView->getSelected()); + break; } - } - return false; -} - -void CharSelectDialog::setFocusedContainer(const int i, const int button) -{ - if (i >= 0 && i < static_cast(mLoginData->characterSlots)) - { - CharacterDisplay *const container = mCharacterEntries[i]; - if (button) - container->focusDelete(); - else - container->focusSelect(); + default: + break; } } @@ -671,6 +481,10 @@ void CharSelectDialog::setLocked(const bool locked) mUnregisterButton->setEnabled(!locked); if (mChangeEmailButton) mChangeEmailButton->setEnabled(!locked); + if (mPlayButton) + mPlayButton->setEnabled(!locked); + if (mDeleteButton) + mDeleteButton->setEnabled(!locked); for (size_t i = 0, sz = mCharacterEntries.size(); i < sz; ++i) { @@ -695,7 +509,8 @@ bool CharSelectDialog::selectByName(const std::string &name, { if (character->dummy && character->dummy->getName() == name) { - focusCharacter(static_cast(i)); + mCharacterView->show(static_cast(i)); + updateState(); if (selAction == Choose) attemptCharacterSelect(static_cast(i)); return true; @@ -713,14 +528,6 @@ void CharSelectDialog::close() Window::close(); } -void CharSelectDialog::focusCharacter(const int i) -{ - if (mCharacterEntries[i]) - mCharacterEntries[i]->requestFocus(); - if (mCharacterView) - mCharacterView->show(i); -} - void CharSelectDialog::widgetResized(const gcn::Event &event) { Window::widgetResized(event); @@ -728,87 +535,18 @@ void CharSelectDialog::widgetResized(const gcn::Event &event) mCharacterView->resize(); } -CharacterDisplay::CharacterDisplay(const Widget2 *const widget, - CharSelectDialog *const charSelectDialog) : - Container(widget), - mCharacter(nullptr), - mPlayerBox(new PlayerBox(nullptr)), - mName(new Label(this, "wwwwwwwwwwwwwwwwwwwwwwww")), - mLevel(new Label(this, "(888)")), - mMoney(new Label(this, "wwwwwwwww")), - mButton(new Button(this, "wwwwwwwww", "go", charSelectDialog)), - mDelete(new Button(this, _("Delete"), "delete", charSelectDialog)) +void CharSelectDialog::updateState() { - mPlayerBox->setActionEventId("use"); - mPlayerBox->addActionListener(charSelectDialog); - - LayoutHelper h(this); - ContainerPlacer placer = h.getPlacer(0, 0); - - placer(0, 0, mPlayerBox, 3, 5); - placer(0, 5, mName, 3); - placer(0, 6, mLevel, 3); - placer(0, 7, mMoney, 3); - placer(0, 8, mButton, 3); - placer(0, 9, mDelete, 3); - - update(); - - // Setting the width so that the largest label fits. - mName->adjustSize(); - mMoney->adjustSize(); - - setWidth(110); - setHeight(200); -} - -void CharacterDisplay::setCharacter(Net::Character *const character) -{ - if (mCharacter == character) - return; - - mCharacter = character; - mPlayerBox->setPlayer(character ? character->dummy : nullptr); - update(); -} - -void CharacterDisplay::requestFocus() -{ - mButton->requestFocus(); -} - -void CharacterDisplay::setActive(const bool active) -{ - mButton->setEnabled(active); - mDelete->setEnabled(active); -} - -void CharacterDisplay::update() -{ - if (mCharacter) + const int idx = mCharacterView->getSelected(); + if (idx == -1) { - const LocalPlayer *const character = mCharacter->dummy; - mButton->setCaption(_("Choose")); - mButton->setActionEventId("use"); - mName->setCaption(strprintf("%s", character->getName().c_str())); - mLevel->setCaption(strprintf(_("Level %d"), - mCharacter->data.mAttributes[PlayerInfo::LEVEL])); - mMoney->setCaption(Units::formatCurrency( - mCharacter->data.mAttributes[PlayerInfo::MONEY])); - - mDelete->setVisible(true); - } - else - { - mButton->setCaption(_("Create")); - mButton->setActionEventId("new"); - mName->setCaption(_("(empty)")); - mLevel->setCaption(_("(empty)")); - mMoney->setCaption(Units::formatCurrency(0)); - - mDelete->setVisible(false); + mPlayButton->setEnabled(false); + return; } + mPlayButton->setEnabled(true); - // Recompute layout - distributeResizedEvent(); + if (mCharacterEntries[idx]->getCharacter()) + mPlayButton->setCaption(_("Play")); + else + mPlayButton->setCaption(_("Create")); } diff --git a/src/gui/charselectdialog.h b/src/gui/charselectdialog.h index b24b8e225..c6bf0578c 100644 --- a/src/gui/charselectdialog.h +++ b/src/gui/charselectdialog.h @@ -94,10 +94,10 @@ class CharSelectDialog final : public Window, void close() override; - void focusCharacter(int i); - void widgetResized(const gcn::Event &event) override; + void updateState(); + private: void attemptCharacterDelete(const int index); @@ -105,28 +105,25 @@ class CharSelectDialog final : public Window, void setCharacters(const Net::Characters &characters); + void use(const int selected); + void lock(); void unlock(); void setLocked(const bool locked); - bool getFocusedContainer(int &container, int &idx) A_WARN_UNUSED; - - void setFocusedContainer(const int i, const int button); - bool mLocked; LoginData *mLoginData; - Label *mAccountNameLabel; - Label *mLastLoginLabel; - Button *mSwitchLoginButton; Button *mChangePasswordButton; Button *mUnregisterButton; Button *mChangeEmailButton; + Button *mPlayButton; + Button *mInfoButton; + Button *mDeleteButton; CharacterViewBase *mCharacterView; - /** The player boxes */ std::vector mCharacterEntries; Net::CharServerHandler *mCharServerHandler; diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index a27d55c89..fe6ba0a3d 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -56,7 +56,8 @@ EquipmentWindow::EquipmentWindow(Equipment *const equipment, gcn::ActionListener(), mEquipment(equipment), mItemPopup(new ItemPopup), - mPlayerBox(new PlayerBox("equipment_playerbox.xml")), + mPlayerBox(new PlayerBox("equipment_playerbox.xml", + "equipment_selectedplayerbox.xml")), mUnequip(new Button(this, _("Unequip"), "unequip", this)), mSelected(-1), mForing(foring), diff --git a/src/gui/widgets/characterdisplay.cpp b/src/gui/widgets/characterdisplay.cpp new file mode 100644 index 000000000..35af15efc --- /dev/null +++ b/src/gui/widgets/characterdisplay.cpp @@ -0,0 +1,83 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gui/widgets/characterdisplay.h" + +#include "gui/charselectdialog.h" + +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" + +#include "debug.h" + +CharacterDisplay::CharacterDisplay(const Widget2 *const widget, + CharSelectDialog *const charSelectDialog) : + Container(widget), + mCharacter(nullptr), + mPlayerBox(new PlayerBox(nullptr)), + mName(new Label(this, "wwwwwwwwwwwwwwwwwwwwwwww")) +{ + mPlayerBox->setActionEventId("select"); + mPlayerBox->addActionListener(charSelectDialog); + + LayoutHelper h(this); + ContainerPlacer placer = h.getPlacer(0, 0); + + placer(0, 0, mPlayerBox, 3, 5); + placer(0, 5, mName, 3); + + update(); + + mName->setAlignment(Graphics::CENTER); + mName->adjustSize(); + + setWidth(80); + setHeight(100); +} + +void CharacterDisplay::setCharacter(Net::Character *const character) +{ + if (mCharacter == character) + return; + + mCharacter = character; + mPlayerBox->setPlayer(character ? character->dummy : nullptr); + update(); +} + +void CharacterDisplay::requestFocus() +{ +} + +void CharacterDisplay::setActive(const bool active A_UNUSED) +{ +} + +void CharacterDisplay::update() +{ + if (mCharacter) + mName->setCaption(mCharacter->dummy->getName()); + else + mName->setCaption(""); + + distributeResizedEvent(); +} diff --git a/src/gui/widgets/characterdisplay.h b/src/gui/widgets/characterdisplay.h new file mode 100644 index 000000000..5c602b4f9 --- /dev/null +++ b/src/gui/widgets/characterdisplay.h @@ -0,0 +1,79 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WIDGETS_CHARACTER_DISPLAY_H +#define WIDGETS_CHARACTER_DISPLAY_H + +#include "gui/widgets/container.h" +#include "gui/widgets/playerbox.h" + +#include "net/charserverhandler.h" +#include "net/net.h" + +class Button; +class CharSelectDialog; +class Label; +class PlayerBox; + +class CharacterDisplay final : public Container +{ + public: + CharacterDisplay(const Widget2 *const widget, + CharSelectDialog *const charSelectDialog); + + A_DELETE_COPY(CharacterDisplay) + + void setCharacter(Net::Character *const character); + + Net::Character *getCharacter() const + { return mCharacter; } + + void requestFocus(); + + void setActive(const bool active); + + bool isSelectFocused() const + { return false; } + + bool isDeleteFocused() const + { return false; } + + void focusSelect() + { } + + void focusDelete() + { } + + void setSelect(bool b) + { + mPlayerBox->setSelected(b); + } + + private: + void update(); + + Net::Character *mCharacter; + PlayerBox *mPlayerBox; + Label *mName; +}; + +#endif diff --git a/src/gui/widgets/characterviewbase.h b/src/gui/widgets/characterviewbase.h new file mode 100644 index 000000000..42e4025eb --- /dev/null +++ b/src/gui/widgets/characterviewbase.h @@ -0,0 +1,65 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WIDGETS_CHARACTERVIEWBASE_H +#define WIDGETS_CHARACTERVIEWBASE_H + +#include "gui/charselectdialog.h" + +#include "gui/widgets/container.h" + +#include + +#include "debug.h" + +class CharacterViewBase : public Container, + public gcn::ActionListener +{ + public: + CharacterViewBase(CharSelectDialog *const widget, const int padding) : + Container(widget), + gcn::ActionListener(), + mParent(widget), + mPadding(padding), + mSelected(0) + { + } + + A_DELETE_COPY(CharacterViewBase) + + virtual ~CharacterViewBase() + { } + + virtual void show(const int i) = 0; + + virtual void resize() = 0; + + int getSelected() const + { + return mSelected; + } + + protected: + CharSelectDialog *mParent; + int mPadding; + int mSelected; +}; + +#endif diff --git a/src/gui/widgets/characterviewnormal.cpp b/src/gui/widgets/characterviewnormal.cpp new file mode 100644 index 000000000..920fde61c --- /dev/null +++ b/src/gui/widgets/characterviewnormal.cpp @@ -0,0 +1,85 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gui/widgets/characterviewnormal.h" + +#include "gui/widgets/characterdisplay.h" +#include "gui/widgets/characterviewsmall.h" + +#include "debug.h" + +CharacterViewNormal::CharacterViewNormal(CharSelectDialog *const widget, + std::vector *const entries, + const int padding) : + CharacterViewBase(widget, padding), + mSelectedEntry(nullptr), + mCharacterEntries(entries) +{ + addKeyListener(widget); + if (entries) + { + FOR_EACHP (std::vector::iterator, + it, entries) + { + CharacterDisplay *character = *it; + add(character); + character->setVisible(true); + } + show(0); + } + const CharacterDisplay *const firtChar = (*mCharacterEntries)[0]; + setWidth(firtChar->getWidth() * 5 + mPadding * 2); + setHeight(200); +} + +CharacterViewNormal::~CharacterViewNormal() +{ + removeKeyListener(mParent); +} + +void CharacterViewNormal::show(const int i) +{ + const int sz = static_cast(mCharacterEntries->size()); + if (i >= 0 && i < sz) + { + if (mSelected >= 0) + (*mCharacterEntries)[mSelected]->setSelect(false); + mSelected = i; + (*mCharacterEntries)[i]->setSelect(true); + } +} + +void CharacterViewNormal::resize() +{ + const CharacterDisplay *const firtChar = (*mCharacterEntries)[0]; + int y = 0; + const int width = firtChar->getWidth(); + const int height = firtChar->getHeight(); + for (int f = 0; f < 5; f ++) + (*mCharacterEntries)[f]->setPosition(f * width, y); + y += height; + + for (int f = 5; f < 10; f ++) + (*mCharacterEntries)[f]->setPosition((f - 5) * width, y); +} + +void CharacterViewNormal::action(const gcn::ActionEvent &event A_UNUSED) +{ +} diff --git a/src/gui/widgets/characterviewnormal.h b/src/gui/widgets/characterviewnormal.h new file mode 100644 index 000000000..ab45bee8a --- /dev/null +++ b/src/gui/widgets/characterviewnormal.h @@ -0,0 +1,50 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WIDGETS_CHARACTERVIEWNORMAL_H +#define WIDGETS_CHARACTERVIEWNORMAL_H + +#include "gui/widgets/characterviewbase.h" + +#include "debug.h" + +class CharacterViewNormal final : public CharacterViewBase +{ + public: + CharacterViewNormal(CharSelectDialog *const widget, + std::vector *const entries, + const int padding); + + A_DELETE_COPY(CharacterViewNormal) + + ~CharacterViewNormal(); + + void show(const int i); + + void resize(); + + void action(const gcn::ActionEvent &event A_UNUSED) override; + + private: + CharacterDisplay *mSelectedEntry; + std::vector *mCharacterEntries; +}; + +#endif diff --git a/src/gui/widgets/characterviewsmall.cpp b/src/gui/widgets/characterviewsmall.cpp new file mode 100644 index 000000000..59cdd8150 --- /dev/null +++ b/src/gui/widgets/characterviewsmall.cpp @@ -0,0 +1,112 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gui/widgets/characterviewsmall.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/characterdisplay.h" +#include "gui/widgets/label.h" + +#include "debug.h" + +CharacterViewSmall::CharacterViewSmall(CharSelectDialog *const widget, + std::vector + *const entries, + const int padding) : + CharacterViewBase(widget, padding), + mSelectedEntry(nullptr), + mPrevious(new Button(this, "<", "prev", this)), + mNext(new Button(this, ">", "next", this)), + mNumber(new Label(this, "??")), + mCharacterEntries(entries) +{ + addKeyListener(widget); + if (entries) + { + FOR_EACHP (std::vector::iterator, + it, entries) + { + CharacterDisplay *character = *it; + add(character); + } + show(0); + } + add(mPrevious); + add(mNext); + add(mNumber); + + setHeight(200); +} + +CharacterViewSmall::~CharacterViewSmall() +{ + removeKeyListener(mParent); +} + +void CharacterViewSmall::show(const int i) +{ + const int sz = static_cast(mCharacterEntries->size()); + if (mSelectedEntry) + mSelectedEntry->setVisible(false); + if (i >= sz) + mSelected = 0; + else if (i < 0) + mSelected = mCharacterEntries->size() - 1; + else + mSelected = i; + mSelectedEntry = (*mCharacterEntries)[mSelected]; + mSelectedEntry->setVisible(true); + mNumber->setCaption(strprintf("%d / %d", mSelected + 1, sz)); + mNumber->adjustSize(); +} + +void CharacterViewSmall::resize() +{ + const CharacterDisplay *const firtChar = (*mCharacterEntries)[0]; + const int x = (getWidth() - firtChar->getWidth()) / 2; + const int y = (getHeight() - firtChar->getHeight()) / 2; + FOR_EACHP (std::vector::iterator, + it, mCharacterEntries) + { + (*it)->setPosition(x, y); + } + const int y2 = (getHeight() - mPrevious->getHeight()) / 2; + const int y3 = y2 - 55; + mPrevious->setPosition(x - mPrevious->getWidth() - 10, y3); + mNext->setPosition(getWidth() - x + 10, y3); + mNumber->setPosition(10, y2); +} + +void CharacterViewSmall::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + if (eventId == "next") + { + mSelected ++; + show(mSelected); + mParent->updateState(); + } + else if (eventId == "prev") + { + mSelected --; + show(mSelected); + mParent->updateState(); + } +} diff --git a/src/gui/widgets/characterviewsmall.h b/src/gui/widgets/characterviewsmall.h new file mode 100644 index 000000000..f42500b79 --- /dev/null +++ b/src/gui/widgets/characterviewsmall.h @@ -0,0 +1,54 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WIDGETS_CHARACTERVIEWSMALL_H +#define WIDGETS_CHARACTERVIEWSMALL_H + +#include "gui/widgets/characterviewbase.h" + +#include "debug.h" + +class CharacterViewBase; + +class CharacterViewSmall final : public CharacterViewBase +{ + public: + CharacterViewSmall(CharSelectDialog *const widget, + std::vector *const entries, + const int padding); + A_DELETE_COPY(CharacterViewSmall) + + ~CharacterViewSmall(); + + void show(const int i); + + void resize(); + + void action(const gcn::ActionEvent &event) override; + + private: + CharacterDisplay *mSelectedEntry; + Button *mPrevious; + Button *mNext; + Label *mNumber; + std::vector *mCharacterEntries; +}; + +#endif diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp index 98c0adc42..38e7f1f57 100644 --- a/src/gui/widgets/playerbox.cpp +++ b/src/gui/widgets/playerbox.cpp @@ -33,31 +33,39 @@ #include "debug.h" -PlayerBox::PlayerBox(Being *const being, const std::string &skin) : +PlayerBox::PlayerBox(Being *const being, const std::string &skin, + const std::string &selectedSkin) : Widget2(), ScrollArea(), mBeing(being), mAlpha(1.0), mBackground(), + mSelectedBackground(), mSkin(nullptr), - mDrawBackground(false), + mSelectedSkin(nullptr), mOffsetX(-16), - mOffsetY(-32) + mOffsetY(-32), + mDrawBackground(false), + mSelected(false) { - init(skin); + init(skin, selectedSkin); } -PlayerBox::PlayerBox(std::string skin) : +PlayerBox::PlayerBox(const std::string &skin, + const std::string &selectedSkin) : ScrollArea(), mBeing(nullptr), mAlpha(1.0), mBackground(), + mSelectedBackground(), mSkin(nullptr), - mDrawBackground(false), + mSelectedSkin(nullptr), mOffsetX(-16), - mOffsetY(-32) + mOffsetY(-32), + mDrawBackground(false), + mSelected(false) { - init(skin); + init(skin, selectedSkin); } PlayerBox::~PlayerBox() @@ -68,23 +76,23 @@ PlayerBox::~PlayerBox() Theme *const theme = Theme::instance(); if (theme) { - theme->unload(mSkin); theme->unloadRect(mBackground); + theme->unloadRect(mSelectedBackground); } mBeing = nullptr; } -void PlayerBox::init(std::string skin) +void PlayerBox::init(std::string name, std::string selectedName) { setFrameSize(2); if (Theme::instance()) { - if (skin.empty()) - skin = "playerbox.xml"; + if (name.empty()) + name = "playerbox.xml"; mSkin = Theme::instance()->loadSkinRect(mBackground, - skin, "playerbox_background.xml"); + name, "playerbox_background.xml"); if (mSkin) { mDrawBackground = (mSkin->getOption("drawbackground") != 0); @@ -92,11 +100,17 @@ void PlayerBox::init(std::string skin) mOffsetY = mSkin->getOption("offsetY", -32); mFrameSize = mSkin->getOption("frameSize", 2); } + if (selectedName.empty()) + selectedName = "playerboxselected.xml"; + mSelectedSkin = Theme::instance()->loadSkinRect(mSelectedBackground, + selectedName, "playerbox_background.xml"); } else { for (int f = 0; f < 9; f ++) mBackground.grid[f] = nullptr; + for (int f = 0; f < 9; f ++) + mSelectedBackground.grid[f] = nullptr; } } @@ -133,8 +147,16 @@ void PlayerBox::drawFrame(gcn::Graphics *graphics) w = getWidth() + bs * 2; h = getHeight() + bs * 2; - static_cast(graphics)->drawImageRect( - 0, 0, w, h, mBackground); + if (!mSelected) + { + static_cast(graphics)->drawImageRect( + 0, 0, w, h, mBackground); + } + else + { + static_cast(graphics)->drawImageRect( + 0, 0, w, h, mSelectedBackground); + } } BLOCK_END("PlayerBox::drawFrame") } diff --git a/src/gui/widgets/playerbox.h b/src/gui/widgets/playerbox.h index 61ad7dae4..f2b0a0616 100644 --- a/src/gui/widgets/playerbox.h +++ b/src/gui/widgets/playerbox.h @@ -46,9 +46,11 @@ class PlayerBox final : public Widget2, * Constructor. Takes the initial player character that this box should * display, which defaults to NULL. */ - PlayerBox(Being *const being, const std::string &skin = ""); + PlayerBox(Being *const being, const std::string &skin = "", + const std::string &selectedSkin = ""); - explicit PlayerBox(std::string skin = ""); + PlayerBox(const std::string &skin = "", + const std::string &selectedSkin = ""); A_DELETE_COPY(PlayerBox) @@ -57,7 +59,7 @@ class PlayerBox final : public Widget2, */ ~PlayerBox(); - void init(std::string skin); + void init(std::string name, std::string selectedName); /** * Sets a new player character to be displayed by this box. Setting the @@ -80,6 +82,9 @@ class PlayerBox final : public Widget2, Being *getBeing() A_WARN_UNUSED { return mBeing; } + void setSelected(bool b) + { mSelected = b; } + void mouseReleased(gcn::MouseEvent& event); private: @@ -87,10 +92,13 @@ class PlayerBox final : public Widget2, float mAlpha; ImageRect mBackground; + ImageRect mSelectedBackground; Skin *mSkin; - bool mDrawBackground; + Skin *mSelectedSkin; int mOffsetX; int mOffsetY; + bool mDrawBackground; + bool mSelected; }; #endif -- cgit v1.2.3-70-g09d2