diff options
author | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-11-21 21:07:59 +0100 |
---|---|---|
committer | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2012-01-10 20:31:56 +0100 |
commit | 98be39a094cc20f513da1847c553513682e4eeae (patch) | |
tree | bf3ac3591cf80c14e484328d50d7b553d18244e2 | |
parent | 683da50e37fbbb2e3f70a4421a06dabd9bb912d8 (diff) | |
download | mana-98be39a094cc20f513da1847c553513682e4eeae.tar.gz mana-98be39a094cc20f513da1847c553513682e4eeae.tar.bz2 mana-98be39a094cc20f513da1847c553513682e4eeae.tar.xz mana-98be39a094cc20f513da1847c553513682e4eeae.zip |
Made addition of custom servers be done in a separate window.
Now the first window the user can see is a list of servers
which can double-clicked, making it all less cluttered.
This commit also makes custom servers able to now have
their own titles and their own description,
just as the official ones.
I also fixed the add entry button being registered twice
to the action listener, and the fact that the description
wasn't updated properly at windows loading
and when adding/removing an entry.
Resolves: Mana-Mantis #237.
Reviewed-by: Ablu
-rw-r--r-- | mana.cbp | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/gui/customserverdialog.cpp | 194 | ||||
-rw-r--r-- | src/gui/customserverdialog.h | 96 | ||||
-rw-r--r-- | src/gui/serverdialog.cpp | 176 | ||||
-rw-r--r-- | src/gui/serverdialog.h | 31 |
6 files changed, 351 insertions, 150 deletions
@@ -165,6 +165,8 @@ <Unit filename="src\gui\confirmdialog.h" /> <Unit filename="src\gui\connectiondialog.cpp" /> <Unit filename="src\gui\connectiondialog.h" /> + <Unit filename="src\gui\customserverdialog.cpp" /> + <Unit filename="src\gui\customserverdialog.h" /> <Unit filename="src\gui\debugwindow.cpp" /> <Unit filename="src\gui\debugwindow.h" /> <Unit filename="src\gui\emotepopup.cpp" /> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f4f50eff..42279239 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -233,6 +233,8 @@ SET(SRCS gui/confirmdialog.h gui/connectiondialog.cpp gui/connectiondialog.h + gui/customserverdialog.cpp + gui/customserverdialog.h gui/debugwindow.cpp gui/debugwindow.h gui/emotepopup.cpp diff --git a/src/gui/customserverdialog.cpp b/src/gui/customserverdialog.cpp new file mode 100644 index 00000000..304665d6 --- /dev/null +++ b/src/gui/customserverdialog.cpp @@ -0,0 +1,194 @@ +/* + * The Mana Client + * Copyright (C) 2011 The Mana 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/>. + */ + +#include "gui/customserverdialog.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 "ManaServ"; + else + return "Unknown"; +} + +CustomServerDialog::CustomServerDialog(ServerDialog *parent): + Window(_("Add a custom Server"), true, static_cast<Window*>(parent)), + mServerDialog(parent) +{ + setWindowName("CustomServerDialog"); + + 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()); + + 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, 3).setPadding(3); + place(0, 1, serverAdressLabel); + place(1, 1, mServerAddressField, 3).setPadding(3); + place(0, 2, portLabel); + place(1, 2, mPortField, 3).setPadding(3); + place(0, 3, typeLabel); + place(3, 3, mTypeField, 1).setPadding(3); + place(0, 4, descriptionLabel); + place(1, 4, mDescriptionField, 3).setPadding(3); + place(3, 5, mOkButton); + place(2, 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 < 400) + { + width = 400; + 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(); + + setVisible(true); + + mNameField->requestFocus(); +} + +CustomServerDialog::~CustomServerDialog() +{ + delete mTypeListModel; +} + +void CustomServerDialog::logic() +{ + Window::logic(); +} + +void CustomServerDialog::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); + + ServerInfo serverInfo; + serverInfo.name = mNameField->getText(); + serverInfo.description = mDescriptionField->getText(); + serverInfo.hostname = mServerAddressField->getText(); + serverInfo.port = (short) atoi(mPortField->getText().c_str()); + switch (mTypeField->getSelected()) + { + case 0: + serverInfo.type = ServerInfo::TMWATHENA; + break; + case 1: + serverInfo.type = ServerInfo::MANASERV; + break; + default: + serverInfo.type = ServerInfo::UNKNOWN; + } + + // Tell the server has to be saved + serverInfo.save = true; + + //Add server + mServerDialog->saveCustomServers(serverInfo); + scheduleDelete(); + } + } + else if (event.getId() == "cancel") + { + scheduleDelete(); + } +} + +void CustomServerDialog::keyPressed(gcn::KeyEvent &keyEvent) +{ + gcn::Key key = keyEvent.getKey(); + + if (key.getValue() == Key::ESCAPE) + { + scheduleDelete(); + } + else if (key.getValue() == Key::ENTER) + { + action(gcn::ActionEvent(NULL, mOkButton->getActionEventId())); + } +} diff --git a/src/gui/customserverdialog.h b/src/gui/customserverdialog.h new file mode 100644 index 00000000..af19d9c7 --- /dev/null +++ b/src/gui/customserverdialog.h @@ -0,0 +1,96 @@ +/* + * The Mana Client + * Copyright (C) 2011 The Mana 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 CUSTOMSERVERDIALOG_H +#define CUSTOMSERVERDIALOG_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() { return 2; } + + /** + * Used to get an element from the list + */ + std::string getElementAt(int elementIndex); +}; + +/** + * The custom server addition dialog. + * + * \ingroup Interface + */ +class CustomServerDialog : public Window, + public gcn::ActionListener, + public gcn::KeyListener +{ + public: + CustomServerDialog(ServerDialog *parent); + + ~CustomServerDialog(); + + /** + * 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; +}; + +#endif // CUSTOMSERVERDIALOG_H diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 2994cbaf..d580d4d3 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -28,6 +28,7 @@ #include "log.h" #include "main.h" +#include "gui/customserverdialog.h" #include "gui/okdialog.h" #include "gui/sdlinput.h" @@ -115,16 +116,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 "ManaServ"; - else - return "Unknown"; -} - class ServersListBox : public ListBox { public: @@ -203,12 +194,6 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): { setWindowName("ServerDialog"); - Label *serverLabel = new Label(_("Server:")); - Label *portLabel = new Label(_("Port:")); - Label *typeLabel = new Label(_("Server type:")); - mServerNameField = new TextField(mServerInfo->hostname); - mPortField = new TextField(toString(mServerInfo->port)); - loadCustomServers(); mServersListModel = new ServersListModel(&mServers, this); @@ -218,11 +203,6 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): ScrollArea *usedScroll = new ScrollArea(mServersList); usedScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - mTypeListModel = new TypeListModel(); - mTypeField = new DropDown(mTypeListModel); - mTypeField->setSelected((serverInfo->type == ServerInfo::MANASERV) ? - 1 : 0); - mDescription = new Label(std::string()); mQuitButton = new Button(_("Quit"), "quit", this); @@ -230,27 +210,16 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): mManualEntryButton = new Button(_("Custom Server"), "addEntry", this); mDeleteButton = new Button(_("Delete"), "remove", this); - mServerNameField->setActionEventId("connect"); - mPortField->setActionEventId("connect"); - - mServerNameField->addActionListener(this); - mPortField->addActionListener(this); - mManualEntryButton->addActionListener(this); + mServersList->setActionEventId("connect"); mServersList->addSelectionListener(this); usedScroll->setVerticalScrollAmount(0); - place(0, 0, serverLabel); - place(1, 0, mServerNameField, 4).setPadding(3); - place(0, 1, portLabel); - place(1, 1, mPortField, 4).setPadding(3); - place(0, 2, typeLabel); - place(1, 2, mTypeField, 4).setPadding(3); - place(0, 3, usedScroll, 5, 5).setPadding(3); - place(0, 8, mDescription, 5); - place(0, 9, mManualEntryButton); - place(1, 9, mDeleteButton); - place(3, 9, mQuitButton); - place(4, 9, mConnectButton); + place(0, 0, usedScroll, 5, 5).setPadding(3); + place(0, 5, mDescription, 5); + place(0, 6, mManualEntryButton); + place(1, 6, mDeleteButton); + place(3, 6, mQuitButton); + place(4, 6, mConnectButton); // Make sure the list has enough height getLayout().setRowHeight(3, 80); @@ -276,21 +245,11 @@ 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(); - } + mServersList->requestFocus(); downloadServerList(); } @@ -304,7 +263,6 @@ ServerDialog::~ServerDialog() mDownload = 0; } delete mServersListModel; - delete mTypeListModel; } void ServerDialog::action(const gcn::ActionEvent &event) @@ -312,16 +270,17 @@ void ServerDialog::action(const gcn::ActionEvent &event) if (event.getId() == "ok") { // Give focus back to the server dialog. - mServerNameField->requestFocus(); + mServersList->requestFocus(); } else if (event.getId() == "connect") { + int index = mServersList->getSelected(); + // Check login - if (mServerNameField->getText().empty() - || mPortField->getText().empty()) + if (index < 0) { OkDialog *dlg = new OkDialog(_("Error"), - _("Please type both the address and the port of a server.")); + _("Please select a server.")); dlg->addActionListener(this); } else @@ -329,28 +288,19 @@ void ServerDialog::action(const gcn::ActionEvent &event) mDownload->cancel(); mQuitButton->setEnabled(false); mConnectButton->setEnabled(false); + mDeleteButton->setEnabled(false); + mManualEntryButton->setEnabled(false); - mServerInfo->hostname = mServerNameField->getText(); - mServerInfo->port = (short) atoi(mPortField->getText().c_str()); - switch (mTypeField->getSelected()) - { - case 0: - mServerInfo->type = ServerInfo::TMWATHENA; - break; - case 1: - mServerInfo->type = ServerInfo::MANASERV; - break; - default: - mServerInfo->type = ServerInfo::UNKNOWN; - } + const ServerInfo &serverInfo = mServersListModel->getServer(index); + mServerInfo->hostname = serverInfo.hostname; + mServerInfo->port = serverInfo.port; + mServerInfo->type = serverInfo.type; // Save the selected server mServerInfo->save = true; chatLogger->setServerName(mServerInfo->hostname); - saveCustomServers(*mServerInfo); - Client::setState(STATE_CONNECT_SERVER); } } @@ -361,7 +311,8 @@ void ServerDialog::action(const gcn::ActionEvent &event) } else if (event.getId() == "addEntry") { - setFieldsReadOnly(false); + // Add a custom server: It will delete itself using guichan logic. + new CustomServerDialog(this); } else if (event.getId() == "remove") { @@ -399,19 +350,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)); - switch (myServer.type) - { - case ServerInfo::TMWATHENA: - case ServerInfo::UNKNOWN: - mTypeField->setSelected(0); - break; - case ServerInfo::MANASERV: - mTypeField->setSelected(1); - break; - } - setFieldsReadOnly(true); mDeleteButton->setEnabled(myServer.save); } @@ -434,7 +372,7 @@ void ServerDialog::logic() { mDownloadStatus = DOWNLOADING_OVER; - mDescription->setCaption(std::string()); + mDescription->setCaption(mServers[0].description); } else if (mDownloadStatus == DOWNLOADING_IN_PROGRESS) { @@ -459,27 +397,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()); - mServerNameField->requestFocus(); - } - - mManualEntryButton->setEnabled(readOnly); - mDeleteButton->setEnabled(false); - mDescription->setVisible(readOnly); - - mServerNameField->setEnabled(!readOnly); - mPortField->setEnabled(!readOnly); - mTypeField->setEnabled(!readOnly); -} - void ServerDialog::downloadServerList() { // Try to load the configuration value for the onlineServerList @@ -575,17 +492,20 @@ void ServerDialog::loadServers() MutexLocker lock(&mMutex); // Add the server to the local list if it's not already present bool found = false; - for (unsigned int i = 0; i < mServers.size(); i++) + int i = 0; + for (ServerInfos::iterator it = mServers.begin(); it != mServers.end(); + ++it) { - if (mServers[i] == server) + if (*it == server) { // Use the name listed in the server list - mServers[i].name = server.name; - mServers[i].version = server.version; + (*it).name = server.name; + (*it).version = server.version; mServersListModel->setVersionString(i, version); found = true; break; } + ++i; } if (!found) @@ -598,16 +518,20 @@ 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 hostNameKey = "MostUsedServerName" + index; const std::string typeKey = "MostUsedServerType" + index; const std::string portKey = "MostUsedServerPort" + index; + const std::string descriptionKey = "MostUsedServerDescription" + index; ServerInfo server; - server.hostname = config.getValue(nameKey, ""); + server.name = config.getValue(nameKey, ""); + server.hostname = config.getValue(hostNameKey, ""); server.type = ServerInfo::parseType(config.getValue(typeKey, "")); const int defaultPort = defaultPortForServerType(server.type); server.port = (unsigned short) config.getValue(portKey, defaultPort); + server.description = config.getValue(descriptionKey, ""); // Stop on the first invalid server if (!server.isValid()) @@ -621,15 +545,16 @@ void ServerDialog::loadCustomServers() void ServerDialog::saveCustomServers(const ServerInfo ¤tServer) { + ServerInfos::iterator it, it_end = mServers.end(); + // 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) + for (it = mServers.begin(); it != it_end; ++it) { - if (*i == currentServer) + if (*it == currentServer) { - mServers.erase(i); + mServers.erase(it); break; } } @@ -638,29 +563,36 @@ void ServerDialog::saveCustomServers(const ServerInfo ¤tServer) int savedServerCount = 0; - for (unsigned i = 0; - i < mServers.size() && savedServerCount < MAX_SERVERLIST; ++i) + for (it = mServers.begin(), it_end = mServers.end(); + it != it_end && savedServerCount < MAX_SERVERLIST; ++it) { - const ServerInfo &server = mServers.at(i); + const ServerInfo &server = *it; // Only save servers that were loaded from settings if (!(server.save && server.isValid())) continue; const std::string index = toString(savedServerCount); - const std::string nameKey = "MostUsedServerName" + index; + const std::string nameKey = "MostUsedServerDescName" + index; + const std::string hostNameKey = "MostUsedServerName" + index; const std::string typeKey = "MostUsedServerType" + index; const std::string portKey = "MostUsedServerPort" + index; + const std::string descriptionKey = "MostUsedServerDescription" + index; - config.setValue(nameKey, toString(server.hostname)); + config.setValue(hostNameKey, toString(server.hostname)); config.setValue(typeKey, serverTypeToString(server.type)); config.setValue(portKey, toString(server.port)); + config.setValue(nameKey, server.name); + config.setValue(descriptionKey, server.description); ++savedServerCount; } // Insert an invalid entry at the end to make the loading stop there if (savedServerCount < MAX_SERVERLIST) config.setValue("MostUsedServerName" + toString(savedServerCount), ""); + + // Restore the correct description + mDescription->setCaption(mServers[0].description); } int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h index bf0a43d6..611f65e9 100644 --- a/src/gui/serverdialog.h +++ b/src/gui/serverdialog.h @@ -81,26 +81,6 @@ class ServersListModel : public gcn::ListModel }; /** - * Server Type List Model - */ -class TypeListModel : public gcn::ListModel -{ - public: - TypeListModel() {} - - /** - * Used to get number of line in the list - */ - int getNumberOfElements() { return 2; } - - /** - * Used to get an element from the list - */ - std::string getElementAt(int elementIndex); -}; - - -/** * The server choice dialog. * * \ingroup Interface @@ -135,6 +115,9 @@ class ServerDialog : public Window, friend class ServersListModel; MutexLocker lock() { return MutexLocker(&mMutex); } + friend class CustomServerDialog; + void saveCustomServers(const ServerInfo ¤tServer = ServerInfo()); + private: /** * Called to load a list of available server from an online xml file. @@ -143,15 +126,10 @@ class ServerDialog : public Window, void loadServers(); void loadCustomServers(); - void saveCustomServers(const ServerInfo ¤tServer = ServerInfo()); 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; @@ -161,9 +139,6 @@ class ServerDialog : public Window, ListBox *mServersList; ServersListModel *mServersListModel; - DropDown *mTypeField; - TypeListModel *mTypeListModel; - const std::string &mDir; enum ServerDialogDownloadStatus |