diff options
author | Andrei Karas <akaras@inbox.ru> | 2012-02-05 15:00:58 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2012-02-05 15:00:58 +0300 |
commit | 9a3a196dbf633a699c26d0227802a42f025c8bfd (patch) | |
tree | dfbdb2ff1e2c54d75a2bf6411d3f70df22518c28 /src/gui | |
parent | fc17ff22d9df50df9c5d1cf3dc0de358001271ed (diff) | |
parent | ece36a40d4e9a838cde01075d7681b8fc517b19f (diff) | |
download | mv-9a3a196dbf633a699c26d0227802a42f025c8bfd.tar.gz mv-9a3a196dbf633a699c26d0227802a42f025c8bfd.tar.bz2 mv-9a3a196dbf633a699c26d0227802a42f025c8bfd.tar.xz mv-9a3a196dbf633a699c26d0227802a42f025c8bfd.zip |
Merge branch 'master' into stripped
Conflicts:
src/guichan/gui.cpp
src/guichan/include/guichan/sdl/sdlpixel.hpp
Diffstat (limited to 'src/gui')
69 files changed, 1266 insertions, 944 deletions
diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index a1233fdcc..8d4767a15 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -47,6 +47,7 @@ #include "resources/chardb.h" #include "resources/colordb.h" #include "resources/itemdb.h" +#include "resources/iteminfo.h" #include "utils/gettext.h" #include "utils/stringutils.h" @@ -55,14 +56,27 @@ #include "debug.h" +const static Being::Action actions[] = +{ + Being::STAND, Being::SIT, Being::MOVE, Being::ATTACK, Being::DEAD +}; + +const static int directions[] = +{ + Being::DOWN, Being::RIGHT, Being::UP, Being::LEFT +}; + CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot): - Window(_("Create Character"), true, parent, "charcreate.xml"), + Window(_("New Character"), true, parent, "charcreate.xml"), mCharSelectDialog(parent), mRace(0), - mSlot(slot) + mSlot(slot), + mAction(0), + mDirection(0) { setStickyButtonLock(true); setSticky(true); + setWindowName("NewCharacter"); mPlayer = new Being(0, ActorSprite::PLAYER, mRace, nullptr); mPlayer->setGender(GENDER_MALE); @@ -79,9 +93,9 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot): mHairStyle = (rand() % maxHairStyle) + minHairStyle; mHairColor = (rand() % maxHairColor) + minHairColor; - updateHair(); mNameField = new TextField(""); + mNameField->setMaximum(24); mNameLabel = new Label(_("Name:")); // TRANSLATORS: This is a narrow symbol used to denote 'next'. // You may change this symbol if your language uses another. @@ -90,15 +104,20 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot): // You may change this symbol if your language uses another. mPrevHairColorButton = new Button(_("<"), "prevcolor", this); mHairColorLabel = new Label(_("Hair color:")); + mHairColorNameLabel = new Label(""); mNextHairStyleButton = new Button(_(">"), "nextstyle", this); mPrevHairStyleButton = new Button(_("<"), "prevstyle", this); mHairStyleLabel = new Label(_("Hair style:")); + mHairStyleNameLabel = new Label(""); + mActionButton = new Button(_("^"), "action", this); + mRotateButton = new Button(_(">"), "rotate", this); if (serverVersion >= 2) { mNextRaceButton = new Button(_(">"), "nextrace", this); mPrevRaceButton = new Button(_("<"), "prevrace", this); mRaceLabel = new Label(_("Race:")); + mRaceNameLabel = new Label(""); } mCreateButton = new Button(_("Create"), "create", this); @@ -124,31 +143,42 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot): mAttributesLeft = new Label( strprintf(_("Please distribute %d points"), 99)); - int w = 280; - int h = 330; + int w = 480; + int h = 350; setContentSize(w, h); - mPlayerBox->setDimension(gcn::Rectangle(145, 35, 110, 87)); - mNameLabel->setPosition(5, 5); + mPlayerBox->setDimension(gcn::Rectangle(350, 40, 110, 90)); + mActionButton->setPosition(375, 140); + mRotateButton->setPosition(405, 140); + + mNameLabel->setPosition(5, 10); mNameField->setDimension( - gcn::Rectangle(60, 5, w - 60 - 7, mNameField->getHeight())); - mPrevHairColorButton->setPosition(155, 35); - mNextHairColorButton->setPosition(230, 35); - mHairColorLabel->setPosition(5, 40); - mPrevHairStyleButton->setPosition(155, 64); - mNextHairStyleButton->setPosition(230, 64); - mHairStyleLabel->setPosition(5, 70); + gcn::Rectangle(60, 10, 300, mNameField->getHeight())); + + int leftX = 120; + int rightX = 300; + int labelX = 5; + int nameX = 145; + mPrevHairColorButton->setPosition(leftX, 40); + mNextHairColorButton->setPosition(rightX, 40); + mHairColorLabel->setPosition(labelX, 45); + mHairColorNameLabel->setPosition(nameX, 45); + mPrevHairStyleButton->setPosition(leftX, 69); + mNextHairStyleButton->setPosition(rightX, 69); + mHairStyleLabel->setPosition(labelX, 74); + mHairStyleNameLabel->setPosition(nameX, 74); if (serverVersion >= 2) { - mPrevRaceButton->setPosition(155, 93); - mNextRaceButton->setPosition(230, 93); - mRaceLabel->setPosition(5, 100); + mPrevRaceButton->setPosition(leftX, 103); + mNextRaceButton->setPosition(rightX, 103); + mRaceLabel->setPosition(labelX, 108); + mRaceNameLabel->setPosition(nameX, 108); } mAttributesLeft->setPosition(15, 280); updateSliders(); mCancelButton->setPosition( - w - 5 - mCancelButton->getWidth(), + w / 2, h - 5 - mCancelButton->getHeight()); mCreateButton->setPosition( mCancelButton->getX() - 5 - mCreateButton->getWidth(), @@ -163,15 +193,20 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot): add(mNextHairColorButton); add(mPrevHairColorButton); add(mHairColorLabel); + add(mHairColorNameLabel); add(mNextHairStyleButton); add(mPrevHairStyleButton); add(mHairStyleLabel); + add(mHairStyleNameLabel); + add(mActionButton); + add(mRotateButton); if (serverVersion >= 2) { add(mNextRaceButton); add(mPrevRaceButton); add(mRaceLabel); + add(mRaceNameLabel); } add(mAttributesLeft); @@ -184,6 +219,12 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot): center(); setVisible(true); mNameField->requestFocus(); + + updateHair(); + if (serverVersion >= 2) + updateRace(); + + updatePlayer(); } CharCreateDialog::~CharCreateDialog() @@ -197,7 +238,8 @@ CharCreateDialog::~CharCreateDialog() void CharCreateDialog::action(const gcn::ActionEvent &event) { - if (event.getId() == "create") + const std::string id = event.getId(); + if (id == "create") { if ( #ifdef MANASERV_SUPPORT @@ -232,51 +274,65 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) true, this); } } - else if (event.getId() == "cancel") + else if (id == "cancel") { scheduleDelete(); } - else if (event.getId() == "nextcolor") + else if (id == "nextcolor") { - mHairColor++; + mHairColor ++; updateHair(); } - else if (event.getId() == "prevcolor") + else if (id == "prevcolor") { - mHairColor--; + mHairColor --; updateHair(); } - else if (event.getId() == "nextstyle") + else if (id == "nextstyle") { - mHairStyle++; + mHairStyle ++; updateHair(); } - else if (event.getId() == "prevstyle") + else if (id == "prevstyle") { - mHairStyle--; + mHairStyle --; updateHair(); } - else if (event.getId() == "nextrace") + else if (id == "nextrace") { - mRace++; + mRace ++; updateRace(); } - else if (event.getId() == "prevrace") + else if (id == "prevrace") { - mRace--; + mRace --; updateRace(); } - else if (event.getId() == "statslider") + else if (id == "statslider") { updateSliders(); } - else if (event.getId() == "gender") + else if (id == "gender") { if (mMale->isSelected()) mPlayer->setGender(GENDER_MALE); else mPlayer->setGender(GENDER_FEMALE); } + else if (id == "action") + { + mAction ++; + if (mAction >= 5) + mAction = 0; + updatePlayer(); + } + else if (id == "rotate") + { + mDirection ++; + if (mDirection >= 4) + mDirection = 0; + updatePlayer(); + } } std::string CharCreateDialog::getName() const @@ -357,34 +413,34 @@ void CharCreateDialog::setAttributes(const std::vector<std::string> &labels, mAttributeSlider.resize(labels.size()); mAttributeValue.resize(labels.size()); - int w = 200; - int h = 330; + int w = 480; + int h = 350; for (unsigned i = 0; i < labels.size(); i++) { mAttributeLabel[i] = new Label(labels[i]); mAttributeLabel[i]->setWidth(70); - mAttributeLabel[i]->setPosition(5, 140 + i*20); + mAttributeLabel[i]->setPosition(5, 145 + i * 24); mAttributeLabel[i]->adjustSize(); add(mAttributeLabel[i]); mAttributeSlider[i] = new Slider(min, max); - mAttributeSlider[i]->setDimension(gcn::Rectangle(140, 140 + i * 20, - 100, 10)); + mAttributeSlider[i]->setDimension(gcn::Rectangle(140, 145 + i * 24, + 150, 12)); mAttributeSlider[i]->setActionEventId("statslider"); mAttributeSlider[i]->addActionListener(this); add(mAttributeSlider[i]); mAttributeValue[i] = new Label(toString(min)); - mAttributeValue[i]->setPosition(245, 140 + i*20); + mAttributeValue[i]->setPosition(295, 145 + i * 24); add(mAttributeValue[i]); } - mAttributesLeft->setPosition(15, 280); + mAttributesLeft->setPosition(15, 300); updateSliders(); mCancelButton->setPosition( - w - 5 - mCancelButton->getWidth(), + w / 2, h - 5 - mCancelButton->getHeight()); mCreateButton->setPosition( mCancelButton->getX() - 5 - mCreateButton->getWidth(), @@ -420,12 +476,17 @@ void CharCreateDialog::updateHair() mHairStyle += Being::getNumOfHairstyles(); if (mHairStyle < (signed)minHairStyle || mHairStyle > (signed)maxHairStyle) mHairStyle = minHairStyle; + const ItemInfo &item = ItemDB::get(-mHairStyle); + mHairStyleNameLabel->setCaption(item.getName()); + mHairStyleNameLabel->adjustSize(); mHairColor %= ColorDB::getHairSize(); if (mHairColor < 0) mHairColor += ColorDB::getHairSize(); if (mHairColor < (signed)minHairColor || mHairColor > (signed)maxHairColor) mHairColor = minHairColor; + mHairColorNameLabel->setCaption(ColorDB::getHairColorName(mHairColor)); + mHairColorNameLabel->adjustSize(); mPlayer->setSprite(Net::getCharHandler()->hairSprite(), mHairStyle * -1, ColorDB::getHairColor(mHairColor)); @@ -448,4 +509,22 @@ void CharCreateDialog::updateRace() } mPlayer->setSubtype(mRace); + const ItemInfo &item = ItemDB::get(id); + mRaceNameLabel->setCaption(item.getName()); + mRaceNameLabel->adjustSize(); +} + +void CharCreateDialog::logic() +{ + if (mPlayer) + mPlayer->logic(); +} + +void CharCreateDialog::updatePlayer() +{ + if (mPlayer) + { + mPlayer->setDirection(directions[mDirection]); + mPlayer->setAction(actions[mAction]); + } } diff --git a/src/gui/charcreatedialog.h b/src/gui/charcreatedialog.h index e369f1777..ceafcc08e 100644 --- a/src/gui/charcreatedialog.h +++ b/src/gui/charcreatedialog.h @@ -37,6 +37,7 @@ class LocalPlayer; class PlayerBox; +class TextField; /** * Character creation dialog. @@ -69,6 +70,10 @@ class CharCreateDialog : public Window, public gcn::ActionListener void setFixedGender(bool fixed, Gender gender = GENDER_FEMALE); + void logic(); + + void updatePlayer(); + private: int getDistributedPoints() const; @@ -90,17 +95,23 @@ class CharCreateDialog : public Window, public gcn::ActionListener CharSelectDialog *mCharSelectDialog; - gcn::TextField *mNameField; + TextField *mNameField; gcn::Label *mNameLabel; gcn::Button *mNextHairColorButton; gcn::Button *mPrevHairColorButton; gcn::Label *mHairColorLabel; + gcn::Label *mHairColorNameLabel; gcn::Button *mNextHairStyleButton; gcn::Button *mPrevHairStyleButton; gcn::Label *mHairStyleLabel; + gcn::Label *mHairStyleNameLabel; gcn::Button *mNextRaceButton; gcn::Button *mPrevRaceButton; gcn::Label *mRaceLabel; + gcn::Label *mRaceNameLabel; + + gcn::Button *mActionButton; + gcn::Button *mRotateButton; gcn::RadioButton *mMale; gcn::RadioButton *mFemale; @@ -129,6 +140,9 @@ class CharCreateDialog : public Window, public gcn::ActionListener unsigned minHairColor; unsigned maxHairStyle; unsigned minHairStyle; + + unsigned mAction; + unsigned mDirection; }; #endif // CHAR_CREATE_DIALOG_H diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp index 638691bab..d2b74a632 100644 --- a/src/gui/charselectdialog.cpp +++ b/src/gui/charselectdialog.cpp @@ -386,7 +386,7 @@ bool CharSelectDialog::selectByName(const std::string &name, Net::Character *character = mCharacterEntries[i]->getCharacter(); if (mCharacterEntries[i] && character) { - if (character->dummy->getName() == name) + if ( character->dummy && character->dummy->getName() == name) { if (mCharacterEntries[i]) mCharacterEntries[i]->requestFocus(); diff --git a/src/gui/chatwindow.cpp b/src/gui/chatwindow.cpp index 899bbdc36..6831ad5b6 100644 --- a/src/gui/chatwindow.cpp +++ b/src/gui/chatwindow.cpp @@ -548,6 +548,9 @@ void ChatWindow::removeTab(ChatTab *tab) void ChatWindow::addTab(ChatTab *tab) { + if (!tab) + return; + mChatTabs->addTab(tab, tab->mScrollArea); // Update UI @@ -764,18 +767,18 @@ void ChatWindow::keyPressed(gcn::KeyEvent &event) mCurHist = mHistory.end(); mChatInput->setText(""); } - else if (keyboard.isKeyActive(keyboard.KEY_AUTOCOMPLETE_CHAT) && + else if (keyboard.isActionActive(keyboard.KEY_AUTOCOMPLETE_CHAT) && mChatInput->getText() != "") { autoComplete(); return; } - else if (keyboard.isKeyActive(keyboard.KEY_DEACTIVATE_CHAT) && + else if (keyboard.isActionActive(keyboard.KEY_DEACTIVATE_CHAT) && mChatInput->isVisible()) { mChatInput->processVisible(false); } - else if (keyboard.isKeyActive(keyboard.KEY_CHAT_PREV_HISTORY) && + else if (keyboard.isActionActive(keyboard.KEY_CHAT_PREV_HISTORY) && mChatInput->isVisible()) { ChatTab *tab = getFocused(); @@ -807,7 +810,7 @@ void ChatWindow::keyPressed(gcn::KeyEvent &event) mChatInput->getText().length())); } } - else if (keyboard.isKeyActive(keyboard.KEY_CHAT_NEXT_HISTORY) && + else if (keyboard.isActionActive(keyboard.KEY_CHAT_NEXT_HISTORY) && mChatInput->isVisible()) { ChatTab *tab = getFocused(); diff --git a/src/gui/editdialog.h b/src/gui/editdialog.h index 69f86edca..ef260acfb 100644 --- a/src/gui/editdialog.h +++ b/src/gui/editdialog.h @@ -57,7 +57,7 @@ class EditDialog : public Window, public gcn::ActionListener */ void action(const gcn::ActionEvent &event); - std::string getMsg() + std::string getMsg() const { return mTextField->getText(); } private: diff --git a/src/gui/editserverdialog.cpp b/src/gui/editserverdialog.cpp new file mode 100644 index 000000000..8a4a9579d --- /dev/null +++ b/src/gui/editserverdialog.cpp @@ -0,0 +1,239 @@ +/* + * The Mana Client + * Copyright (C) 2011-2012 The Mana Developers + * Copyright (C) 2012 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 <http://www.gnu.org/licenses/>. + */ + +#include "gui/editserverdialog.h" + +#include "configuration.h" + +#include "gui/okdialog.h" +#include "gui/sdlinput.h" +#include "gui/serverdialog.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/dropdown.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layout.h" +#include "gui/widgets/textfield.h" + +#include "utils/gettext.h" + +std::string TypeListModel::getElementAt(int elementIndex) +{ + if (elementIndex == 0) + return "TmwAthena"; + else if (elementIndex == 1) + return "Evol"; +#ifdef MANASERV_SUPPORT + else if (elementIndex == 2) + return "ManaServ"; +#endif + else + return "Unknown"; +} + +EditServerDialog::EditServerDialog(ServerDialog *parent, ServerInfo server, + int index) : + Window(_("Edit Server"), true, parent), + mServerDialog(parent), + mServer(server), + mIndex(index) +{ + setWindowName("EditServerDialog"); + + Label *nameLabel = new Label(_("Name:")); + Label *serverAdressLabel = new Label(_("Address:")); + Label *portLabel = new Label(_("Port:")); + Label *typeLabel = new Label(_("Server type:")); + Label *descriptionLabel = new Label(_("Description:")); + mServerAddressField = new TextField(std::string()); + mPortField = new TextField(std::string()); + mPortField->setNumeric(true); + mPortField->setRange(1, 65535); + + mTypeListModel = new TypeListModel(); + mTypeField = new DropDown(mTypeListModel); + mTypeField->setSelected(0); // TmwAthena by default for now. + + mNameField = new TextField(std::string()); + mDescriptionField = new TextField(std::string()); + + mOkButton = new Button(_("OK"), "addServer", this); + mCancelButton = new Button(_("Cancel"), "cancel", this); + + mServerAddressField->addActionListener(this); + mPortField->addActionListener(this); + + place(0, 0, nameLabel); + place(1, 0, mNameField, 4).setPadding(3); + place(0, 1, serverAdressLabel); + place(1, 1, mServerAddressField, 4).setPadding(3); + place(0, 2, portLabel); + place(1, 2, mPortField, 4).setPadding(3); + place(0, 3, typeLabel); + place(1, 3, mTypeField).setPadding(3); + place(0, 4, descriptionLabel); + place(1, 4, mDescriptionField, 4).setPadding(3); + place(4, 5, mOkButton); + place(3, 5, mCancelButton); + + // Do this manually instead of calling reflowLayout so we can enforce a + // minimum width. + int width = 0, height = 0; + getLayout().reflow(width, height); + if (width < 300) + { + width = 300; + getLayout().reflow(width, height); + } + if (height < 120) + { + height = 120; + getLayout().reflow(width, height); + } + + setContentSize(width, height); + + setMinWidth(getWidth()); + setMinHeight(getHeight()); + setDefaultSize(getWidth(), getHeight(), ImageRect::CENTER); + + setResizable(false); + addKeyListener(this); + + loadWindowState(); + + mNameField->setText(mServer.name); + mDescriptionField->setText(mServer.description); + mServerAddressField->setText(mServer.hostname); + mPortField->setText(toString(mServer.port)); + + switch (mServer.type) + { + case ServerInfo::MANASERV: +#ifdef MANASERV_SUPPORT + mTypeField->setSelected(2); + break; +#endif + default: + case ServerInfo::UNKNOWN: + case ServerInfo::TMWATHENA: + mTypeField->setSelected(0); + break; + case ServerInfo::EVOL: + mTypeField->setSelected(1); + break; + } + + setLocationRelativeTo(getParentWindow()); + setVisible(true); + + mNameField->requestFocus(); +} + +EditServerDialog::~EditServerDialog() +{ + delete mTypeListModel; +} + +void EditServerDialog::logic() +{ + Window::logic(); +} + +void EditServerDialog::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "ok") + { + // Give focus back to the server dialog. + mServerAddressField->requestFocus(); + } + if (event.getId() == "addServer") + { + // Check the given information + if (mServerAddressField->getText().empty() + || mPortField->getText().empty()) + { + OkDialog *dlg = new OkDialog(_("Error"), + _("Please at least type both the address and the port " + "of the server.")); + dlg->addActionListener(this); + } + else + { + mCancelButton->setEnabled(false); + mOkButton->setEnabled(false); + + mServer.name = mNameField->getText(); + mServer.description = mDescriptionField->getText(); + mServer.hostname = mServerAddressField->getText(); + mServer.port = (short) atoi(mPortField->getText().c_str()); + + if (mTypeField) + { + switch (mTypeField->getSelected()) + { + case 0: + mServer.type = ServerInfo::TMWATHENA; + break; + case 1: + mServer.type = ServerInfo::EVOL; + break; +#ifdef MANASERV_SUPPORT + case 2: + mServer.type = ServerInfo::MANASERV; + break; +#endif + default: + mServer.type = ServerInfo::UNKNOWN; + } + } + else + { + mServer.type = ServerInfo::TMWATHENA; + } + + // Tell the server has to be saved + mServer.save = true; + + //Add server + mServerDialog->updateServer(mServer, mIndex); + scheduleDelete(); + } + } + else if (event.getId() == "cancel") + { + scheduleDelete(); + } +} + +void EditServerDialog::keyPressed(gcn::KeyEvent &keyEvent) +{ + gcn::Key key = keyEvent.getKey(); + + if (key.getValue() == Key::ESCAPE) + { + scheduleDelete(); + } + else if (key.getValue() == Key::ENTER) + { + action(gcn::ActionEvent(nullptr, mOkButton->getActionEventId())); + } +} diff --git a/src/gui/editserverdialog.h b/src/gui/editserverdialog.h new file mode 100644 index 000000000..6035b0e50 --- /dev/null +++ b/src/gui/editserverdialog.h @@ -0,0 +1,104 @@ +/* + * The Mana Client + * Copyright (C) 2011-2012 The Mana Developers + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The Mana 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef EDITSERVERDIALOG_H +#define EDITSERVERDIALOG_H + +class Button; +class Label; +class TextField; +class DropDown; +class ServerDialog; +class TypeListModel; + +#include "gui/widgets/window.h" + +#include "net/serverinfo.h" + +#include <guichan/actionlistener.hpp> +#include <guichan/keylistener.hpp> +#include <guichan/listmodel.hpp> + + +/** + * Server Type List Model + */ +class TypeListModel : public gcn::ListModel +{ + public: + TypeListModel() {} + + /** + * Used to get number of line in the list + */ + int getNumberOfElements() +#ifdef MANASERV_SUPPORT + { return 3; } +#else + { return 2; } +#endif + + /** + * Used to get an element from the list + */ + std::string getElementAt(int elementIndex); +}; + +/** + * The custom server addition dialog. + * + * \ingroup Interface + */ +class EditServerDialog : public Window, + public gcn::ActionListener, + public gcn::KeyListener +{ + public: + EditServerDialog(ServerDialog *parent, ServerInfo server, int index); + + ~EditServerDialog(); + + /** + * Called when receiving actions from the widgets. + */ + void action(const gcn::ActionEvent &event); + + void keyPressed(gcn::KeyEvent &keyEvent); + + void logic(); + + private: + TextField *mServerAddressField; + TextField *mPortField; + TextField *mNameField; + TextField *mDescriptionField; + Button *mOkButton; + Button *mCancelButton; + + DropDown *mTypeField; + TypeListModel *mTypeListModel; + + ServerDialog *mServerDialog; + ServerInfo mServer; + int mIndex; +}; + +#endif // EDITSERVERDIALOG_H diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h index daeaeb3d7..1e7b84533 100644 --- a/src/gui/equipmentwindow.h +++ b/src/gui/equipmentwindow.h @@ -84,7 +84,7 @@ class EquipmentWindow : public Window, public gcn::ActionListener void mousePressed(gcn::MouseEvent& mouseEvent); - Item* getEquipment(int i) + Item* getEquipment(int i) const { return mEquipment ? mEquipment->getEquipment(i) : nullptr; } void setBeing(Being *being); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index bd855a598..1d8b45872 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -99,20 +99,19 @@ Gui::Gui(Graphics *graphics): // Initialize top GUI widget WindowContainer *guiTop = new WindowContainer; guiTop->setFocusable(true); - guiTop->setDimension(gcn::Rectangle(0, 0, - graphics->mWidth, graphics->mHeight)); + guiTop->setSize(graphics->mWidth, graphics->mHeight); guiTop->setOpaque(false); Window::setWindowContainer(guiTop); setTop(guiTop); + const std::vector<std::string> langs = getLang(); + const bool isJapan = (!langs.empty() && langs[0].size() > 3 + && langs[0].substr(0, 3) == "ja_"); + // Set global font const int fontSize = config.getIntValue("fontSize"); - std::string fontFile = config.getValue("font", ""); - - std::vector<std::string> langs = getLang(); - if (!langs.empty() && langs[0].size() > 3 - && langs[0].substr(0, 3) == "ja_") + if (isJapan) { fontFile = config.getValue("japanFont", ""); if (fontFile.empty()) @@ -134,6 +133,15 @@ Gui::Gui(Graphics *graphics): // Set particle font fontFile = config.getValue("particleFont", ""); + + if (isJapan) + { + fontFile = config.getValue("japanFont", ""); + if (fontFile.empty()) + fontFile = branding.getStringValue("japanFont"); + } + + if (fontFile.empty()) fontFile = branding.getStringValue("particleFont"); @@ -278,6 +286,20 @@ void Gui::draw() mGraphics->popClipArea(); } +void Gui::videoResized() +{ + WindowContainer *top = static_cast<WindowContainer*>(getTop()); + + if (top) + { + int oldWidth = top->getWidth(); + int oldHeight = top->getHeight(); + + top->setSize(mainGraphics->mWidth, mainGraphics->mHeight); + top->adjustAfterResize(oldWidth, oldHeight); + } +} + void Gui::setUseCustomCursor(bool customCursor) { if (customCursor != mCustomCursor) diff --git a/src/gui/gui.h b/src/gui/gui.h index cadcc89ac..5ace42323 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -70,6 +70,11 @@ class Gui : public gcn::Gui */ void draw(); + /** + * Called when the application window has been resized. + */ + void videoResized(); + gcn::FocusHandler *getFocusHandler() const { return mFocusHandler; } diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 01e2bdd17..23f1e6fcf 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -340,13 +340,13 @@ void InventoryWindow::action(const gcn::ActionEvent &event) { if (isStorageActive()) { - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, item->getInvIndex(), item->getQuantity(), Inventory::STORAGE); } else { - if (keyboard.isKeyActive(keyboard.KEY_MOD)) + if (keyboard.isActionActive(keyboard.KEY_MOD)) { Net::getInventoryHandler()->dropItem( item, item->getQuantity()); @@ -386,11 +386,11 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) { Window::mouseClicked(event); - const bool mod = (isStorageActive() && keyboard.isKeyActive( + const bool mod = (isStorageActive() && keyboard.isActionActive( keyboard.KEY_MOD)); const bool mod2 = (tradeWindow && tradeWindow->isVisible() - && keyboard.isKeyActive(keyboard.KEY_MOD)); + && keyboard.isActionActive(keyboard.KEY_MOD)); if (!mod && !mod2 && event.getButton() == gcn::MouseEvent::RIGHT) { @@ -431,7 +431,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) } else { - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, item->getInvIndex(), item->getQuantity(), Inventory::STORAGE); } @@ -445,7 +445,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) } else { - Net::getInventoryHandler()->moveItem(Inventory::STORAGE, + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, item->getInvIndex(), item->getQuantity(), Inventory::INVENTORY); } diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index 2b35ec9c4..9d4be5afc 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -115,7 +115,7 @@ class InventoryWindow : public Window, void slotsChanged(Inventory* inventory); - bool isMainInventory() + bool isMainInventory() const { return mInventory->isMainInventory(); } /** diff --git a/src/gui/itemamountwindow.cpp b/src/gui/itemamountwindow.cpp index 9e2a97681..3b01b559f 100644 --- a/src/gui/itemamountwindow.cpp +++ b/src/gui/itemamountwindow.cpp @@ -113,14 +113,12 @@ void ItemAmountWindow::finish(Item *item, int amount, int price, Usage usage) Net::getInventoryHandler()->splitItem(item, amount); break; case StoreAdd: - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, - item->getInvIndex(), amount, - Inventory::STORAGE); + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, + item->getInvIndex(), amount, Inventory::STORAGE); break; case StoreRemove: - Net::getInventoryHandler()->moveItem(Inventory::STORAGE, - item->getInvIndex(), amount, - Inventory::INVENTORY); + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, + item->getInvIndex(), amount, Inventory::INVENTORY); break; case ShopBuyAdd: if (shopWindow) diff --git a/src/gui/logindialog.cpp b/src/gui/logindialog.cpp index b1c80b102..ef8fd6bf0 100644 --- a/src/gui/logindialog.cpp +++ b/src/gui/logindialog.cpp @@ -88,6 +88,7 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName, mUpdateHost(updateHost), mServerName(serverName) { + gcn::Label *serverLabel1 = new Label(_("Server:")); gcn::Label *serverLabel2 = new Label(serverName); serverLabel2->adjustSize(); @@ -131,12 +132,11 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName, mPassField->addActionListener(this); place(0, 0, serverLabel1); - place(1, 0, serverLabel2, 8).setPadding(1); - + place(1, 0, serverLabel2, 8); place(0, 1, userLabel); place(0, 2, passLabel); - place(1, 1, mUserField, 8).setPadding(1); - place(1, 2, mPassField, 8).setPadding(1); + place(1, 1, mUserField, 8); + place(1, 2, mPassField, 8); place(0, 6, mUpdateTypeLabel, 1); place(1, 6, mUpdateTypeDropDown, 8); place(0, 7, mCustomUpdateHost, 9); @@ -146,9 +146,8 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName, place(2, 10, mServerButton); place(3, 10, mLoginButton); - reflowLayout(); - addKeyListener(this); + setContentSize(300, 200); center(); setVisible(true); @@ -178,7 +177,8 @@ void LoginDialog::action(const gcn::ActionEvent &event) mLoginData->remember = mKeepCheck->isSelected(); int updateType = mUpdateTypeDropDown->getSelected(); - if (mCustomUpdateHost->isSelected()) + if (mCustomUpdateHost->isSelected() + && mUpdateHostText->getText().empty()) { updateType |= LoginData::Upd_Custom; serverConfig.setValue("customUpdateHost", diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp index 265748b6f..3e5b30a9c 100644 --- a/src/gui/npcdialog.cpp +++ b/src/gui/npcdialog.cpp @@ -26,6 +26,7 @@ #include "client.h" #include "gui/setup.h" +#include "gui/viewport.h" #include "gui/widgets/browserbox.h" #include "gui/widgets/button.h" @@ -62,7 +63,10 @@ NpcDialog::NpcDialog(int npcId) : mDefaultInt(0), mInputState(NPC_INPUT_NONE), mActionState(NPC_ACTION_WAIT), - mLastNextTime(0) + mLastNextTime(0), + mCameraMode(-1), + mCameraX(0), + mCameraY(0) { // Basic Window Setup setWindowName("NpcText"); @@ -220,6 +224,7 @@ void NpcDialog::action(const gcn::ActionEvent &event) return; nextDialog(); + addText(std::string(), false); } else if (mActionState == NPC_ACTION_CLOSE || mActionState == NPC_ACTION_WAIT) @@ -301,6 +306,7 @@ void NpcDialog::nextDialog() void NpcDialog::closeDialog() { + restoreCamera(); Net::getNpcHandler()->closeDialog(mNpcId); } @@ -504,4 +510,34 @@ void NpcDialog::buildLayout() redraw(); mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll()); -}
\ No newline at end of file +} + +void NpcDialog::saveCamera() +{ + if (!viewport || mCameraMode >= 0) + return; + + mCameraMode = viewport->getCameraMode(); + mCameraX = viewport->getCameraRelativeX(); + mCameraY = viewport->getCameraRelativeY(); +} + +void NpcDialog::restoreCamera() +{ + if (!viewport || mCameraMode == -1) + return; + + if (!mCameraMode) + { + if (viewport->getCameraMode() != mCameraMode) + viewport->toggleCameraMode(); + } + else + { + if (viewport->getCameraMode() != mCameraMode) + viewport->toggleCameraMode(); + viewport->setCameraRelativeX(mCameraX); + viewport->setCameraRelativeY(mCameraY); + } + mCameraMode = -1; +} diff --git a/src/gui/npcdialog.h b/src/gui/npcdialog.h index e76897499..d4288d5c9 100644 --- a/src/gui/npcdialog.h +++ b/src/gui/npcdialog.h @@ -154,7 +154,8 @@ class NpcDialog : public Window, public gcn::ActionListener, /** * Returns true if any instances exist. */ - static bool isActive() { return !instances.empty(); } + static bool isActive() + { return !instances.empty(); } /** * Returns the first active instance. Useful for pushing user @@ -172,6 +173,10 @@ class NpcDialog : public Window, public gcn::ActionListener, */ static void destroyAll(); + void saveCamera(); + + void restoreCamera(); + private: typedef std::list<NpcDialog*> DialogList; static DialogList instances; @@ -230,6 +235,9 @@ class NpcDialog : public Window, public gcn::ActionListener, NpcInputState mInputState; NpcActionState mActionState; int mLastNextTime; + int mCameraMode; + int mCameraX; + int mCameraY; }; #endif // NPCDIALOG_H diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp index 74e8dbe46..73484f1d5 100644 --- a/src/gui/outfitwindow.cpp +++ b/src/gui/outfitwindow.cpp @@ -491,375 +491,32 @@ void OutfitWindow::unequipNotInOutfit(int outfit) } } +static const SDLKey numsTbl[] = +{ + SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9, + SDLK_0, SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_INSERT, SDLK_HOME, + SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, SDLK_o, + SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_BACKSLASH, SDLK_a, + SDLK_s, SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, + SDLK_SEMICOLON, SDLK_QUOTE, SDLK_z, SDLK_x, SDLK_c, SDLK_v, SDLK_b, SDLK_n, + SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH +}; + int OutfitWindow::keyToNumber(SDLKey key) const { - int outfitNum = -1; - switch (key) + for (unsigned f = 0; f < sizeof(numsTbl) / sizeof(SDLKey); f ++) { - case SDLK_1: - case SDLK_2: - case SDLK_3: - case SDLK_4: - case SDLK_5: - case SDLK_6: - case SDLK_7: - case SDLK_8: - case SDLK_9: - outfitNum = key - SDLK_1; - break; - - case SDLK_0: - outfitNum = 9; - break; - - case SDLK_MINUS: - outfitNum = 10; - break; - - case SDLK_EQUALS: - outfitNum = 11; - break; - - case SDLK_BACKSPACE: - outfitNum = 12; - break; - - case SDLK_INSERT: - outfitNum = 13; - break; - - case SDLK_HOME: - outfitNum = 14; - break; - - case SDLK_q: - outfitNum = 15; - break; - - case SDLK_w: - outfitNum = 16; - break; - - case SDLK_e: - outfitNum = 17; - break; - - case SDLK_r: - outfitNum = 18; - break; - - case SDLK_t: - outfitNum = 19; - break; - - case SDLK_y: - outfitNum = 20; - break; - - case SDLK_u: - outfitNum = 21; - break; - - case SDLK_i: - outfitNum = 22; - break; - - case SDLK_o: - outfitNum = 23; - break; - - case SDLK_p: - outfitNum = 24; - break; - - case SDLK_LEFTBRACKET: - outfitNum = 25; - break; - - case SDLK_RIGHTBRACKET: - outfitNum = 26; - break; - - case SDLK_BACKSLASH: - outfitNum = 27; - break; - - case SDLK_a: - outfitNum = 28; - break; - - case SDLK_s: - outfitNum = 29; - break; - - case SDLK_d: - outfitNum = 30; - break; - - case SDLK_f: - outfitNum = 31; - break; - - case SDLK_g: - outfitNum = 32; - break; - - case SDLK_h: - outfitNum = 33; - break; - - case SDLK_j: - outfitNum = 34; - break; - - case SDLK_k: - outfitNum = 35; - break; - - case SDLK_l: - outfitNum = 36; - break; - - case SDLK_SEMICOLON: - outfitNum = 37; - break; - - case SDLK_QUOTE: - outfitNum = 38; - break; - - case SDLK_z: - outfitNum = 39; - break; - - - case SDLK_x: - outfitNum = 40; - break; - - case SDLK_c: - outfitNum = 41; - break; - - case SDLK_v: - outfitNum = 42; - break; - - case SDLK_b: - outfitNum = 43; - break; - - case SDLK_n: - outfitNum = 44; - break; - - case SDLK_m: - outfitNum = 45; - break; - - case SDLK_COMMA: - outfitNum = 46; - break; - - case SDLK_PERIOD: - outfitNum = 47; - break; - - case SDLK_SLASH: - outfitNum = 48; - break; - - default: - break; + if (numsTbl[f] == key) + return f; } - - return outfitNum; + return -1; } -SDLKey OutfitWindow::numberToKey(int number) const +SDLKey OutfitWindow::numberToKey(unsigned number) const { - SDLKey key = SDLK_UNKNOWN; - switch (number) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - key = static_cast<SDLKey>( - static_cast<unsigned int>(SDLK_1) + number); - break; - - case 9: - key = SDLK_0; - break; - - case 10: - key = SDLK_MINUS; - break; - - case 11: - key = SDLK_EQUALS; - break; - - case 12: - key = SDLK_BACKSPACE; - break; - - case 13: - key = SDLK_INSERT; - break; - - case 14: - key = SDLK_HOME; - break; - - case 15: - key = SDLK_q; - break; - - case 16: - key = SDLK_w; - break; - - case 17: - key = SDLK_e; - break; - - case 18: - key = SDLK_r; - break; - - case 19: - key = SDLK_t; - break; - - case 20: - key = SDLK_y; - break; - - case 21: - key = SDLK_u; - break; - - case 22: - key = SDLK_i; - break; - - case 23: - key = SDLK_o; - break; - - case 24: - key = SDLK_p; - break; - - case 25: - key = SDLK_LEFTBRACKET; - break; - - case 26: - key = SDLK_RIGHTBRACKET; - break; - - case 27: - key = SDLK_BACKSLASH; - break; - - case 28: - key = SDLK_a; - break; - - case 29: - key = SDLK_s; - break; - - case 30: - key = SDLK_d; - break; - - case 31: - key = SDLK_f; - break; - - case 32: - key = SDLK_g; - break; - - case 33: - key = SDLK_h; - break; - - case 34: - key = SDLK_j; - break; - - case 35: - key = SDLK_k; - break; - - case 36: - key = SDLK_l; - break; - - case 37: - key = SDLK_SEMICOLON; - break; - - case 38: - key = SDLK_QUOTE; - break; - - case 39: - key = SDLK_z; - break; - - - case 40: - key = SDLK_x; - break; - - case 41: - key = SDLK_c; - break; - - case 42: - key = SDLK_v; - break; - - case 43: - key = SDLK_b; - break; - - case 44: - key = SDLK_n; - break; - - case 45: - key = SDLK_m; - break; - - case 46: - key = SDLK_COMMA; - break; - - case 47: - key = SDLK_PERIOD; - break; - - case 48: - key = SDLK_SLASH; - break; - - default: - break; - } - - return key; + if (number >= sizeof(numsTbl) / sizeof(SDLKey)) + return SDLK_UNKNOWN; + return numsTbl[number]; } std::string OutfitWindow::keyName(int number) diff --git a/src/gui/outfitwindow.h b/src/gui/outfitwindow.h index b2b46c7e7..6f67c472d 100644 --- a/src/gui/outfitwindow.h +++ b/src/gui/outfitwindow.h @@ -72,7 +72,7 @@ class OutfitWindow : public Window, gcn::ActionListener void setItemSelected(Item *item); - bool isItemSelected() + bool isItemSelected() const { return mItemSelected > 0; } void wearOutfit(int outfit, bool unwearEmpty = true, @@ -90,7 +90,7 @@ class OutfitWindow : public Window, gcn::ActionListener int keyToNumber(SDLKey key) const A_PURE; - SDLKey numberToKey(int number) const A_PURE; + SDLKey numberToKey(unsigned number) const A_PURE; void next(); diff --git a/src/gui/palette.h b/src/gui/palette.h index 36d87e305..7d5d93830 100644 --- a/src/gui/palette.h +++ b/src/gui/palette.h @@ -98,9 +98,7 @@ class Palette * @return the gradient type of the color with the given index */ inline GradientType getGradientType(int type) const - { - return mColors[type].grad; - } + { return mColors[type].grad; } /** * Get the character used by the specified color. @@ -110,9 +108,7 @@ class Palette * @return the color char of the color with the given index */ inline char getColorChar(int type) const - { - return mColors[type].ch; - } + { return mColors[type].ch; } /** * Gets the gradient delay for the specified type. @@ -122,7 +118,7 @@ class Palette * @return the gradient delay of the color with the given index */ inline int getGradientDelay(int type) const - { return mColors[type].delay; } + { return mColors[type].delay; } /** * Updates all colors, that are non-static. diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index cd3a4c5ad..142acc69c 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -1184,19 +1184,19 @@ void PopupMenu::handleLink(const std::string &link, int cnt = 10; if (cnt > mItem->getQuantity()) cnt = mItem->getQuantity(); - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, mItem->getInvIndex(), cnt, Inventory::STORAGE); } else if (link == "store half" && mItem) { - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, mItem->getInvIndex(), mItem->getQuantity() / 2, Inventory::STORAGE); } else if (link == "store all" && mItem) { - Net::getInventoryHandler()->moveItem(Inventory::INVENTORY, + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, mItem->getInvIndex(), mItem->getQuantity(), Inventory::STORAGE); } @@ -1235,19 +1235,19 @@ void PopupMenu::handleLink(const std::string &link, int cnt = 10; if (cnt > mItem->getQuantity()) cnt = mItem->getQuantity(); - Net::getInventoryHandler()->moveItem(Inventory::STORAGE, + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, mItem->getInvIndex(), cnt, Inventory::INVENTORY); } else if (link == "retrieve half" && mItem) { - Net::getInventoryHandler()->moveItem(Inventory::STORAGE, + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, mItem->getInvIndex(), mItem->getQuantity() / 2, Inventory::INVENTORY); } else if (link == "retrieve all" && mItem) { - Net::getInventoryHandler()->moveItem(Inventory::STORAGE, + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, mItem->getInvIndex(), mItem->getQuantity(), Inventory::INVENTORY); } diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 39ff19a89..59bdf9660 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -28,6 +28,7 @@ #include "logger.h" #include "main.h" +#include "gui/editserverdialog.h" #include "gui/gui.h" #include "gui/logindialog.h" #include "gui/okdialog.h" @@ -117,8 +118,8 @@ std::string ServersListModel::getElementAt(int elementIndex) const ServerInfo &server = mServers->at(elementIndex); std::string myServer; myServer += server.hostname; - myServer += ":"; - myServer += toString(server.port); +// myServer += ":"; +// myServer += toString(server.port); return myServer; } @@ -138,20 +139,6 @@ void ServersListModel::setVersionString(int index, const std::string &version) } } -std::string TypeListModel::getElementAt(int elementIndex) -{ - if (elementIndex == 0) - return "TmwAthena"; - else if (elementIndex == 1) - return "Evol"; -#ifdef MANASERV_SUPPORT - else if (elementIndex == 2) - return "ManaServ"; -#endif - else - return "Unknown"; -} - class ServersListBox : public ListBox { public: @@ -196,20 +183,24 @@ public: graphics->setColor(mTextColor); int top; + int x = 2; if (!info.name.empty()) { graphics->setFont(boldFont); + x += boldFont->getWidth(info.name) + 15; graphics->drawText(info.name, 2, y); - top = y + height / 2; + top = y + boldFont->getHeight() + 2; } else { - top = y + height / 4; + top = y + height / 4 + 2; } graphics->setFont(getFont()); + if (!info.description.empty()) + graphics->drawText(info.description, x, y); graphics->drawText(model->getElementAt(i), 2, top); if (info.version.first > 0) @@ -224,7 +215,7 @@ public: unsigned int getRowHeight() const { - return 2 * getFont()->getHeight(); + return 2 * getFont()->getHeight() + 5; } private: gcn::Color mHighlightColor; @@ -249,11 +240,6 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): setWindowName("ServerDialog"); - Label *serverLabel = new Label(_("Server:")); - Label *portLabel = new Label(_("Port:")); - - mServerNameField = new TextField(mServerInfo->hostname); - mPortField = new TextField(toString(mServerInfo->port)); mPersistentIPCheckBox = new CheckBox(_("Use same ip for game sub servers"), config.getBoolValue("usePersistentIP"), this, "persitent ip"); @@ -268,66 +254,33 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): ScrollArea *usedScroll = new ScrollArea(mServersList); usedScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - Label *typeLabel = new Label(_("Server type:")); - mTypeListModel = new TypeListModel(); - mTypeField = new DropDown(mTypeListModel); - switch (serverInfo->type) - { - case ServerInfo::MANASERV: -#ifdef MANASERV_SUPPORT - mTypeField->setSelected(2); - break; -#endif - default: - case ServerInfo::UNKNOWN: - case ServerInfo::TMWATHENA: - mTypeField->setSelected(0); - break; - case ServerInfo::EVOL: - mTypeField->setSelected(1); - break; - } - int n = 1; + int n = 0; mDescription = new Label(std::string()); mQuitButton = new Button(_("Quit"), "quit", this); mLoadButton = new Button(_("Load"), "load", this); mConnectButton = new Button(_("Connect"), "connect", this); - mManualEntryButton = new Button(_("Custom Server"), "addEntry", this); + mAddEntryButton = new Button(_("Add"), "addEntry", this); + mEditEntryButton = new Button(_("Edit"), "editEntry", this); mDeleteButton = new Button(_("Delete"), "remove", this); - mServerNameField->setActionEventId("connect"); - mPortField->setActionEventId("connect"); - - mServerNameField->addActionListener(this); - mPortField->addActionListener(this); - mManualEntryButton->addActionListener(this); mServersList->addSelectionListener(this); usedScroll->setVerticalScrollAmount(0); - place(0, 0, serverLabel); - place(1, 0, mServerNameField, 5).setPadding(3); - place(0, 1, portLabel); - place(1, 1, mPortField, 5).setPadding(3); - place(0, 2, typeLabel); - place(1, 2, mTypeField, 5).setPadding(3); - place(0, 2 + n, usedScroll, 6, 5).setPadding(3); - place(0, 7 + n, mDescription, 6); - place(0, 8 + n, mPersistentIPCheckBox, 6); - place(0, 9 + n, mManualEntryButton); - place(1, 9 + n, mDeleteButton); - place(2, 9 + n, mLoadButton); - place(4, 9 + n, mQuitButton); - place(5, 9 + n, mConnectButton); + place(0, 0 + n, usedScroll, 7, 5).setPadding(3); + place(0, 5 + n, mDescription, 7); + place(0, 6 + n, mPersistentIPCheckBox, 7); + place(0, 7 + n, mAddEntryButton); + place(1, 7 + n, mEditEntryButton); + place(2, 7 + n, mLoadButton); + place(3, 7 + n, mDeleteButton); + place(5, 7 + n, mQuitButton); + place(6, 7 + n, mConnectButton); // Make sure the list has enough height - getLayout().setRowHeight(3, 80); + getLayout().setRowHeight(0, 80); -/* - reflowLayout(400, 300); - setDefaultSize(400, 300, ImageRect::CENTER); -*/ // Do this manually instead of calling reflowLayout so we can enforce a // minimum width. int width = 0, height = 0; @@ -349,21 +302,10 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): loadWindowState(); - setFieldsReadOnly(true); mServersList->setSelected(0); // Do this after for the Delete button setVisible(true); - if (mServerNameField->getText().empty()) - { - mServerNameField->requestFocus(); - } - else - { - if (mPortField->getText().empty()) - mPortField->requestFocus(); - else - mConnectButton->requestFocus(); - } + mConnectButton->requestFocus(); loadServers(true); @@ -381,82 +323,48 @@ ServerDialog::~ServerDialog() } delete mServersListModel; mServersListModel = nullptr; - delete mTypeListModel; - mTypeListModel = nullptr; } void ServerDialog::action(const gcn::ActionEvent &event) { - if (event.getId() == "ok") - { - // Give focus back to the server dialog. - mServerNameField->requestFocus(); - } - else if (event.getId() == "connect") + if (event.getId() == "connect") { - // Check login - if (mServerNameField->getText().empty() - || mPortField->getText().empty()) - { - OkDialog *dlg = new OkDialog(_("Error"), - _("Please type both the address and the port of a server.")); - dlg->addActionListener(this); - } - else - { - if (mDownload) - mDownload->cancel(); - - mQuitButton->setEnabled(false); - mConnectButton->setEnabled(false); - mLoadButton->setEnabled(false); + if (Client::getState() == STATE_CONNECT_SERVER) + return; - mServerInfo->hostname = mServerNameField->getText(); - mServerInfo->port = static_cast<short>( - atoi(mPortField->getText().c_str())); + if (mDownload) + mDownload->cancel(); - if (mTypeField) - { - switch (mTypeField->getSelected()) - { - case 0: - mServerInfo->type = ServerInfo::TMWATHENA; - break; - case 1: - mServerInfo->type = ServerInfo::EVOL; - break; -#ifdef MANASERV_SUPPORT - case 2: - mServerInfo->type = ServerInfo::MANASERV; - break; -#endif - default: - mServerInfo->type = ServerInfo::UNKNOWN; - } - } - else - { - mServerInfo->type = ServerInfo::TMWATHENA; - } + mQuitButton->setEnabled(false); + mConnectButton->setEnabled(false); + mLoadButton->setEnabled(false); - // Save the selected server - mServerInfo->save = true; + int index = mServersList->getSelected(); + if (index < 0) + return; - if (chatLogger) - chatLogger->setServerName(mServerInfo->hostname); + ServerInfo server = mServers.at(index); + mServerInfo->hostname = server.hostname; + mServerInfo->port = server.port; + mServerInfo->type = server.type; + mServerInfo->name = server.name; + mServerInfo->description = server.description; + mServerInfo->save = true; - saveCustomServers(*mServerInfo); + if (chatLogger) + chatLogger->setServerName(mServerInfo->hostname); - if (!LoginDialog::savedPasswordKey.empty()) - { - if (mServerInfo->hostname != LoginDialog::savedPasswordKey) - LoginDialog::savedPassword = ""; - } + saveCustomServers(*mServerInfo); - config.setValue("usePersistentIP", - mPersistentIPCheckBox->isSelected()); - Client::setState(STATE_CONNECT_SERVER); + if (!LoginDialog::savedPasswordKey.empty()) + { + if (mServerInfo->hostname != LoginDialog::savedPasswordKey) + LoginDialog::savedPassword = ""; } + + config.setValue("usePersistentIP", + mPersistentIPCheckBox->isSelected()); + Client::setState(STATE_CONNECT_SERVER); } else if (event.getId() == "quit") { @@ -470,15 +378,23 @@ void ServerDialog::action(const gcn::ActionEvent &event) } else if (event.getId() == "addEntry") { - setFieldsReadOnly(false); + new EditServerDialog(this, ServerInfo(), -1); + } + else if (event.getId() == "editEntry") + { + int index = mServersList->getSelected(); + if (index >= 0) + new EditServerDialog(this, mServers.at(index), index); } else if (event.getId() == "remove") { int index = mServersList->getSelected(); - mServersList->setSelected(0); - mServers.erase(mServers.begin() + index); - - saveCustomServers(); + if (index >= 0) + { + mServersList->setSelected(0); + mServers.erase(mServers.begin() + index); + saveCustomServers(); + } } } @@ -503,34 +419,6 @@ void ServerDialog::valueChanged(const gcn::SelectionEvent &) // Update the server and post fields according to the new selection const ServerInfo &myServer = mServersListModel->getServer(index); - mDescription->setCaption(myServer.description); - mServerNameField->setText(myServer.hostname); - mPortField->setText(toString(myServer.port)); - if (mTypeField) - { - switch (myServer.type) - { - case ServerInfo::TMWATHENA: - case ServerInfo::UNKNOWN: -#ifdef MANASERV_SUPPORT - default: - mTypeField->setSelected(0); - break; - case ServerInfo::MANASERV: - mTypeField->setSelected(2); - break; -#else - case ServerInfo::MANASERV: - default: - mTypeField->setSelected(0); - break; -#endif - case ServerInfo::EVOL: - mTypeField->setSelected(1); - break; - } - } - setFieldsReadOnly(true); mDeleteButton->setEnabled(myServer.save); } @@ -577,30 +465,6 @@ void ServerDialog::logic() Window::logic(); } -void ServerDialog::setFieldsReadOnly(bool readOnly) -{ - if (!readOnly) - { - mDescription->setCaption(std::string()); - mServersList->setSelected(-1); - - mServerNameField->setText(std::string()); - mPortField->setText(std::string("6901")); - - mServerNameField->requestFocus(); - } - - mManualEntryButton->setEnabled(readOnly); - mDeleteButton->setEnabled(false); - mLoadButton->setEnabled(readOnly); - mDescription->setVisible(readOnly); - - mServerNameField->setEnabled(!readOnly); - mPortField->setEnabled(!readOnly); - if (mTypeField) - mTypeField->setEnabled(!readOnly); -} - void ServerDialog::downloadServerList() { // Try to load the configuration value for the onlineServerList @@ -647,6 +511,9 @@ void ServerDialog::loadServers(bool addNew) return; } + const std::string lang = getLangShort(); + const std::string description2 = "description_" + lang; + for_each_xml_child_node(serverNode, rootNode) { if (!xmlNameEqual(serverNode, "server")) @@ -696,7 +563,9 @@ void ServerDialog::loadServers(bool addNew) server.port = defaultPortForServerType(server.type); } } - else if (xmlNameEqual(subNode, "description")) + else if ((xmlNameEqual(subNode, "description") + && server.description.empty()) || (!lang.empty() + && xmlNameEqual(subNode, description2.c_str()))) { server.description = reinterpret_cast<const char*>( subNode->xmlChildrenNode->content); @@ -716,6 +585,7 @@ void ServerDialog::loadServers(bool addNew) // Use the name listed in the server list mServers[i].name = server.name; mServers[i].version = server.version; + mServers[i].description = server.description; mServersListModel->setVersionString(i, version); found = true; break; @@ -731,12 +601,16 @@ void ServerDialog::loadCustomServers() for (int i = 0; i < MAX_SERVERLIST; ++i) { const std::string index = toString(i); - const std::string nameKey = "MostUsedServerName" + index; + const std::string nameKey = "MostUsedServerDescName" + index; + const std::string descKey = "MostUsedServerDescription" + index; + const std::string hostKey = "MostUsedServerName" + index; const std::string typeKey = "MostUsedServerType" + index; const std::string portKey = "MostUsedServerPort" + index; ServerInfo server; - server.hostname = config.getValue(nameKey, ""); + server.name = config.getValue(nameKey, ""); + server.description = config.getValue(descKey, ""); + server.hostname = config.getValue(hostKey, ""); server.type = ServerInfo::parseType(config.getValue(typeKey, "")); const int defaultPort = defaultPortForServerType(server.type); @@ -752,21 +626,29 @@ void ServerDialog::loadCustomServers() } } -void ServerDialog::saveCustomServers(const ServerInfo ¤tServer) +void ServerDialog::saveCustomServers(const ServerInfo ¤tServer, + int index) { // Make sure the current server is mentioned first if (currentServer.isValid()) { - ServerInfos::iterator i, i_end = mServers.end(); - for (i = mServers.begin(); i != i_end; ++i) + if (index >= 0 && (unsigned)index < mServers.size()) { - if (*i == currentServer) + mServers[index] = currentServer; + } + else + { + ServerInfos::iterator i, i_end = mServers.end(); + for (i = mServers.begin(); i != i_end; ++i) { - mServers.erase(i); - break; + if (*i == currentServer) + { + mServers.erase(i); + break; + } } + mServers.insert(mServers.begin(), currentServer); } - mServers.insert(mServers.begin(), currentServer); } int savedServerCount = 0; @@ -780,15 +662,19 @@ void ServerDialog::saveCustomServers(const ServerInfo ¤tServer) if (!(server.save && server.isValid())) continue; - const std::string index = toString(savedServerCount); - const std::string nameKey = "MostUsedServerName" + index; - const std::string typeKey = "MostUsedServerType" + index; - const std::string portKey = "MostUsedServerPort" + index; + const std::string num = toString(savedServerCount); + const std::string nameKey = "MostUsedServerDescName" + num; + const std::string descKey = "MostUsedServerDescription" + num; + const std::string hostKey = "MostUsedServerName" + num; + const std::string typeKey = "MostUsedServerType" + num; + const std::string portKey = "MostUsedServerPort" + num; - config.setValue(nameKey, toString(server.hostname)); + config.setValue(nameKey, toString(server.name)); + config.setValue(descKey, toString(server.description)); + config.setValue(hostKey, toString(server.hostname)); config.setValue(typeKey, serverTypeToString(server.type)); config.setValue(portKey, toString(server.port)); - ++savedServerCount; + ++ savedServerCount; } // Insert an invalid entry at the end to make the loading stop there @@ -799,7 +685,7 @@ void ServerDialog::saveCustomServers(const ServerInfo ¤tServer) int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, size_t total, size_t remaining) { - if (status == DOWNLOAD_STATUS_CANCELLED) + if (!ptr || status == DOWNLOAD_STATUS_CANCELLED) return -1; ServerDialog *sd = reinterpret_cast<ServerDialog*>(ptr); @@ -853,3 +739,8 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, return 0; } + +void ServerDialog::updateServer(ServerInfo server, int index) +{ + saveCustomServers(server, index); +} diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h index d2fe0d25b..c23fb8776 100644 --- a/src/gui/serverdialog.h +++ b/src/gui/serverdialog.h @@ -83,30 +83,6 @@ class ServersListModel : public gcn::ListModel ServerDialog *mParent; }; -/** - * Server Type List Model - */ -class TypeListModel : public gcn::ListModel -{ - public: - TypeListModel() {} - - /** - * Used to get number of line in the list - */ - int getNumberOfElements() -#ifdef MANASERV_SUPPORT - { return 3; } -#else - { return 2; } -#endif - - /** - * Used to get an element from the list - */ - std::string getElementAt(int elementIndex); -}; - /** * The server choice dialog. @@ -147,12 +123,17 @@ class ServerDialog : public Window, void logic(); + void updateServer(ServerInfo server, int index); + protected: friend class ServersListModel; + MutexLocker lock() { return MutexLocker(&mMutex); } private: + friend class EditServerDialog; + /** * Called to load a list of available server from an online xml file. */ @@ -160,28 +141,23 @@ class ServerDialog : public Window, void loadServers(bool addNew = true); void loadCustomServers(); - void saveCustomServers(const ServerInfo ¤tServer = ServerInfo()); + void saveCustomServers(const ServerInfo ¤tServer = ServerInfo(), + int index = -1); static int downloadUpdate(void *ptr, DownloadStatus status, size_t total, size_t remaining); - void setFieldsReadOnly(bool readOnly); - - TextField *mServerNameField; - TextField *mPortField; Label *mDescription; Button *mQuitButton; Button *mConnectButton; - Button *mManualEntryButton; + Button *mAddEntryButton; + Button *mEditEntryButton; Button *mDeleteButton; Button *mLoadButton; ListBox *mServersList; ServersListModel *mServersListModel; - DropDown *mTypeField; - TypeListModel *mTypeListModel; - const std::string &mDir; enum ServerDialogDownloadStatus diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index bac474950..3408fba33 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -75,7 +75,7 @@ Setup::Setup(): nullptr }; int x = width; - for (const char **curBtn = buttonNames; *curBtn; ++curBtn) + for (const char **curBtn = buttonNames; *curBtn; ++ curBtn) { Button *btn = new Button(gettext(*curBtn), *curBtn, this); x -= btn->getWidth() + 5; diff --git a/src/gui/setup_relations.cpp b/src/gui/setup_relations.cpp index 9ddef9e1a..571856a14 100644 --- a/src/gui/setup_relations.cpp +++ b/src/gui/setup_relations.cpp @@ -193,6 +193,8 @@ public: std::string getPlayerAt(int index) const { + if (index < 0 || index >= (signed)mPlayers->size()) + return ""; return (*mPlayers)[index]; } @@ -257,10 +259,7 @@ Setup_Relations::Setup_Relations(): mIgnoreActionChoicesBox = new DropDown(mIgnoreActionChoicesModel); for (int i = 0; i < COLUMNS_NR; i++) - { - mPlayerTableTitleModel->set(0, i, - new Label(gettext(table_titles[i]))); - } + mPlayerTableTitleModel->set(0, i, new Label(gettext(table_titles[i]))); mPlayerTitleTable->setLinewiseSelection(true); diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index 259388fd0..9a5b30ea7 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -143,11 +143,11 @@ ModeListModel::ModeListModel() } else { - for (int i = 0; modes[i]; ++i) + for (int i = 0; modes[i]; ++ i) { const std::string modeString = toString(static_cast<int>(modes[i]->w)) + "x" - + toString(static_cast<int>(modes[i]->h)); + + toString(static_cast<int>(modes[i]->h)); mVideoModes.push_back(modeString); } } @@ -281,6 +281,8 @@ Setup_Video::Setup_Video(): mOpacity(config.getFloatValue("guialpha")), mFps(config.getIntValue("fpslimit")), mAltFps(config.getIntValue("altfpslimit")), + mEnableResize(config.getBoolValue("enableresize")), + mNoFrame(config.getBoolValue("noframe")), mSpeechMode(static_cast<Being::Speech>( config.getIntValue("speech"))), mModeListModel(new ModeListModel), @@ -296,6 +298,8 @@ Setup_Video::Setup_Video(): // TRANSLATORS: Refers to "Show own name" mPickupParticleCheckBox(new CheckBox(_("as particle"), mPickupParticleEnabled)), + mEnableResizeCheckBox(new CheckBox(_("Enable resize"), mEnableResize)), + mNoFrameCheckBox(new CheckBox(_("No frame"), mNoFrame)), mSpeechSlider(new Slider(0, 3)), mSpeechLabel(new Label("")), mAlphaSlider(new Slider(0.1, 1.0)), @@ -367,6 +371,8 @@ Setup_Video::Setup_Video(): mParticleDetailSlider->setActionEventId("particledetailslider"); mParticleDetailField->setActionEventId("particledetailfield"); mOpenGLDropDown->setActionEventId("opengl"); + mEnableResizeCheckBox->setActionEventId("enableresize"); + mNoFrameCheckBox->setActionEventId("noframe"); mModeList->addActionListener(this); mCustomCursorCheckBox->addActionListener(this); @@ -383,6 +389,8 @@ Setup_Video::Setup_Video(): mParticleDetailSlider->addActionListener(this); mParticleDetailField->addKeyListener(this); mOpenGLDropDown->addActionListener(this); + mEnableResizeCheckBox->addActionListener(this); + mNoFrameCheckBox->addActionListener(this); mSpeechLabel->setCaption(speechModeToString(mSpeechMode)); mSpeechSlider->setValue(mSpeechMode); @@ -397,8 +405,8 @@ Setup_Video::Setup_Video(): LayoutHelper h(this); ContainerPlacer place = h.getPlacer(0, 0); - place(0, 0, scrollArea, 1, 5).setPadding(2); - place(0, 5, mOpenGLDropDown, 1); + place(0, 0, scrollArea, 1, 6).setPadding(2); + place(0, 6, mOpenGLDropDown, 1); // place(0, 6, mHwAccelCheckBox, 6); @@ -406,34 +414,36 @@ Setup_Video::Setup_Video(): place(1, 1, mCustomCursorCheckBox, 3); - place(1, 2, mParticleEffectsCheckBox, 2); + place(1, 2, mEnableResizeCheckBox, 2); + place(1, 3, mNoFrameCheckBox, 2); - place(1, 3, mPickupNotifyLabel, 4); + place(1, 4, mParticleEffectsCheckBox, 2); - place(1, 4, mPickupChatCheckBox, 1); - place(2, 4, mPickupParticleCheckBox, 2); + place(1, 5, mPickupNotifyLabel, 4); + place(1, 6, mPickupChatCheckBox, 1); + place(2, 6, mPickupParticleCheckBox, 2); - place(0, 6, mAlphaSlider); - place(1, 6, alphaLabel, 3); + place(0, 7, mAlphaSlider); + place(1, 7, alphaLabel, 3); - place(0, 7, mFpsSlider); - place(1, 7, mFpsCheckBox).setPadding(3); - place(2, 7, mFpsLabel).setPadding(1); + place(0, 9, mFpsSlider); + place(1, 9, mFpsCheckBox).setPadding(3); + place(2, 9, mFpsLabel).setPadding(1); - place(0, 8, mAltFpsSlider); - place(1, 8, mAltFpsLabel).setPadding(3); + place(0, 10, mAltFpsSlider); + place(1, 10, mAltFpsLabel).setPadding(3); - place(0, 9, mSpeechSlider); - place(1, 9, speechLabel); - place(2, 9, mSpeechLabel, 3).setPadding(2); + place(0, 11, mSpeechSlider); + place(1, 11, speechLabel); + place(2, 11, mSpeechLabel, 3).setPadding(2); - place(0, 10, mOverlayDetailSlider); - place(1, 10, overlayDetailLabel); - place(2, 10, mOverlayDetailField, 3).setPadding(2); + place(0, 12, mOverlayDetailSlider); + place(1, 12, overlayDetailLabel); + place(2, 12, mOverlayDetailField, 3).setPadding(2); - place(0, 11, mParticleDetailSlider); - place(1, 11, particleDetailLabel); - place(2, 11, mParticleDetailField, 3).setPadding(2); + place(0, 13, mParticleDetailSlider); + place(1, 13, particleDetailLabel); + place(2, 13, mParticleDetailField, 3).setPadding(2); int width = 600; @@ -540,6 +550,8 @@ void Setup_Video::apply() mOpenGLEnabled = config.getIntValue("opengl"); mPickupChatEnabled = config.getBoolValue("showpickupchat"); mPickupParticleEnabled = config.getBoolValue("showpickupparticle"); + mEnableResize = config.getBoolValue("enableresize"); + mNoFrame = config.getBoolValue("noframe"); } void Setup_Video::cancel() @@ -560,6 +572,8 @@ void Setup_Video::cancel() mFpsLabel->setCaption(mFpsCheckBox->isSelected() ? toString(mFps) : _("None")); mAltFpsLabel->setCaption(_("Alt FPS limit: ") + toString(mAltFps)); + mEnableResizeCheckBox->setSelected(mEnableResize); + mNoFrameCheckBox->setSelected(mNoFrame); config.setValue("screen", mFullScreenEnabled); @@ -578,6 +592,8 @@ void Setup_Video::cancel() config.setValue("opengl", mOpenGLEnabled); config.setValue("showpickupchat", mPickupChatEnabled); config.setValue("showpickupparticle", mPickupParticleEnabled); + config.setValue("enableresize", mEnableResize); + config.setValue("noframe", mNoFrame); } void Setup_Video::action(const gcn::ActionEvent &event) @@ -614,6 +630,7 @@ void Setup_Video::action(const gcn::ActionEvent &event) // TODO: Find out why the drawing area doesn't resize without a restart. if (width != mainGraphics->mWidth || height != mainGraphics->mHeight) { +#if defined(_WIN32) if (width < mainGraphics->mWidth || height < mainGraphics->mHeight) new OkDialog(_("Screen Resolution Changed"), _("Restart your client for the change to take effect.") @@ -622,6 +639,9 @@ void Setup_Video::action(const gcn::ActionEvent &event) else new OkDialog(_("Screen Resolution Changed"), _("Restart your client for the change to take effect.")); +#else + Client::resize(width, height); +#endif } config.setValue("oldscreen", config.getBoolValue("screen")); @@ -711,6 +731,14 @@ void Setup_Video::action(const gcn::ActionEvent &event) mAltFpsSlider->setValue(mAltFps); mAltFpsSlider->setEnabled(mAltFps > 0); } + else if (id == "enableresize") + { + config.setValue("enableresize", mEnableResizeCheckBox->isSelected()); + } + else if (id == "noframe") + { + config.setValue("noframe", mNoFrameCheckBox->isSelected()); + } } void Setup_Video::externalUpdated() diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h index 0c82ab272..31d45d93d 100644 --- a/src/gui/setup_video.h +++ b/src/gui/setup_video.h @@ -62,6 +62,8 @@ class Setup_Video : public SetupTab, public gcn::KeyListener float mOpacity; int mFps; int mAltFps; + bool mEnableResize; + bool mNoFrame; Being::Speech mSpeechMode; ModeListModel *mModeListModel; @@ -85,6 +87,9 @@ class Setup_Video : public SetupTab, public gcn::KeyListener gcn::CheckBox *mPickupChatCheckBox; gcn::CheckBox *mPickupParticleCheckBox; + gcn::CheckBox *mEnableResizeCheckBox; + gcn::CheckBox *mNoFrameCheckBox; + gcn::Slider *mSpeechSlider; gcn::Label *mSpeechLabel; gcn::Slider *mAlphaSlider; diff --git a/src/gui/shopwindow.cpp b/src/gui/shopwindow.cpp index b6b87edb7..1a27b8b0c 100644 --- a/src/gui/shopwindow.cpp +++ b/src/gui/shopwindow.cpp @@ -55,6 +55,7 @@ #include "net/net.h" #include "net/chathandler.h" #include "net/npchandler.h" +#include "net/playerhandler.h" #include "net/tradehandler.h" #include "resources/iteminfo.h" @@ -206,11 +207,15 @@ void ShopWindow::action(const gcn::ActionEvent &event) && mBuyShopItemList->getSelected() >= 0) { mBuyShopItems->del(mBuyShopItemList->getSelected()); + if (isShopEmpty() && player_node) + player_node->updateStatus(); } else if (event.getId() == "delete sell" && mSellShopItemList && mSellShopItemList->getSelected() >= 0) { mSellShopItems->del(mSellShopItemList->getSelected()); + if (isShopEmpty() && player_node) + player_node->updateStatus(); } else if (event.getId() == "announce buy" && mBuyShopItems && mBuyShopItems->getNumberOfElements() > 0) @@ -306,8 +311,12 @@ void ShopWindow::addBuyItem(Item *item, int amount, int price) { if (!mBuyShopItems || !item) return; + bool emp = isShopEmpty(); mBuyShopItems->addItemNoDup(item->getId(), item->getColor(), amount, price); + if (emp && player_node) + player_node->updateStatus(); + updateButtonsAndLabels(); } @@ -315,8 +324,12 @@ void ShopWindow::addSellItem(Item *item, int amount, int price) { if (!mBuyShopItems || !item) return; + bool emp = isShopEmpty(); mSellShopItems->addItemNoDup(item->getId(), item->getColor(), amount, price); + if (emp && player_node) + player_node->updateStatus(); + updateButtonsAndLabels(); } diff --git a/src/gui/shopwindow.h b/src/gui/shopwindow.h index 53ed7690c..a8d131acb 100644 --- a/src/gui/shopwindow.h +++ b/src/gui/shopwindow.h @@ -109,7 +109,7 @@ class ShopWindow : public Window, public gcn::ActionListener, void setAcceptPlayer(std::string name) { mAcceptPlayer = name; } - const std::string &getAcceptPlayer() + const std::string &getAcceptPlayer() const { return mAcceptPlayer; } void sendMessage(const std::string &nick, std::string data, diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index dcb40927a..9032f82ef 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -77,7 +77,7 @@ class SkillDialog : public Window, public gcn::ActionListener SkillInfo* getSkill(int id); - bool hasSkills() + bool hasSkills() const { return !mSkills.empty(); } void widgetResized(const gcn::Event &event); diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 3988c819c..59ace1685 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -1143,7 +1143,7 @@ public: std::vector<std::string> *players = player_relations.getPlayersByRelation(PlayerRelation::FRIEND); - std::set<std::string> players2 = whoIsOnline->getOnlinePlayers(); + const std::set<std::string> &players2 = whoIsOnline->getOnlineNicks(); if (!players) return; @@ -1273,10 +1273,12 @@ SocialWindow::SocialWindow() : loadWindowState(); - mPlayers = new SocialPlayersTab("P"); + // TRANSLATORS: here P is title for visible players tab in social window + mPlayers = new SocialPlayersTab(_("P")); mTabs->addTab(mPlayers, mPlayers->mScroll); - mFriends = new SocialFriendsTab("F"); + // TRANSLATORS: here F is title for friends tab in social window + mFriends = new SocialFriendsTab(_("F")); mTabs->addTab(mFriends, mFriends->mScroll); mNavigation = new SocialNavigationTab(); diff --git a/src/gui/socialwindow.h b/src/gui/socialwindow.h index 1429866ee..9da78562b 100644 --- a/src/gui/socialwindow.h +++ b/src/gui/socialwindow.h @@ -101,13 +101,13 @@ public: void prevTab(); - Map* getMap() + Map* getMap() const { return mMap; } void setMap(Map *map) { mMap = map; mProcessedPortals = false; } - bool getProcessedPortals() + bool getProcessedPortals() const { return mProcessedPortals; } void setProcessedPortals(int n) diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index 410ee08e2..86964383a 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -69,7 +69,7 @@ class AttrDisplay : public Container virtual std::string update(); - virtual Type getType() + virtual Type getType() const { return UNKNOWN; } std::string getValue() @@ -96,7 +96,7 @@ class DerDisplay : public AttrDisplay public: DerDisplay(int id, const std::string &name); - virtual Type getType() + virtual Type getType() const { return DERIVED; } }; @@ -107,7 +107,7 @@ class ChangeDisplay : public AttrDisplay, gcn::ActionListener std::string update(); - virtual Type getType() + virtual Type getType() const { return CHANGEABLE; } void setPointsNeeded(int needed); @@ -424,12 +424,12 @@ void StatusWindow::addAttribute(int id, const std::string &name, if (modifiable) { disp = new ChangeDisplay(id, name); - mAttrCont->add(disp); + mAttrCont->add1(disp); } else { disp = new DerDisplay(id, name); - mDAttrCont->add(disp); + mDAttrCont->add1(disp); } mAttrs[id] = disp; } @@ -522,9 +522,14 @@ void StatusWindow::updateProgressBar(ProgressBar *bar, int value, int max, / static_cast<float>(max); if (percent) - bar->setText(strprintf("%2.5f%%", static_cast<double>(100 * progress))); + { + bar->setText(strprintf("%2.5f%%", + static_cast<double>(100 * progress))); + } else + { bar->setText(toString(value) + "/" + toString(max)); + } bar->setProgress(progress); } diff --git a/src/gui/theme.h b/src/gui/theme.h index 3be6882a3..9cb8f6180 100644 --- a/src/gui/theme.h +++ b/src/gui/theme.h @@ -95,7 +95,7 @@ class Skin */ void updateAlpha(float minimumOpacityAllowed = 0.0f); - int getPadding() + int getPadding() const { return mPadding; } int instances; diff --git a/src/gui/tradewindow.h b/src/gui/tradewindow.h index b055c90ce..268d2f108 100644 --- a/src/gui/tradewindow.h +++ b/src/gui/tradewindow.h @@ -128,7 +128,7 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener void initTrade(std::string nick); - std::string getAutoTradeNick() + std::string getAutoTradeNick() const { return mAutoAddToNick; } bool checkItem(Item *item); diff --git a/src/gui/updaterwindow.cpp b/src/gui/updaterwindow.cpp index 39dde65c3..28bd8467c 100644 --- a/src/gui/updaterwindow.cpp +++ b/src/gui/updaterwindow.cpp @@ -155,6 +155,12 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost, mLoadUpdates(applyUpdates), mUpdateType(updateType) { + setWindowName("UpdaterWindow"); + setResizable(true); + setDefaultSize(450, 400, ImageRect::CENTER); + setMinWidth(320); + setMinHeight(240); + mBrowserBox = new BrowserBox; mScrollArea = new ScrollArea(mBrowserBox); mLabel = new Label(_("Connecting...")); @@ -175,14 +181,12 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost, placer(3, 5, mCancelButton); placer(4, 5, mPlayButton); - reflowLayout(450, 400); - Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); addKeyListener(this); - center(); + loadWindowState(); setVisible(true); mCancelButton->requestFocus(); diff --git a/src/gui/userpalette.h b/src/gui/userpalette.h index cb0593fa7..6fba30abc 100644 --- a/src/gui/userpalette.h +++ b/src/gui/userpalette.h @@ -107,7 +107,7 @@ class UserPalette : public Palette, public gcn::ListModel * * @return the requested test color */ - inline const gcn::Color &getTestColor(int type) + inline const gcn::Color &getTestColor(int type) const { return mColors[type].testColor; } /** diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 1407415fd..7ff2c8850 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -497,16 +497,16 @@ void Viewport::mousePressed(gcn::MouseEvent &event) } } else if (player_node->withinAttackRange(mHoverBeing) || - keyboard.isKeyActive(keyboard.KEY_ATTACK)) + keyboard.isActionActive(keyboard.KEY_ATTACK)) { if (player_node != mHoverBeing) { player_node->attack(mHoverBeing, - !keyboard.isKeyActive(keyboard.KEY_TARGET)); + !keyboard.isActionActive(keyboard.KEY_TARGET)); return; } } - else if (!keyboard.isKeyActive(keyboard.KEY_ATTACK)) + else if (!keyboard.isActionActive(keyboard.KEY_ATTACK)) { if (player_node != mHoverBeing) { @@ -522,7 +522,7 @@ void Viewport::mousePressed(gcn::MouseEvent &event) player_node->pickUp(mHoverItem); } // Just walk around - else if (!keyboard.isKeyActive(keyboard.KEY_ATTACK)) + else if (!keyboard.isActionActive(keyboard.KEY_ATTACK)) { player_node->stopAttack(); player_node->cancelFollow(); @@ -875,3 +875,44 @@ bool Viewport::isPopupMenuVisible() { return mPopupMenu ? mPopupMenu->isVisible() : false; } + +void Viewport::moveCameraToActor(int actorId, int x, int y) +{ + if (!player_node) + return; + + Actor *actor = actorSpriteManager->findBeing(actorId); + if (!actor) + return; + Vector actorPos = actor->getPosition(); + Vector playerPos = player_node->getPosition(); + mCameraMode = 1; + mCameraRelativeX = actorPos.x - playerPos.x + x; + mCameraRelativeY = actorPos.y - playerPos.y + y; +} + +void Viewport::moveCameraToPosition(int x, int y) +{ + if (!player_node) + return; + + Vector playerPos = player_node->getPosition(); + mCameraMode = 1; + + mCameraRelativeX = x - playerPos.x; + mCameraRelativeY = y - playerPos.y; +} + +void Viewport::moveCameraRelative(int x, int y) +{ + mCameraMode = 1; + mCameraRelativeX += x; + mCameraRelativeY += y; +} + +void Viewport::returnCamera() +{ + mCameraMode = 0; + mCameraRelativeX = 0; + mCameraRelativeY = 0; +} diff --git a/src/gui/viewport.h b/src/gui/viewport.h index b25f51242..f3035b5df 100644 --- a/src/gui/viewport.h +++ b/src/gui/viewport.h @@ -218,13 +218,13 @@ class Viewport : public WindowContainer, public gcn::MouseListener, Map *getCurrentMap() const { return mMap; } - int getDebugPath() + int getDebugPath() const { return mShowDebugPath; } void setDebugPath(int n) { mShowDebugPath = n; } - int getCameraMode() + int getCameraMode() const { return mCameraMode; } /** @@ -237,19 +237,33 @@ class Viewport : public WindowContainer, public gcn::MouseListener, */ void cleanHoverItems(); - Map *getMap() + Map *getMap() const { return mMap; } void moveCamera(int dx, int dy); - int getCameraRelativeX() + int getCameraRelativeX() const { return mCameraRelativeX; } - int getCameraRelativeY() + int getCameraRelativeY() const { return mCameraRelativeY; } + void setCameraRelativeX(int n) + { mCameraRelativeX = n; } + + void setCameraRelativeY(int n) + { mCameraRelativeY = n; } + bool isPopupMenuVisible(); + void moveCameraToActor(int actorId, int x = 0, int y = 0); + + void moveCameraToPosition(int x, int y); + + void moveCameraRelative(int x, int y); + + void returnCamera(); + protected: friend class ActorSpriteManager; diff --git a/src/gui/whoisonline.cpp b/src/gui/whoisonline.cpp index a80fb4c89..205a1aae1 100644 --- a/src/gui/whoisonline.cpp +++ b/src/gui/whoisonline.cpp @@ -48,6 +48,7 @@ #include "gui/chatwindow.h" +#include "utils/dtor.h" #include "utils/gettext.h" #include "utils/stringutils.h" @@ -68,21 +69,10 @@ class NameFunctuator { public: - bool operator()(const std::string &left, - const std::string &right) const + bool operator()(const OnlinePlayer *left, + const OnlinePlayer *right) const { - for (std::string::const_iterator lit = left.begin(), - rit = right.begin(); - lit != left.end() && rit != right.end(); ++lit, ++rit) - { - if (tolower(*lit) < tolower(*rit)) - return true; - else if (tolower(*lit) > tolower(*rit)) - return false; - } - if (left.size() < right.size()) - return true; - return false; + return (compareStrI(left->getNick(), right->getNick()) < 0); } } nameCompare; @@ -149,6 +139,14 @@ WhoIsOnline::~WhoIsOnline() // Remove possibly leftover temporary download delete[] mCurlError; + + std::set<OnlinePlayer*>::iterator itd = mOnlinePlayers.begin(); + std::set<OnlinePlayer*>::iterator itd_end = mOnlinePlayers.end(); + + for (; itd != itd_end; ++ itd) + delete *itd; + mOnlinePlayers.clear(); + mOnlineNicks.clear(); } void WhoIsOnline::handleLink(const std::string& link, gcn::MouseEvent *event) @@ -186,10 +184,10 @@ void WhoIsOnline::handleLink(const std::string& link, gcn::MouseEvent *event) } } -void WhoIsOnline::updateWindow(std::vector<std::string> &friends, - std::vector<std::string> &neutral, - std::vector<std::string> &disregard, - std::vector<std::string> enemy, +void WhoIsOnline::updateWindow(std::vector<OnlinePlayer*> &friends, + std::vector<OnlinePlayer*> &neutral, + std::vector<OnlinePlayer*> &disregard, + std::vector<OnlinePlayer*> enemy, int numOnline) { //Set window caption @@ -202,7 +200,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends, bool addedFromSection(false); for (int i = 0; i < static_cast<int>(friends.size()); i++) { - mBrowserBox->addRow(friends.at(i)); + mBrowserBox->addRow(friends.at(i)->getText()); addedFromSection = true; } if (addedFromSection == true) @@ -212,7 +210,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends, } for (int i = 0; i < static_cast<int>(enemy.size()); i++) { - mBrowserBox->addRow(enemy.at(i)); + mBrowserBox->addRow(enemy.at(i)->getText()); addedFromSection = true; } if (addedFromSection == true) @@ -222,7 +220,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends, } for (int i = 0; i < static_cast<int>(neutral.size()); i++) { - mBrowserBox->addRow(neutral.at(i)); + mBrowserBox->addRow(neutral.at(i)->getText()); addedFromSection = true; } if (addedFromSection == true && !disregard.empty()) @@ -232,7 +230,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends, } for (int i = 0; i < static_cast<int>(disregard.size()); i++) { - mBrowserBox->addRow(disregard.at(i)); + mBrowserBox->addRow(disregard.at(i)->getText()); } if (mScrollArea->getVerticalMaxScroll() < @@ -243,43 +241,59 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends, } } -void WhoIsOnline::loadList(std::vector<std::string> &list) +void WhoIsOnline::loadList(std::vector<OnlinePlayer*> &list) { mBrowserBox->clearRows(); int numOnline = list.size(); - std::vector<std::string> friends; - std::vector<std::string> neutral; - std::vector<std::string> disregard; - std::vector<std::string> enemy; + std::vector<OnlinePlayer*> friends; + std::vector<OnlinePlayer*> neutral; + std::vector<OnlinePlayer*> disregard; + std::vector<OnlinePlayer*> enemy; + + std::set<OnlinePlayer*>::iterator itd = mOnlinePlayers.begin(); + std::set<OnlinePlayer*>::iterator itd_end = mOnlinePlayers.end(); + for (; itd != itd_end; ++ itd) + delete *itd; mOnlinePlayers.clear(); + mOnlineNicks.clear(); + mShowLevel = config.getBoolValue("showlevel"); - std::vector<std::string>::const_iterator it = list.begin(); - std::vector<std::string>::const_iterator it_end = list.end(); + std::vector<OnlinePlayer*>::iterator it = list.begin(); + std::vector<OnlinePlayer*>::iterator it_end = list.end(); for (; it != it_end; ++ it) { - std::string nick = *it; - mOnlinePlayers.insert(nick); + OnlinePlayer *player = *it; + std::string nick = player->getNick(); + mOnlinePlayers.insert(player); + mOnlineNicks.insert(nick); + + if (!mShowLevel) + player->setLevel(0); switch (player_relations.getRelation(nick)) { case PlayerRelation::NEUTRAL: default: - neutral.push_back(prepareNick(nick, 0, "0")); + player->setText("0"); + neutral.push_back(player); break; case PlayerRelation::FRIEND: - friends.push_back(prepareNick(nick, 0, "2")); + player->setText("2"); + friends.push_back(player); break; case PlayerRelation::DISREGARDED: case PlayerRelation::BLACKLISTED: - disregard.push_back(prepareNick(nick, 0, "8")); + player->setText("8"); + disregard.push_back(player); break; case PlayerRelation::ENEMY2: - enemy.push_back(prepareNick(nick, 0, "1")); + player->setText("1"); + enemy.push_back(player); break; case PlayerRelation::IGNORED: @@ -290,10 +304,10 @@ void WhoIsOnline::loadList(std::vector<std::string> &list) } updateWindow(friends, neutral, disregard, enemy, numOnline); - if (!mOnlinePlayers.empty()) + if (!mOnlineNicks.empty()) { if (chatWindow) - chatWindow->updateOnline(mOnlinePlayers); + chatWindow->updateOnline(mOnlineNicks); if (socialWindow) socialWindow->updateActiveList(); } @@ -313,15 +327,23 @@ void WhoIsOnline::loadWebList() bool listStarted(false); std::string lineStr; int numOnline(0); - std::vector<std::string> friends; - std::vector<std::string> neutral; - std::vector<std::string> disregard; - std::vector<std::string> enemy; + std::vector<OnlinePlayer*> friends; + std::vector<OnlinePlayer*> neutral; + std::vector<OnlinePlayer*> disregard; + std::vector<OnlinePlayer*> enemy; // Tokenize and add each line separately char *line = strtok(mMemoryBuffer, "\n"); const std::string gmText = "(GM)"; + + std::set<OnlinePlayer*>::iterator itd = mOnlinePlayers.begin(); + std::set<OnlinePlayer*>::iterator itd_end = mOnlinePlayers.end(); + + for (; itd != itd_end; ++ itd) + delete *itd; + mOnlinePlayers.clear(); + mOnlineNicks.clear(); mShowLevel = config.getBoolValue("showlevel"); @@ -383,27 +405,38 @@ void WhoIsOnline::loadWebList() } } - mOnlinePlayers.insert(nick); + + if (!mShowLevel) + level = 0; + + OnlinePlayer *player = new OnlinePlayer(nick, 255, level, + GENDER_UNSPECIFIED, -1); + mOnlinePlayers.insert(player); + mOnlineNicks.insert(nick); numOnline++; switch (player_relations.getRelation(nick)) { case PlayerRelation::NEUTRAL: default: - neutral.push_back(prepareNick(nick, level, "0")); + player->setText("0"); + neutral.push_back(player); break; case PlayerRelation::FRIEND: - friends.push_back(prepareNick(nick, level, "2")); + player->setText("2"); + friends.push_back(player); break; case PlayerRelation::DISREGARDED: case PlayerRelation::BLACKLISTED: - disregard.push_back(prepareNick(nick, level, "8")); + player->setText("8"); + disregard.push_back(player); break; case PlayerRelation::ENEMY2: - enemy.push_back(prepareNick(nick, level, "1")); + player->setText("1"); + enemy.push_back(player); break; case PlayerRelation::IGNORED: @@ -431,6 +464,9 @@ void WhoIsOnline::loadWebList() size_t WhoIsOnline::memoryWrite(void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (!stream) + return 0; + WhoIsOnline *wio = reinterpret_cast<WhoIsOnline *>(stream); size_t totalMem = size * nmemb; wio->mMemoryBuffer = static_cast<char*>(realloc(wio->mMemoryBuffer, @@ -472,8 +508,8 @@ int WhoIsOnline::downloadThread(void *ptr) curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr); curl_easy_setopt(curl, CURLOPT_USERAGENT, - strprintf(PACKAGE_EXTENDED_VERSION, branding - .getValue("appShort", "mana").c_str()).c_str()); + strprintf(PACKAGE_EXTENDED_VERSION, + branding.getStringValue("appName").c_str()).c_str()); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, wio->mCurlError); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); @@ -596,10 +632,10 @@ void WhoIsOnline::logic() mUpdateButton->setEnabled(true); mUpdateTimer = 0; updateSize(); - if (!mOnlinePlayers.empty()) + if (!mOnlineNicks.empty()) { if (chatWindow) - chatWindow->updateOnline(mOnlinePlayers); + chatWindow->updateOnline(mOnlineNicks); if (socialWindow) socialWindow->updateActiveList(); } @@ -681,3 +717,46 @@ void WhoIsOnline::optionChanged(const std::string &name) if (name == "updateOnlineList") mUpdateOnlineList = config.getBoolValue("updateOnlineList"); } + +void OnlinePlayer::setText(std::string color) +{ + mText = strprintf("@@%s|##%s%s ", mNick.c_str(), + color.c_str(), mNick.c_str()); + + if (mStatus != 255 && actorSpriteManager) + { + Being *being = actorSpriteManager->findBeingByName( + mNick, Being::PLAYER); + if (being) + being->setState(mStatus); + } + + if (mLevel > 0) + mText += strprintf("%d", mLevel); + + if (mGender == GENDER_FEMALE) + mText += "\u2640"; + else if (mGender == GENDER_MALE) + mText += "\u2642"; + + if (mStatus > 0 && mStatus != 255) + { + if (mStatus & Being::FLAG_SHOP) + mText += "$"; + if (mStatus & Being::FLAG_AWAY) + { + // TRANSLATORS: this away status writed in player nick + mText += _("A"); + } + if (mStatus & Being::FLAG_INACTIVE) + { + // TRANSLATORS: this inactive status writed in player nick + mText += _("I"); + } + } + + if (mVersion > 0) + mText += strprintf(" - %d", mVersion); + + mText += strprintf("@@"); +} diff --git a/src/gui/whoisonline.h b/src/gui/whoisonline.h index ade391d5a..dad51e857 100644 --- a/src/gui/whoisonline.h +++ b/src/gui/whoisonline.h @@ -42,6 +42,54 @@ class ScrollArea; struct SDL_Thread; +class OnlinePlayer +{ + public: + OnlinePlayer(std::string nick, unsigned char status, + char level, unsigned char gender, char version) : + mNick(nick), + mText(""), + mStatus(status), + mLevel(level), + mVersion(version), + mGender(gender) + { + } + + const std::string getNick() const + { return mNick; } + + unsigned char getStaus() const + { return mStatus; } + + char getVersion() const + { return mVersion; } + + char getLevel() const + { return mLevel; } + + const std::string getText() const + { return mText; } + + void setText(std::string str); + + void setLevel(char level) + { mLevel = level; } + + private: + std::string mNick; + + std::string mText; + + unsigned char mStatus; + + char mLevel; + + char mVersion; + + unsigned char mGender; +}; + /** * Update progress window GUI * @@ -52,7 +100,7 @@ class WhoIsOnline : public Window, public gcn::ActionListener, public ConfigListener { - public: +public: /** * Constructor. */ @@ -68,7 +116,7 @@ class WhoIsOnline : public Window, */ void loadWebList(); - void loadList(std::vector<std::string> &list); + void loadList(std::vector<OnlinePlayer*> &list); void handleLink(const std::string& link, gcn::MouseEvent *event); @@ -78,9 +126,12 @@ class WhoIsOnline : public Window, void widgetResized(const gcn::Event &event); - std::set<std::string> &getOnlinePlayers() + const std::set<OnlinePlayer*> &getOnlinePlayers() { return mOnlinePlayers; } + const std::set<std::string> &getOnlineNicks() + { return mOnlineNicks; } + void setAllowUpdate(bool n) { mAllowUpdate = n; } @@ -109,10 +160,10 @@ private: const std::string prepareNick(std::string nick, int level, std::string color) const; - void updateWindow(std::vector<std::string> &friends, - std::vector<std::string> &neutral, - std::vector<std::string> &disregard, - std::vector<std::string> enemy, + void updateWindow(std::vector<OnlinePlayer*> &friends, + std::vector<OnlinePlayer*> &neutral, + std::vector<OnlinePlayer*> &disregard, + std::vector<OnlinePlayer*> enemy, int numOnline); enum DownloadStatus @@ -143,7 +194,8 @@ private: BrowserBox *mBrowserBox; ScrollArea *mScrollArea; time_t mUpdateTimer; - std::set<std::string> mOnlinePlayers; + std::set<OnlinePlayer*> mOnlinePlayers; + std::set<std::string> mOnlineNicks; gcn::Button *mUpdateButton; bool mAllowUpdate; diff --git a/src/gui/widgets/browserbox.h b/src/gui/widgets/browserbox.h index ab3049c0b..d82ebd758 100644 --- a/src/gui/widgets/browserbox.h +++ b/src/gui/widgets/browserbox.h @@ -187,7 +187,7 @@ class BrowserBox : public gcn::Widget, TextRows &getRows() { return mTextRows; } - bool hasRows() + bool hasRows() const { return !mTextRows.empty(); } void setAlwaysUpdate(bool n) diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h index aed46bb55..560e46377 100644 --- a/src/gui/widgets/button.h +++ b/src/gui/widgets/button.h @@ -70,16 +70,16 @@ class Button : public gcn::Button, public gcn::WidgetListener void setDescription(std::string text) { mDescription = text; } - std::string getDescription() + std::string getDescription() const { return mDescription; } - unsigned getClickCount() + unsigned getClickCount() const { return mClickCount; } void setTag(int tag) { mTag = tag; } - int getTag() + int getTag() const { return mTag; } void widgetResized(const gcn::Event &event); diff --git a/src/gui/widgets/channeltab.h b/src/gui/widgets/channeltab.h index 4b56d2e05..39702a696 100644 --- a/src/gui/widgets/channeltab.h +++ b/src/gui/widgets/channeltab.h @@ -34,7 +34,8 @@ class ChannelTab : public ChatTab { public: - Channel *getChannel() const { return mChannel; } + Channel *getChannel() const + { return mChannel; } void showHelp(); diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp index aea367482..6d5dfc9dd 100644 --- a/src/gui/widgets/chattab.cpp +++ b/src/gui/widgets/chattab.cpp @@ -224,9 +224,17 @@ void ChatTab::chatLog(std::string line, Own own, { struct tm *timeInfo; timeInfo = localtime(&t); - line = strprintf("%s[%02d:%02d] %s%s", lineColor.c_str(), - timeInfo->tm_hour, timeInfo->tm_min, tmp.nick.c_str(), - tmp.text.c_str()); + if (timeInfo) + { + line = strprintf("%s[%02d:%02d] %s%s", lineColor.c_str(), + timeInfo->tm_hour, timeInfo->tm_min, tmp.nick.c_str(), + tmp.text.c_str()); + } + else + { + line = strprintf("%s %s%s", lineColor.c_str(), + tmp.nick.c_str(), tmp.text.c_str()); + } } else { diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h index ddf10bf5e..912305a63 100644 --- a/src/gui/widgets/chattab.h +++ b/src/gui/widgets/chattab.h @@ -137,24 +137,24 @@ class ChatTab : public Tab std::list<std::string> &getRows() { return mTextOutput->getRows(); } - bool hasRows() + bool hasRows() const { return mTextOutput->hasRows(); } void loadFromLogFile(std::string name); - bool getAllowHighlight() + bool getAllowHighlight() const { return mAllowHightlight; } void setAllowHighlight(bool n) { mAllowHightlight = n; } - bool getRemoveNames() + bool getRemoveNames() const { return mRemoveNames; } void setRemoveNames(bool n) { mRemoveNames = n; } - bool getNoAway() + bool getNoAway() const { return mNoAway; } void setNoAway(bool n) diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp index beb232fb2..b40558c78 100644 --- a/src/gui/widgets/desktop.cpp +++ b/src/gui/widgets/desktop.cpp @@ -48,10 +48,14 @@ Desktop::Desktop() : std::string appName = branding.getValue("appName", std::string("")); if (appName.empty()) + { mVersionLabel = new Label(FULL_VERSION); + } else - mVersionLabel = new Label(strprintf("%s (Mana %s)", appName.c_str(), - FULL_VERSION)); + { + mVersionLabel = new Label(strprintf("%s (%s)", FULL_VERSION, + appName.c_str())); + } mVersionLabel->setBackgroundColor( Theme::getThemeColor(Theme::BACKGROUND, 128)); diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp index e8d7bb7e3..794357275 100644 --- a/src/gui/widgets/emoteshortcutcontainer.cpp +++ b/src/gui/widgets/emoteshortcutcontainer.cpp @@ -43,7 +43,7 @@ #include "debug.h" -static const int MAX_ITEMS = 44; +static const int MAX_ITEMS = 48; EmoteShortcutContainer::EmoteShortcutContainer(): ShortcutContainer(), diff --git a/src/gui/widgets/guildchattab.h b/src/gui/widgets/guildchattab.h index bebdaa1f3..be6f4d034 100644 --- a/src/gui/widgets/guildchattab.h +++ b/src/gui/widgets/guildchattab.h @@ -41,7 +41,8 @@ class GuildChatTab : public ChatTab void saveToLogFile(std::string &msg); - int getType() const { return ChatTab::TAB_GUILD; } + int getType() const + { return ChatTab::TAB_GUILD; } protected: void handleInput(const std::string &msg); diff --git a/src/gui/widgets/icon.h b/src/gui/widgets/icon.h index 6f05da3f7..98fee314a 100644 --- a/src/gui/widgets/icon.h +++ b/src/gui/widgets/icon.h @@ -48,7 +48,8 @@ class Icon : public gcn::Widget /** * Gets the current Image. */ - Image *getImage() const { return mImage; } + Image *getImage() const + { return mImage; } /** * Sets the image to display. diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h index 02fed43b5..046d09b59 100644 --- a/src/gui/widgets/layout.h +++ b/src/gui/widgets/layout.h @@ -266,10 +266,10 @@ class LayoutCell void setType(int t) { mType = t; } - int getWidth() + int getWidth() const { return mExtent[0]; } - int getHeight() + int getHeight() const { return mExtent[1]; } void setWidth(int w) diff --git a/src/gui/widgets/popup.h b/src/gui/widgets/popup.h index 8ff21149a..5572abd03 100644 --- a/src/gui/widgets/popup.h +++ b/src/gui/widgets/popup.h @@ -94,28 +94,32 @@ class Popup : public Container, public gcn::MouseListener, */ void setMinWidth(int width); - int getMinWidth() const { return mMinWidth; } + int getMinWidth() const + { return mMinWidth; } /** * Sets the minimum height of the popup. */ void setMinHeight(int height); - int getMinHeight() const { return mMinHeight; } + int getMinHeight() const + { return mMinHeight; } /** * Sets the maximum width of the popup. */ void setMaxWidth(int width); - int getMaxWidth() const { return mMaxWidth; } + int getMaxWidth() const + { return mMaxWidth; } /** * Sets the minimum height of the popup. */ void setMaxHeight(int height); - int getMaxHeight() const { return mMaxHeight; } + int getMaxHeight() const + { return mMaxHeight; } /** * Gets the padding of the popup. The padding is the distance between @@ -124,9 +128,11 @@ class Popup : public Container, public gcn::MouseListener, * @return The padding of the popup. * @see setPadding */ - int getPadding() const { return mPadding; } + int getPadding() const + { return mPadding; } - void setPadding(int padding) { mPadding = padding; } + void setPadding(int padding) + { mPadding = padding; } /** * Sets the name of the popup. This is only useful for debug purposes. diff --git a/src/gui/widgets/progressbar.h b/src/gui/widgets/progressbar.h index 163310245..603df6157 100644 --- a/src/gui/widgets/progressbar.h +++ b/src/gui/widgets/progressbar.h @@ -73,7 +73,8 @@ class ProgressBar : public gcn::Widget, public gcn::WidgetListener /** * Returns the current progress. */ - float getProgress() const { return mProgress; } + float getProgress() const + { return mProgress; } /** * Change the ProgressPalette for this ProgressBar to follow or -1 to @@ -89,7 +90,8 @@ class ProgressBar : public gcn::Widget, public gcn::WidgetListener /** * Returns the color of the progress bar. */ - const gcn::Color &getColor() const { return mColor; } + const gcn::Color &getColor() const + { return mColor; } /** * Sets the text shown on the progress bar. diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h index 86902b5c9..582033071 100644 --- a/src/gui/widgets/scrollarea.h +++ b/src/gui/widgets/scrollarea.h @@ -89,7 +89,8 @@ class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener /** * Returns whether the widget draws its background or not. */ - bool isOpaque() const { return mOpaque; } + bool isOpaque() const + { return mOpaque; } /** * Called when the mouse moves in the widget area. diff --git a/src/gui/widgets/setupitem.cpp b/src/gui/widgets/setupitem.cpp index 92ff625c2..059b05ba2 100644 --- a/src/gui/widgets/setupitem.cpp +++ b/src/gui/widgets/setupitem.cpp @@ -192,7 +192,7 @@ void SetupItemCheckBox::createControls() load(); mCheckBox = new CheckBox(mText, mValue != "0", mParent, mEventName); mWidget = mCheckBox; - mParent->getContainer()->add(mWidget); + mParent->getContainer()->add1(mWidget); mParent->addControl(this); mParent->addActionListener(this); mWidget->addActionListener(this); @@ -275,7 +275,7 @@ void SetupItemTextField::createControls() mHorizont->add(mTextField); mHorizont->add(mButton); - mParent->getContainer()->add(mHorizont, true, 4); + mParent->getContainer()->add2(mHorizont, true, 4); mParent->addControl(this); mParent->addControl(this, mEventName + "_EDIT"); mParent->addControl(this, mEventName + "_EDIT_OK"); @@ -398,7 +398,7 @@ void SetupItemIntTextField::createControls() mHorizont->add(mTextField); mHorizont->add(mButton); - mParent->getContainer()->add(mHorizont, true, 4); + mParent->getContainer()->add2(mHorizont, true, 4); mParent->addControl(this); mParent->addControl(this, mEventName + "_EDIT"); mParent->addControl(this, mEventName + "_EDIT_OK"); @@ -486,7 +486,7 @@ void SetupItemLabel::createControls() } mWidget = mLabel; - mParent->getContainer()->add(mWidget); + mParent->getContainer()->add1(mWidget); mParent->addControl(this); mParent->addActionListener(this); mWidget->addActionListener(this); @@ -568,7 +568,7 @@ void SetupItemDropDown::createControls() mHorizont->add(mLabel); mHorizont->add(mDropDown); - mParent->getContainer()->add(mHorizont, true, 4); + mParent->getContainer()->add2(mHorizont, true, 4); mParent->addControl(this); mParent->addActionListener(this); mWidget->addActionListener(this); diff --git a/src/gui/widgets/setupitem.h b/src/gui/widgets/setupitem.h index eb2680ede..71856d6e2 100644 --- a/src/gui/widgets/setupitem.h +++ b/src/gui/widgets/setupitem.h @@ -75,7 +75,7 @@ class SetupItem : public gcn::ActionListener void setWidget(gcn::Widget *widget) { mWidget = widget; } - gcn::Widget *getWidget() + gcn::Widget *getWidget() const { return mWidget; } Configuration *getConfig(); @@ -93,7 +93,7 @@ class SetupItem : public gcn::ActionListener virtual void externalUpdated(std::string eventName); // virtual int add(ContainerPlacer &place, int x, int y, int width); - bool isMainConfig() + bool isMainConfig() const { return mMainConfig; } protected: diff --git a/src/gui/widgets/setuptabscroll.h b/src/gui/widgets/setuptabscroll.h index 4ad1f464b..d471ecfbc 100644 --- a/src/gui/widgets/setuptabscroll.h +++ b/src/gui/widgets/setuptabscroll.h @@ -43,7 +43,7 @@ class SetupTabScroll : public SetupTab void addControl(SetupItem *widget, std::string event); - VertContainer *getContainer() + VertContainer *getContainer() const { return mContainer; } virtual void apply(); diff --git a/src/gui/widgets/shoplistbox.h b/src/gui/widgets/shoplistbox.h index 9b416d3a3..694fdb92e 100644 --- a/src/gui/widgets/shoplistbox.h +++ b/src/gui/widgets/shoplistbox.h @@ -56,7 +56,8 @@ class ShopListBox : public ListBox /** * Returns the height of a row. */ - unsigned int getRowHeight() const { return mRowHeight; } + unsigned int getRowHeight() const + { return mRowHeight; } /** * gives information about the current player's money diff --git a/src/gui/widgets/tab.h b/src/gui/widgets/tab.h index 40b46ede5..829689543 100644 --- a/src/gui/widgets/tab.h +++ b/src/gui/widgets/tab.h @@ -61,7 +61,7 @@ class Tab : public gcn::Tab, public gcn::WidgetListener */ void setFlash(int flash); - int getFlash() + int getFlash() const { return mFlash; } void widgetResized(const gcn::Event &event); @@ -70,7 +70,7 @@ class Tab : public gcn::Tab, public gcn::WidgetListener void setLabelFont(gcn::Font *font); - gcn::Label *getLabel() + gcn::Label *getLabel() const { return mLabel; } protected: diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index b202dfc9d..cceaf56b7 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -136,13 +136,13 @@ class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener void setRightMargin(int n) { mRightMargin = n; } - int getRightMargin() + int getRightMargin() const { return mRightMargin; } void setFollowDownScroll(bool n) { mFollowDownScroll = n; } - bool getFollowDownScroll() + bool getFollowDownScroll() const { return mFollowDownScroll; } void fixSize() diff --git a/src/gui/widgets/textbox.h b/src/gui/widgets/textbox.h index 6d2467b38..a052247c4 100644 --- a/src/gui/widgets/textbox.h +++ b/src/gui/widgets/textbox.h @@ -59,7 +59,8 @@ class TextBox : public gcn::TextBox */ inline void draw(gcn::Graphics *graphics) { - setForegroundColor(*mTextColor); + if (mTextColor) + setForegroundColor(*mTextColor); gcn::TextBox::draw(graphics); } diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 03fdb5378..4dba2eb57 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -183,7 +183,7 @@ int TextField::getValue() const if (value < mMinimum) return mMinimum; - if (value > mMaximum) + if (value > (signed)mMaximum) return mMaximum; return value; @@ -195,29 +195,43 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) if (val >= 32) { - int l; - if (val < 128) - l = 1; // 0xxxxxxx - else if (val < 0x800) - l = 2; // 110xxxxx 10xxxxxx - else if (val < 0x10000) - l = 3; // 1110xxxx 10xxxxxx 10xxxxxx - else - l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - - char buf[4]; - for (int i = 0; i < l; ++i) + if (mNumeric) { - buf[i] = static_cast<char>(val >> (6 * (l - i - 1))); - if (i > 0) - buf[i] = static_cast<char>((buf[i] & 63) | 128); + if ((val >= '0' && val <= '9') || (val == '-' && !mCaretPosition)) + { + char buf[2]; + buf[0] = val; + buf[1] = 0; + mText.insert(mCaretPosition, std::string(buf)); + mCaretPosition += 1; + } } + else if (!mMaximum || mText.size() < mMaximum) + { + int l; + if (val < 128) + l = 1; // 0xxxxxxx + else if (val < 0x800) + l = 2; // 110xxxxx 10xxxxxx + else if (val < 0x10000) + l = 3; // 1110xxxx 10xxxxxx 10xxxxxx + else + l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + + char buf[4]; + for (int i = 0; i < l; ++i) + { + buf[i] = static_cast<char>(val >> (6 * (l - i - 1))); + if (i > 0) + buf[i] = static_cast<char>((buf[i] & 63) | 128); + } - if (l > 1) - buf[0] |= static_cast<char>(255 << (8 - l)); + if (l > 1) + buf[0] |= static_cast<char>(255 << (8 - l)); - mText.insert(mCaretPosition, std::string(buf, buf + l)); - mCaretPosition += l; + mText.insert(mCaretPosition, std::string(buf, buf + l)); + mCaretPosition += l; + } } /* In UTF-8, 10xxxxxx is only used for inner parts of characters. So skip diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h index bc1123f19..fef606526 100644 --- a/src/gui/widgets/textfield.h +++ b/src/gui/widgets/textfield.h @@ -114,7 +114,7 @@ class TextField : public gcn::TextField static ImageRect skin; bool mNumeric; int mMinimum; - int mMaximum; + unsigned mMaximum; bool mLoseFocusOnTab; int mLastEventPaste; }; diff --git a/src/gui/widgets/vertcontainer.cpp b/src/gui/widgets/vertcontainer.cpp index 305343d1a..0eb59c8f9 100644 --- a/src/gui/widgets/vertcontainer.cpp +++ b/src/gui/widgets/vertcontainer.cpp @@ -35,12 +35,12 @@ VertContainer::VertContainer(int verticalItemSize, bool resizable, addWidgetListener(this); } -void VertContainer::add(gcn::Widget *widget, int spacing) +void VertContainer::add1(gcn::Widget *widget, int spacing) { - add(widget, mResizable, spacing); + add2(widget, mResizable, spacing); } -void VertContainer::add(gcn::Widget *widget, bool resizable, int spacing) +void VertContainer::add2(gcn::Widget *widget, bool resizable, int spacing) { if (!widget) return; @@ -70,6 +70,7 @@ void VertContainer::clear() mCount = 0; mNextY = 0; + mResizableWidgets.clear(); } void VertContainer::widgetResized(const gcn::Event &event A_UNUSED) diff --git a/src/gui/widgets/vertcontainer.h b/src/gui/widgets/vertcontainer.h index 6e1305a06..b4e43d31d 100644 --- a/src/gui/widgets/vertcontainer.h +++ b/src/gui/widgets/vertcontainer.h @@ -39,10 +39,10 @@ class VertContainer : public Container, public gcn::WidgetListener VertContainer(int verticalItemSize, bool resizable = true, int leftSpacing = 0); - virtual void add(gcn::Widget *widget, bool resizable, - int spacing = -1); + virtual void add2(gcn::Widget *widget, bool resizable, + int spacing = -1); - virtual void add(gcn::Widget *widget, int spacing = -1); + virtual void add1(gcn::Widget *widget, int spacing = -1); virtual void clear(); diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 3858b0d81..6e6918694 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -433,7 +433,7 @@ void Window::setVisible(bool visible, bool forceSticky) // Check if the window is off screen... if (visible) - checkIfIsOffScreen(); + ensureOnScreen(); if (isStickyButtonLock()) gcn::Window::setVisible(visible); @@ -713,7 +713,7 @@ void Window::loadWindowState() } // Check if the window is off screen... - checkIfIsOffScreen(); + ensureOnScreen(); if (viewport) { @@ -848,6 +848,22 @@ void Window::resetToDefaultSize() saveWindowState(); } +void Window::adjustPositionAfterResize(int oldScreenWidth, int oldScreenHeight) +{ + gcn::Rectangle dimension = getDimension(); + + // If window was aligned to the right or bottom, keep it there + const int rightMargin = oldScreenWidth - (getX() + getWidth()); + const int bottomMargin = oldScreenHeight - (getY() + getHeight()); + if (getX() > 0 && getX() > rightMargin) + dimension.x = mainGraphics->mWidth - rightMargin - getWidth(); + if (getY() > 0 && getY() > bottomMargin) + dimension.y = mainGraphics->mHeight - bottomMargin - getHeight(); + + setDimension(dimension); + ensureOnScreen(); +} + int Window::getResizeHandles(gcn::MouseEvent &event) { if ((mStickyButtonLock && mSticky) || event.getX() < 0 || event.getY() < 0) @@ -972,57 +988,27 @@ void Window::centerHorisontally() setLocationHorisontallyRelativeTo(getParent()); } -void Window::checkIfIsOffScreen(bool partially, bool entirely) +void Window::ensureOnScreen() { - // Move the window onto screen if it has become off screen - // For instance, because of resolution change... - - // First of all, don't deal when a window hasn't got - // any size initialized yet... + // Skip when a window hasn't got any size initialized yet if (getWidth() == 0 && getHeight() == 0) return; - // Made partially the default behaviour - if (!partially && !entirely) - partially = true; - - // Keep guichan window inside screen (supports resizing any side) - - gcn::Rectangle winDimension = getDimension(); - - if (winDimension.x < 0) - { - winDimension.width += winDimension.x; - winDimension.x = 0; - } - if (winDimension.y < 0) - { - winDimension.height += winDimension.y; - winDimension.y = 0; - } - - // Look if the window is partially off-screen limits... - if (partially) - { - if (winDimension.x + winDimension.width > mainGraphics->mWidth) - winDimension.x = mainGraphics->mWidth - winDimension.width; - - if (winDimension.y + winDimension.height > mainGraphics->mHeight) - winDimension.y = mainGraphics->mHeight - winDimension.height; + gcn::Rectangle dimension = getDimension(); - setDimension(winDimension); - return; - } + // Check the left and bottom screen boundaries + if (dimension.x + dimension.width > mainGraphics->mWidth) + dimension.x = mainGraphics->mWidth - dimension.width; + if (dimension.y + dimension.height > mainGraphics->mHeight) + dimension.y = mainGraphics->mHeight - dimension.height; - if (entirely) - { - if (winDimension.x > mainGraphics->mWidth) - winDimension.x = mainGraphics->mWidth - winDimension.width; + // But never allow the windows to disappear in to the right and top + if (dimension.x < 0) + dimension.x = 0; + if (dimension.y < 0) + dimension.y = 0; - if (winDimension.y > mainGraphics->mHeight) - winDimension.y = mainGraphics->mHeight - winDimension.height; - } - setDimension(winDimension); + setDimension(dimension); } gcn::Rectangle Window::getWindowArea() diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h index 65dbf196b..6fa47dedc 100644 --- a/src/gui/widgets/window.h +++ b/src/gui/widgets/window.h @@ -329,6 +329,13 @@ class Window : public gcn::Window, gcn::WidgetListener virtual void resetToDefaultSize(); /** + * Adjusts the window position after the application window has been + * resized. + */ + void adjustPositionAfterResize(int oldScreenWidth, + int oldScreenHeight); + + /** * Gets the layout handler for this window. */ Layout &getLayout(); @@ -406,11 +413,11 @@ class Window : public gcn::Window, gcn::WidgetListener }; /** - * Check if the window is off-screen and then move it to be visible - * again. This is internally used by loadWindowState - * and setVisible(true) members. + * Ensures the window is on the screen, moving it if necessary. This is + * used by loadWindowState and setVisible(true), and when the screen + * is resized. */ - void checkIfIsOffScreen(bool partially = true, bool entirely = true); + void ensureOnScreen(); /** * Determines if the mouse is in a resize area and returns appropriate diff --git a/src/gui/widgets/windowcontainer.cpp b/src/gui/widgets/windowcontainer.cpp index 43aaea8a4..9e698ffa6 100644 --- a/src/gui/widgets/windowcontainer.cpp +++ b/src/gui/widgets/windowcontainer.cpp @@ -22,6 +22,8 @@ #include "gui/widgets/windowcontainer.h" +#include "gui/widgets/window.h" + #include "utils/dtor.h" #include "debug.h" @@ -41,3 +43,13 @@ void WindowContainer::scheduleDelete(gcn::Widget *widget) if (widget) mDeathList.push_back(widget); } + +void WindowContainer::adjustAfterResize(int oldScreenWidth, + int oldScreenHeight) +{ + for (WidgetListIterator i = mWidgets.begin(); i != mWidgets.end(); ++i) + { + if (Window *window = dynamic_cast<Window*>(*i)) + window->adjustPositionAfterResize(oldScreenWidth, oldScreenHeight); + } +} diff --git a/src/gui/widgets/windowcontainer.h b/src/gui/widgets/windowcontainer.h index 00ef04c19..1cec11861 100644 --- a/src/gui/widgets/windowcontainer.h +++ b/src/gui/widgets/windowcontainer.h @@ -48,6 +48,12 @@ class WindowContainer : public Container */ void scheduleDelete(gcn::Widget *widget); + /** + * Ensures that all visible windows are on the screen after the screen + * has been resized. + */ + void adjustAfterResize(int oldScreenWidth, int oldScreenHeight); + private: /** * List of widgets that are scheduled to be deleted. diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp index e954340f8..138090075 100644 --- a/src/gui/windowmenu.cpp +++ b/src/gui/windowmenu.cpp @@ -299,7 +299,7 @@ void WindowMenu::mouseMoved(gcn::MouseEvent &event) if (key != KeyboardConfig::KEY_NO_VALUE) { mTextPopup->show(x + getX(), y + getY(), btn->getDescription(), - "Key: " + keyboard.getKeyValueString(key)); + strprintf(_("Key: %s"), keyboard.getKeyValueString(key).c_str())); } else { |