diff options
Diffstat (limited to 'src/gui')
41 files changed, 499 insertions, 305 deletions
diff --git a/src/gui/beingpopup.cpp b/src/gui/beingpopup.cpp index 7fd99371..33fdff44 100644 --- a/src/gui/beingpopup.cpp +++ b/src/gui/beingpopup.cpp @@ -27,7 +27,7 @@ #include "gui/gui.h" #include "gui/palette.h" -#include "gui/widgets/textbox.h" +#include "gui/widgets/label.h" #include "utils/gettext.h" #include "utils/stringutils.h" @@ -39,14 +39,14 @@ BeingPopup::BeingPopup(): Popup("BeingPopup") { // Being Name - mBeingName = new TextBox(); + mBeingName = new Label("A"); mBeingName->setFont(boldFont); mBeingName->setPosition(getPadding(), getPadding()); - const int fontHeight = getFont()->getHeight(); + const int fontHeight = mBeingName->getHeight() + getPadding(); // Being's party - mBeingParty = new TextBox(); + mBeingParty = new Label("A"); mBeingParty->setPosition(getPadding(), fontHeight); add(mBeingName); @@ -69,12 +69,15 @@ void BeingPopup::show(int x, int y, Player *p) if (!(p->getPartyName().empty())) { - mBeingName->setTextWrapped(p->getName(), 196); - mBeingParty->setTextWrapped(strprintf(_("Party: %s"), - p->getPartyName().c_str()), 196); + mBeingName->setCaption(p->getName()); + mBeingName->adjustSize(); - int minWidth = std::max(mBeingName->getMinWidth(), - mBeingParty->getMinWidth()); + mBeingParty->setCaption(strprintf(_("Party: %s"), + p->getPartyName().c_str())); + mBeingParty->adjustSize(); + + int minWidth = std::max(mBeingName->getWidth(), + mBeingParty->getWidth()); const int height = getFont()->getHeight(); diff --git a/src/gui/beingpopup.h b/src/gui/beingpopup.h index 078b84d9..71d9dd2a 100644 --- a/src/gui/beingpopup.h +++ b/src/gui/beingpopup.h @@ -23,10 +23,8 @@ #include "gui/widgets/popup.h" -#include <guichan/mouselistener.hpp> - +class Label; class Player; -class TextBox; /** * A popup that displays information about a being. @@ -52,8 +50,8 @@ class BeingPopup : public Popup // TODO: Add a version for monsters, NPCs, etc? private: - TextBox *mBeingName; - TextBox *mBeingParty; + Label *mBeingName; + Label *mBeingParty; static gcn::Color getColor(); }; diff --git a/src/gui/emotepopup.cpp b/src/gui/emotepopup.cpp index 2711161e..2161e04c 100644 --- a/src/gui/emotepopup.cpp +++ b/src/gui/emotepopup.cpp @@ -29,10 +29,11 @@ #include "localplayer.h" #include "log.h" +#include "gui/skin.h" + #include "resources/emotedb.h" #include "resources/image.h" #include "resources/iteminfo.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -56,8 +57,7 @@ EmotePopup::EmotePopup(): mEmotes.push_back(EmoteDB::getAnimation(i)); } - ResourceManager *resman = ResourceManager::getInstance(); - mSelectionImage = resman->getImage("graphics/gui/selection.png"); + mSelectionImage = SkinLoader::getImageFromTheme("selection.png"); if (!mSelectionImage) logger->error("Unable to load selection.png"); @@ -119,6 +119,8 @@ void EmotePopup::mousePressed(gcn::MouseEvent &event) void EmotePopup::mouseMoved(gcn::MouseEvent &event) { + Popup::mouseMoved(event); + mHoveredEmoteIndex = getIndexAt(event.getX(), event.getY()); } diff --git a/src/gui/emotepopup.h b/src/gui/emotepopup.h index de957925..62a3f24a 100644 --- a/src/gui/emotepopup.h +++ b/src/gui/emotepopup.h @@ -42,8 +42,7 @@ namespace gcn { * * \ingroup GUI */ -class EmotePopup : public Popup, - public gcn::MouseListener +class EmotePopup : public Popup { public: /** diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index e82a33b9..1e36523c 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -26,7 +26,6 @@ #include "gui/sdlinput.h" #include "gui/skin.h" #include "gui/truetypefont.h" -#include "gui/viewport.h" #include "gui/widgets/window.h" #include "gui/widgets/windowcontainer.h" @@ -95,6 +94,7 @@ Gui::Gui(Graphics *graphics): // Initialize top GUI widget WindowContainer *guiTop = new WindowContainer; + guiTop->setFocusable(true); guiTop->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(), graphics->getHeight())); guiTop->setOpaque(false); @@ -209,9 +209,8 @@ void Gui::setUseCustomCursor(bool customCursor) SDL_ShowCursor(SDL_DISABLE); // Load the mouse cursor - ResourceManager *resman = ResourceManager::getInstance(); - mMouseCursors = - resman->getImageSet("graphics/gui/mouse.png", 40, 40); + mMouseCursors = SkinLoader::getImageSetFromTheme("mouse.png", + 40, 40); if (!mMouseCursors) logger->error("Unable to load mouse cursors."); diff --git a/src/gui/gui.h b/src/gui/gui.h index 7bd76c4a..112abcee 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -107,6 +107,9 @@ class Gui : public gcn::Gui CURSOR_RESIZE_DOWN, CURSOR_RESIZE_DOWN_LEFT, CURSOR_RESIZE_DOWN_RIGHT, + CURSOR_FIGHT, + CURSOR_PICKUP, + CURSOR_TALK, CURSOR_TOTAL }; diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index c22a9c33..1d41449d 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -168,6 +168,8 @@ gcn::Color ItemPopup::getColor(ItemType type) void ItemPopup::mouseMoved(gcn::MouseEvent &event) { + Popup::mouseMoved(event); + // When the mouse moved on top of the popup, hide it setVisible(false); } diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h index 79aba523..67d1eb2f 100644 --- a/src/gui/itempopup.h +++ b/src/gui/itempopup.h @@ -34,8 +34,7 @@ class TextBox; /** * A popup that displays information about an item. */ -class ItemPopup : public Popup, - public gcn::MouseListener +class ItemPopup : public Popup { public: /** diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index f439420b..e9f76436 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -49,23 +49,17 @@ #define MAX_SERVERLIST 5 -ServerInfo::Type stringToServerType(const std::string &type) +static ServerInfo::Type stringToServerType(const std::string &type) { if (compareStrI(type, "eathena") == 0) - { return ServerInfo::EATHENA; - } else if (compareStrI(type, "manaserv") == 0) - { return ServerInfo::MANASERV; - } - else - { - return ServerInfo::UNKNOWN; - } + + return ServerInfo::UNKNOWN; } -std::string serverTypeToString(ServerInfo::Type type) +static std::string serverTypeToString(ServerInfo::Type type) { switch (type) { @@ -78,6 +72,18 @@ std::string serverTypeToString(ServerInfo::Type type) } } +static unsigned short defaultPortForServerType(ServerInfo::Type type) +{ + switch (type) + { + default: + case ServerInfo::EATHENA: + return 6901; + case ServerInfo::MANASERV: + return 9601; + } +} + ServersListModel::ServersListModel(ServerInfos *servers, ServerDialog *parent): mServers(servers), mParent(parent) @@ -138,33 +144,33 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): mServerNameField = new TextField(mServerInfo->hostname); mPortField = new TextField(toString(mServerInfo->port)); - ServerInfo currentServer; - // Add the most used servers from config if they are not in the online list - std::string currentConfig = ""; - for (int i = 0; i <= MAX_SERVERLIST; i++) + // Add the most used servers from config + for (int i = 0; i <= MAX_SERVERLIST; ++i) { - currentServer.clear(); - - currentConfig = "MostUsedServerName" + toString(i); - currentServer.hostname = config.getValue(currentConfig, ""); + const std::string index = toString(i); + const std::string nameKey = "MostUsedServerName" + index; + const std::string typeKey = "MostUsedServerType" + index; + const std::string portKey = "MostUsedServerPort" + index; - currentConfig = "MostUsedServerPort" + toString(i); - currentServer.port = (short) config.getValue(currentConfig, - DEFAULT_PORT); + ServerInfo server; + server.hostname = config.getValue(nameKey, ""); + server.type = stringToServerType(config.getValue(typeKey, "")); - currentConfig = "MostUsedServerType" + toString(i); - currentServer.type = stringToServerType(config - .getValue(currentConfig, "")); + const int defaultPort = defaultPortForServerType(server.type); + server.port = (unsigned short) config.getValue(portKey, defaultPort); - if (!currentServer.hostname.empty() && currentServer.port != 0) + if (server.isValid()) { - mServers.push_back(currentServer); + server.save = true; + mServers.push_back(server); } } mServersListModel = new ServersListModel(&mServers, this); mServersList = new ListBox(mServersListModel); + mServersList->addMouseListener(this); + ScrollArea *usedScroll = new ScrollArea(mServersList); usedScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); @@ -175,7 +181,8 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): mQuitButton = new Button(_("Quit"), "quit", this); mConnectButton = new Button(_("Connect"), "connect", this); - mManualEntryButton = new Button(_("Add Entry"), "addEntry", this); + mManualEntryButton = new Button(_("Custom Server"), "addEntry", this); + mDeleteButton = new Button(_("Delete"), "remove", this); mServerNameField->setActionEventId("connect"); mPortField->setActionEventId("connect"); @@ -184,20 +191,20 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): mPortField->addActionListener(this); mManualEntryButton->addActionListener(this); mServersList->addSelectionListener(this); - mServersList->setSelected(0); usedScroll->setVerticalScrollAmount(0); place(0, 0, serverLabel); - place(1, 0, mServerNameField, 3).setPadding(3); + place(1, 0, mServerNameField, 4).setPadding(3); place(0, 1, portLabel); - place(1, 1, mPortField, 3).setPadding(3); + place(1, 1, mPortField, 4).setPadding(3); place(0, 2, typeLabel); - place(1, 2, mTypeField, 3).setPadding(3); - place(0, 3, usedScroll, 4, 5).setPadding(3); - place(0, 8, mDescription, 4); + 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(2, 9, mQuitButton); - place(3, 9, mConnectButton); + place(1, 9, mDeleteButton); + place(3, 9, mQuitButton); + place(4, 9, mConnectButton); // Make sure the list has enough height getLayout().setRowHeight(3, 80); @@ -208,6 +215,7 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir): center(); setFieldsReadOnly(true); + mServersList->setSelected(0); // Do this after for the Delete button setVisible(true); if (mServerNameField->getText().empty()) @@ -247,7 +255,8 @@ void ServerDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "connect") { // Check login - if (mServerNameField->getText().empty() || mPortField->getText().empty()) + if (mServerNameField->getText().empty() + || mPortField->getText().empty()) { OkDialog *dlg = new OkDialog(_("Error"), _("Please type both the address and the port of a server.")); @@ -261,7 +270,6 @@ void ServerDialog::action(const gcn::ActionEvent &event) // First, look if the entry is a new one. ServerInfo currentServer; - ServerInfo tempServer; currentServer.hostname = mServerNameField->getText(); currentServer.port = (short) atoi(mPortField->getText().c_str()); switch (mTypeField->getSelected()) @@ -284,21 +292,27 @@ void ServerDialog::action(const gcn::ActionEvent &event) serverTypeToString(currentServer.type)); // now add the rest of the list... - std::string currentConfig = ""; int configCount = 1; - for (int i = 0; i < mServersListModel->getNumberOfElements(); i++) + for (int i = 0; i < mServersListModel->getNumberOfElements(); ++i) { - tempServer = mServersListModel->getServer(i); + const ServerInfo server = mServersListModel->getServer(i); + + // Only save servers that were loaded from settings + if (!server.save) + continue; // ensure, that our server will not be added twice - if (tempServer != currentServer) + if (server != currentServer) { - currentConfig = "MostUsedServerName" + toString(configCount); - config.setValue(currentConfig, toString(tempServer.hostname)); - currentConfig = "MostUsedServerPort" + toString(configCount); - config.setValue(currentConfig, toString(tempServer.port)); - currentConfig = "MostUsedServerType" + toString(configCount); - config.setValue(currentConfig, serverTypeToString(tempServer.type)); + const std::string index = toString(configCount); + const std::string nameKey = "MostUsedServerName" + index; + const std::string typeKey = "MostUsedServerType" + index; + const std::string portKey = "MostUsedServerPort" + index; + + config.setValue(nameKey, toString(server.hostname)); + config.setValue(typeKey, serverTypeToString(server.type)); + config.setValue(portKey, toString(server.port)); + configCount++; } @@ -321,6 +335,12 @@ void ServerDialog::action(const gcn::ActionEvent &event) { setFieldsReadOnly(false); } + else if (event.getId() == "remove") + { + int index = mServersList->getSelected(); + mServersList->setSelected(0); + mServersListModel->remove(index); + } } void ServerDialog::keyPressed(gcn::KeyEvent &keyEvent) @@ -337,11 +357,14 @@ void ServerDialog::keyPressed(gcn::KeyEvent &keyEvent) } } -void ServerDialog::valueChanged(const gcn::SelectionEvent &event) +void ServerDialog::valueChanged(const gcn::SelectionEvent &) { const int index = mServersList->getSelected(); if (index == -1) + { + mDeleteButton->setEnabled(false); return; + } // Update the server and post fields according to the new selection const ServerInfo myServer = mServersListModel->getServer(index); @@ -350,16 +373,27 @@ void ServerDialog::valueChanged(const gcn::SelectionEvent &event) mPortField->setText(toString(myServer.port)); switch (myServer.type) { - case ServerInfo::UNKNOWN: - mTypeField->setSelected(2); - break; case ServerInfo::EATHENA: + case ServerInfo::UNKNOWN: mTypeField->setSelected(0); break; case ServerInfo::MANASERV: mTypeField->setSelected(1); + break; } setFieldsReadOnly(true); + + mDeleteButton->setEnabled(myServer.save); +} + +void ServerDialog::mouseClicked(gcn::MouseEvent &mouseEvent) +{ + if (mouseEvent.getClickCount() == 2 && + mouseEvent.getSource() == mServersList) + { + action(gcn::ActionEvent(mConnectButton, + mConnectButton->getActionEventId())); + } } void ServerDialog::logic() @@ -391,39 +425,38 @@ void ServerDialog::logic() Window::logic(); } -void ServerDialog::setFieldsReadOnly(const bool readOnly) +void ServerDialog::setFieldsReadOnly(bool readOnly) { - if (readOnly) + if (!readOnly) { - mServerNameField->setEnabled(false); - mPortField->setEnabled(false); - mManualEntryButton->setVisible(true); - mDescription->setVisible(true); - } - else - { - mManualEntryButton->setVisible(false); - - mDescription->setVisible(false); mDescription->setCaption(std::string()); mServersList->setSelected(-1); mServerNameField->setText(std::string()); - mServerNameField->setEnabled(true); - - mPortField->setText(toString(DEFAULT_PORT)); - mPortField->setEnabled(true); + 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 - std::string listFile = config.getValue("onlineServerList", "void"); - // if there is no entry, try to load the file from the default updatehost - if (listFile == "void") + // Try to load the configuration value for the onlineServerList + std::string listFile = branding.getValue("onlineServerList", std::string()); + + if (listFile.empty()) + listFile = config.getValue("onlineServerList", std::string()); + + // Fall back to manasource.org when neither branding nor config set it + if (listFile.empty()) listFile = "http://manasource.org/serverlist.xml"; mDownload = new Net::Download(this, listFile, &downloadUpdate); @@ -433,65 +466,74 @@ void ServerDialog::downloadServerList() void ServerDialog::loadServers() { - ServerInfo currentServer; + XML::Document doc(mDir + "/serverlist.xml", false); + xmlNodePtr rootNode = doc.rootNode(); - xmlDocPtr doc = xmlReadFile((mDir + "/serverlist.xml").c_str(), NULL, 0); + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "serverlist")) + { + logger->log("Error loading server list!"); + return; + } - if (doc != NULL) + int version = XML::getProperty(rootNode, "version", 0); + if (version != 1) { - xmlNodePtr rootNode = xmlDocGetRootElement(doc); - int version = XML::getProperty(rootNode, "version", 3); + logger->log("Error: unsupported online server list version: %d", + version); + return; + } + + for_each_xml_child_node(serverNode, rootNode) + { + if (!xmlStrEqual(serverNode->name, BAD_CAST "server")) + continue; + + ServerInfo server; + + std::string type = XML::getProperty(serverNode, "type", "unknown"); - if (version != 1) + server.type = stringToServerType(type); + server.name = XML::getProperty(serverNode, "name", std::string()); + + if (server.type == ServerInfo::UNKNOWN) { - logger->log("Online server list has wrong version"); - return; + logger->log("Unknown server type: %s", type.c_str()); + continue; } - for_each_xml_child_node(server, rootNode) + for_each_xml_child_node(subNode, serverNode) { - if (xmlStrEqual(server->name, BAD_CAST "server")) - { - std::string type = XML::getProperty(server, "type", "unknown"); - - currentServer.clear(); - currentServer.name = XML::getProperty(server, "name", std::string()); + if (!xmlStrEqual(subNode->name, BAD_CAST "connection")) + continue; - for_each_xml_child_node(subnode, server) - { - if (xmlStrEqual(subnode->name, BAD_CAST "connection")) - { - currentServer.type = stringToServerType(type); - currentServer.hostname = XML::getProperty(subnode, "hostname", std::string()); - currentServer.port = XML::getProperty(subnode, "port", DEFAULT_PORT); - } - } + server.hostname = XML::getProperty(subNode, "hostname", ""); + server.port = XML::getProperty(subNode, "port", 0); + if (server.port == 0) + { + // If no port is given, use the default for the given type + server.port = defaultPortForServerType(server.type); + } + } - MutexLocker lock(&mMutex); - // add the server to the local list (if it's not already present) - ServerInfos::iterator it; - bool found = false; - for (it = mServers.begin(); it != mServers.end(); it++) - { - if ((*it) == currentServer) - { - (*it).name = currentServer.name; - found = true; - break; - } - } - - if (!found) - mServers.push_back(currentServer); + MutexLocker lock(&mMutex); + // Add the server to the local list if it's not already present + ServerInfos::iterator it; + bool found = false; + for (it = mServers.begin(); it != mServers.end(); it++) + { + if ((*it) == server) + { + // Use the name listed in the server list + (*it).name = server.name; + found = true; + break; } } - xmlFreeDoc(doc); + if (!found) + mServers.push_back(server); } - - MutexLocker lock(&mMutex); - mDownloadStatus = DOWNLOADING_COMPLETE; } int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, @@ -518,9 +560,12 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, { float progress = (float) remaining / total; - if (progress != progress) progress = 0.0f; // check for NaN - if (progress < 0.0f) progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway. - if (progress > 1.0f) progress = 1.0f; + if (progress != progress) + progress = 0.0f; // check for NaN + else if (progress < 0.0f) + progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway. + else if (progress > 1.0f) + progress = 1.0f; MutexLocker lock(&sd->mMutex); sd->mDownloadStatus = DOWNLOADING_IN_PROGRESS; @@ -530,6 +575,9 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, if (finished) { sd->loadServers(); + + MutexLocker lock(&sd->mMutex); + sd->mDownloadStatus = DOWNLOADING_COMPLETE; } return 0; diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h index c4af6ab2..3d7dca9d 100644 --- a/src/gui/serverdialog.h +++ b/src/gui/serverdialog.h @@ -32,6 +32,7 @@ #include <guichan/actionlistener.hpp> #include <guichan/keylistener.hpp> #include <guichan/listmodel.hpp> +#include <guichan/mouselistener.hpp> #include <guichan/selectionlistener.hpp> #include <string> @@ -68,18 +69,24 @@ class ServersListModel : public gcn::ListModel ServerInfo getServer(int elementIndex) const { return mServers->at(elementIndex); } + /** + * Removes the entry. + */ + void remove(int elementIndex) + { mServers->erase(mServers->begin() + elementIndex); } + private: ServerInfos *mServers; ServerDialog *mParent; }; /** - * Server and Port List Model + * Server Type List Model */ class TypeListModel : public gcn::ListModel { public: - TypeListModel() { }; + TypeListModel() {} /** * Used to get number of line in the list @@ -128,6 +135,8 @@ class ServerDialog : public Window, */ void valueChanged(const gcn::SelectionEvent &event); + void mouseClicked(gcn::MouseEvent &mouseEvent); + void logic(); protected: @@ -143,7 +152,7 @@ class ServerDialog : public Window, static int downloadUpdate(void *ptr, DownloadStatus status, size_t total, size_t remaining); - void setFieldsReadOnly(const bool readOnly); + void setFieldsReadOnly(bool readOnly); TextField *mServerNameField; TextField *mPortField; @@ -151,6 +160,7 @@ class ServerDialog : public Window, Button *mQuitButton; Button *mConnectButton; Button *mManualEntryButton; + Button *mDeleteButton; ListBox *mServersList; ServersListModel *mServersListModel; diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 78c5c998..09c7ccb2 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -25,6 +25,7 @@ #include "log.h" #include "gui/setup.h" +#include "gui/skin.h" #include "gui/widgets/button.h" #include "gui/widgets/container.h" @@ -76,7 +77,7 @@ struct SkillInfo icon->decRef(); } - void setIcon(std::string iconPath) + void setIcon(const std::string &iconPath) { ResourceManager *res = ResourceManager::getInstance(); if (!iconPath.empty()) @@ -85,7 +86,7 @@ struct SkillInfo } else { - icon = res->getImage("graphics/gui/unknown-item.png"); + icon = SkinLoader::getImageFromTheme("unknown-item.png"); } } @@ -99,11 +100,19 @@ typedef std::vector<SkillInfo*> SkillList; class SkillModel : public gcn::ListModel { public: - int getNumberOfElements() { return mVisibleSkills.size(); } - SkillInfo *getSkillAt(int i) { return mVisibleSkills.at(i); } - std::string getElementAt(int i) { return getSkillAt(i)->name; } + int getNumberOfElements() + { return mVisibleSkills.size(); } + + SkillInfo *getSkillAt(int i) const + { return mVisibleSkills.at(i); } + + std::string getElementAt(int i) + { return getSkillAt(i)->name; } + void updateVisibilities(); - void addSkill(SkillInfo *info) { mSkills.push_back(info); } + + void addSkill(SkillInfo *info) + { mSkills.push_back(info); } private: SkillList mSkills; @@ -119,7 +128,11 @@ public: SkillInfo *getSelectedInfo() { - return static_cast<SkillModel*>(mListModel)->getSkillAt(getSelected()); + const int selected = getSelected(); + if (selected < 0 || selected > mListModel->getNumberOfElements()) + return 0; + + return static_cast<SkillModel*>(mListModel)->getSkillAt(selected); } void draw(gcn::Graphics *gcnGraphics) @@ -216,9 +229,8 @@ void SkillDialog::action(const gcn::ActionEvent &event) if (tab) { - SkillInfo *info = tab->getSelectedInfo(); - - Net::getPlayerHandler()->increaseSkill(info->id); + if (SkillInfo *info = tab->getSelectedInfo()) + Net::getPlayerHandler()->increaseSkill(info->id); } } else if (event.getId() == "close") diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp index a682bf8f..22153720 100644 --- a/src/gui/skin.cpp +++ b/src/gui/skin.cpp @@ -23,22 +23,26 @@ #include "gui/skin.h" +#include "client.h" #include "configuration.h" #include "configlistener.h" #include "log.h" #include "resources/image.h" +#include "resources/imageset.h" #include "resources/resourcemanager.h" #include "utils/dtor.h" #include "utils/stringutils.h" #include "utils/xml.h" +#include <physfs.h> + #include <algorithm> +std::string SkinLoader::mThemePath; SkinLoader *SkinLoader::mInstance = 0; - class SkinConfigListener : public ConfigListener { public: @@ -197,7 +201,7 @@ Skin *SkinLoader::readSkin(const std::string &filename) logger->log("Loading skin '%s'.", filename.c_str()); - XML::Document doc(filename); + XML::Document doc(resolveThemePath(filename)); xmlNodePtr rootNode = doc.rootNode(); if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset")) @@ -215,8 +219,7 @@ Skin *SkinLoader::readSkin(const std::string &filename) logger->log("SkinLoader::load(): <skinset> defines " "'%s' as a skin image.", skinSetImage.c_str()); - ResourceManager *resman = ResourceManager::getInstance(); - Image *dBorders = resman->getImage("graphics/gui/" + skinSetImage); + Image *dBorders = SkinLoader::getImageFromTheme(skinSetImage); ImageRect border; // iterate <widget>'s @@ -286,8 +289,8 @@ Skin *SkinLoader::readSkin(const std::string &filename) logger->log("Finished loading skin."); // Hard-coded for now until we update the above code to look for window buttons - Image *closeImage = resman->getImage("graphics/gui/close_button.png"); - Image *sticky = resman->getImage("graphics/gui/sticky_button.png"); + Image *closeImage = SkinLoader::getImageFromTheme("close_button.png"); + Image *sticky = SkinLoader::getImageFromTheme("sticky_button.png"); Image *stickyImageUp = sticky->getSubImage(0, 0, 15, 15); Image *stickyImageDown = sticky->getSubImage(15, 0, 15, 15); sticky->decRef(); @@ -297,3 +300,68 @@ Skin *SkinLoader::readSkin(const std::string &filename) skin->updateAlpha(mMinimumOpacity); return skin; } + +bool SkinLoader::tryThemePath(std::string themePath) +{ + if (!themePath.empty()) + { + themePath = "graphics/gui/" + themePath; + if (PHYSFS_exists(themePath.c_str())) + { + mThemePath = themePath; + return true; + } + } + + return false; +} + +void SkinLoader::prepareThemePath() +{ + // Try theme from settings + if (tryThemePath(config.getValue("theme", ""))) + return; + + // Try theme from branding + if (tryThemePath(branding.getValue("theme", ""))) + return; + + // Use default + mThemePath = "graphics/gui"; +} + +std::string SkinLoader::resolveThemePath(const std::string &path) +{ + // Need to strip off any dye info for the existence tests + int pos = path.find('|'); + std::string file; + if (pos > 0) + file = path.substr(0, pos); + else + file = path; + + // Might be a valid path already + if (PHYSFS_exists(file.c_str())) + return path; + + // Try the theme + file = getThemePath() + "/" + file; + if (PHYSFS_exists(file.c_str())) + return getThemePath() + "/" + path; + + // Backup + return "graphics/gui/" + path; +} + +Image *SkinLoader::getImageFromTheme(const std::string &path) +{ + ResourceManager *resman = ResourceManager::getInstance(); + return resman->getImage(resolveThemePath(path)); +} + +ImageSet *SkinLoader::getImageSetFromTheme(const std::string &path, + int w, int h) +{ + ResourceManager *resman = ResourceManager::getInstance(); + return resman->getImageSet(resolveThemePath(path), w, h); +} diff --git a/src/gui/skin.h b/src/gui/skin.h index 15d55972..091d3001 100644 --- a/src/gui/skin.h +++ b/src/gui/skin.h @@ -31,6 +31,7 @@ class ConfigListener; class Image; +class ImageSet; class Skin { @@ -101,11 +102,24 @@ class SkinLoader static SkinLoader *instance(); static void deleteInstance(); + static void prepareThemePath(); + static std::string getThemePath() { return mThemePath; } + + /** + * Returns the patch to the given gui resource relative to the theme + * or, if it isn't in the theme, relative to 'graphics/gui'. + */ + static std::string resolveThemePath(const std::string &path); + + static Image *getImageFromTheme(const std::string &path); + static ImageSet *getImageSetFromTheme(const std::string &path, + int w, int h); + /** * Loads a skin. */ Skin *load(const std::string &filename, - const std::string &defaultPath); + const std::string &defaultPath = getThemePath()); /** * Updates the alpha values of all of the skins. @@ -141,8 +155,11 @@ class SkinLoader */ ConfigListener *mSkinConfigListener; + static std::string mThemePath; static SkinLoader *mInstance; + static bool tryThemePath(std::string themePath); + /** * Tells if the current skins opacity * should not get less than the given value diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 26184cae..5da8018c 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -235,7 +235,8 @@ public: mBrowserBox->setOpaque(false); mBrowserBox->setLinkHandler(this); - mBrowserBox->addRow(strprintf("@@guild|%s@@", _("Create Guild"))); + if (Net::getGuildHandler()->isSupported()) + mBrowserBox->addRow(strprintf("@@guild|%s@@", _("Create Guild"))); mBrowserBox->addRow(strprintf("@@party|%s@@", _("Create Party"))); mBrowserBox->addRow("##3---"); mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel"))); @@ -425,7 +426,10 @@ void SocialWindow::action(const gcn::ActionEvent &event) } else if (event.getId() == "create") { - mCreatePopup->show(mCreateButton); + if (Net::getGuildHandler()->isSupported()) + mCreatePopup->show(mCreateButton); + else + showPartyCreate(); } else if (event.getId() == "invite") { @@ -564,7 +568,7 @@ void SocialWindow::showPartyCreate() } mPartyCreateDialog = new TextDialog(_("Party Name"), - _("Choose your part's name."), this); + _("Choose your party's name."), this); mPartyCreateDialog->setOKButtonActionId("create party"); mPartyCreateDialog->addActionListener(this); } diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp index 1513dcf1..3ca0f037 100644 --- a/src/gui/specialswindow.cpp +++ b/src/gui/specialswindow.cpp @@ -24,6 +24,7 @@ #include "log.h" #include "gui/setup.h" +#include "gui/skin.h" #include "gui/widgets/button.h" #include "gui/widgets/container.h" @@ -219,7 +220,7 @@ SpecialEntry::SpecialEntry(SpecialInfo *info) : if (!info->icon.empty()) mIcon = new Icon(info->icon); else - mIcon = new Icon("graphics/gui/unknown-item.png"); + mIcon = new Icon(SkinLoader::resolveThemePath("unknown-item.png")); mIcon->setPosition(1, 0); add(mIcon); diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index 3a87992b..f02965d1 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -25,6 +25,7 @@ #include "graphics.h" #include "gui/gui.h" +#include "gui/skin.h" #include "gui/widgets/textbox.h" @@ -33,7 +34,7 @@ #include <guichan/widgets/label.hpp> SpeechBubble::SpeechBubble(): - Popup("Speech", "graphics/gui/speechbubble.xml") + Popup("Speech", "speechbubble.xml") { setContentSize(140, 46); setMinWidth(29); diff --git a/src/gui/textdialog.h b/src/gui/textdialog.h index 6db09e71..825d9ddc 100644 --- a/src/gui/textdialog.h +++ b/src/gui/textdialog.h @@ -43,8 +43,7 @@ public: */ TextDialog(const std::string &title, const std::string &msg, Window *parent = NULL); - - + ~TextDialog(); /** @@ -61,8 +60,8 @@ public: * Set the OK button action id */ void setOKButtonActionId(const std::string &name); - - static const bool isActive() { return instances > 0; } + + static bool isActive() { return instances > 0; } private: static int instances; diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 763d0c43..1451b935 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -53,10 +53,7 @@ Viewport::Viewport(): mMouseY(0), mPixelViewX(0.0f), mPixelViewY(0.0f), - mTileViewX(0), - mTileViewY(0), mShowDebugPath(false), - mVisibleNames(false), mPlayerFollowMouse(false), mLocalWalkTime(-1) { @@ -67,21 +64,20 @@ Viewport::Viewport(): mScrollRadius = (int) config.getValue("ScrollRadius", 0); mScrollCenterOffsetX = (int) config.getValue("ScrollCenterOffsetX", 0); mScrollCenterOffsetY = (int) config.getValue("ScrollCenterOffsetY", 0); - mVisibleNames = config.getValue("visiblenames", 1); config.addListener("ScrollLaziness", this); config.addListener("ScrollRadius", this); - config.addListener("visiblenames", this); mPopupMenu = new PopupMenu; mBeingPopup = new BeingPopup; + + setFocusable(true); } Viewport::~Viewport() { delete mPopupMenu; - - config.removeListener("visiblenames", this); + delete mBeingPopup; } void Viewport::setMap(Map *map) @@ -109,10 +105,6 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) Graphics *graphics = static_cast<Graphics*>(gcnGraphics); - // Ensure the client doesn't freak out if a feature localplayer uses - // is dependent on a map. - player_node->setMapInitialized(true); - // Avoid freaking out when tick_time overflows if (tick_time < lastTick) { @@ -184,9 +176,6 @@ void Viewport::draw(gcn::Graphics *gcnGraphics) mPixelViewY = viewYmax; } - mTileViewX = (int) (mPixelViewX + 16) / 32; - mTileViewY = (int) (mPixelViewY + 16) / 32; - // Draw tiles and sprites if (mMap) { @@ -312,25 +301,18 @@ void Viewport::mousePressed(gcn::MouseEvent &event) const int pixelX = event.getX() + (int) mPixelViewX; const int pixelY = event.getY() + (int) mPixelViewY; - const int tileX = pixelX / mMap->getTileWidth(); - const int tileY = pixelY / mMap->getTileHeight(); // Right click might open a popup if (event.getButton() == gcn::MouseEvent::RIGHT) { - Being *being; - FloorItem *floorItem; - - if ((being = beingManager->findBeingByPixel(pixelX, pixelY)) && - being != player_node) + if (mHoverBeing && mHoverBeing != player_node) { - mPopupMenu->showPopup(event.getX(), event.getY(), being); + mPopupMenu->showPopup(event.getX(), event.getY(), mHoverBeing); return; } - else if ((floorItem = floorItemManager->findByCoordinates(tileX, - tileY))) + else if (mHoverItem) { - mPopupMenu->showPopup(event.getX(), event.getY(), floorItem); + mPopupMenu->showPopup(event.getX(), event.getY(), mHoverItem); return; } } @@ -345,35 +327,32 @@ void Viewport::mousePressed(gcn::MouseEvent &event) // Left click can cause different actions if (event.getButton() == gcn::MouseEvent::LEFT) { - FloorItem *item; - Being *being; - // Interact with some being - if ((being = beingManager->findBeingByPixel(pixelX, pixelY))) + if (mHoverBeing) { - switch (being->getType()) + switch (mHoverBeing->getType()) { // Talk to NPCs case Being::NPC: - dynamic_cast<NPC*>(being)->talk(); + static_cast<NPC*>(mHoverBeing)->talk(); break; // Attack or walk to monsters or players case Being::MONSTER: case Being::PLAYER: // Ignore it if its dead - if (!being->isAlive()) + if (!mHoverBeing->isAlive()) break; - if (player_node->withinAttackRange(being) || + if (player_node->withinAttackRange(mHoverBeing) || keyboard.isKeyActive(keyboard.KEY_ATTACK)) { - player_node->attack(being, + player_node->attack(mHoverBeing, !keyboard.isKeyActive(keyboard.KEY_TARGET)); } else { - player_node->setGotoTarget(being); + player_node->setGotoTarget(mHoverBeing); } break; default: @@ -381,9 +360,9 @@ void Viewport::mousePressed(gcn::MouseEvent &event) } // Picks up a item if we clicked on one } - else if ((item = floorItemManager->findByCoordinates(tileX, tileY))) + else if (mHoverItem) { - player_node->pickUp(item); + player_node->pickUp(mHoverItem); } else if (player_node->getCurrentAction() == Being::SIT) { @@ -433,8 +412,10 @@ void Viewport::mouseDragged(gcn::MouseEvent &event) if (mLocalWalkTime != player_node->getWalkTime()) { mLocalWalkTime = player_node->getWalkTime(); - int destX = event.getX() / 32 + mTileViewX; - int destY = event.getY() / 32 + mTileViewY; + int destX = (event.getX() + mPixelViewX + 16) / + mMap->getTileWidth(); + int destY = (event.getY() + mPixelViewY + 16) / + mMap->getTileHeight(); player_node->setDestination(destX, destY); } } @@ -464,9 +445,6 @@ void Viewport::optionChanged(const std::string &name) { mScrollLaziness = (int) config.getValue("ScrollLaziness", 32); mScrollRadius = (int) config.getValue("ScrollRadius", 32); - - if (name == "visiblenames") - mVisibleNames = config.getValue("visiblenames", 1); } void Viewport::mouseMoved(gcn::MouseEvent &event) @@ -478,11 +456,42 @@ void Viewport::mouseMoved(gcn::MouseEvent &event) const int x = (event.getX() + (int) mPixelViewX); const int y = (event.getY() + (int) mPixelViewY); - mSelectedBeing = beingManager->findBeingByPixel(x, y); - if (Player *p = dynamic_cast<Player*>(mSelectedBeing)) + mHoverBeing = beingManager->findBeingByPixel(x, y); + if (Player *p = dynamic_cast<Player*>(mHoverBeing)) mBeingPopup->show(getMouseX(), getMouseY(), p); else mBeingPopup->setVisible(false); + + mHoverItem = floorItemManager->findByCoordinates(x / mMap->getTileWidth(), + y / mMap->getTileHeight()); + + if (mHoverBeing) + { + switch (mHoverBeing->getType()) + { + // NPCs + case Being::NPC: + gui->setCursorType(Gui::CURSOR_TALK); + break; + + // Monsters + case Being::MONSTER: + gui->setCursorType(Gui::CURSOR_FIGHT); + break; + default: + gui->setCursorType(Gui::CURSOR_POINTER); + break; + } + // Item mouseover + } + else if (mHoverItem) + { + gui->setCursorType(Gui::CURSOR_PICKUP); + } + else + { + gui->setCursorType(Gui::CURSOR_POINTER); + } } void Viewport::toggleDebugPath() @@ -496,3 +505,7 @@ void Viewport::toggleDebugPath() } } +void Viewport::hideBeingPopup() +{ + mBeingPopup->setVisible(false); +} diff --git a/src/gui/viewport.h b/src/gui/viewport.h index 5b92d950..e4944cd6 100644 --- a/src/gui/viewport.h +++ b/src/gui/viewport.h @@ -152,6 +152,11 @@ class Viewport : public WindowContainer, public gcn::MouseListener, */ Map *getCurrentMap() const { return mMap; } + /** + * Hides the BeingPopup. + */ + void hideBeingPopup(); + private: /** * Finds a path from the player to the mouse, and draws it. This is for @@ -179,20 +184,18 @@ class Viewport : public WindowContainer, public gcn::MouseListener, int mMouseY; /**< Current mouse position in pixels. */ float mPixelViewX; /**< Current viewpoint in pixels. */ float mPixelViewY; /**< Current viewpoint in pixels. */ - int mTileViewX; /**< Current viewpoint in tiles. */ - int mTileViewY; /**< Current viewpoint in tiles. */ int mShowDebugPath; /**< Show a path from player to pointer. */ - bool mVisibleNames; /**< Show target names. */ bool mPlayerFollowMouse; int mLocalWalkTime; /**< Timestamp before the next walk can be sent. */ PopupMenu *mPopupMenu; /**< Popup menu. */ - Being *mSelectedBeing; /**< Current selected being. */ - BeingPopup *mBeingPopup; + Being *mHoverBeing; /**< Being mouse is currently over. */ + FloorItem *mHoverItem; /**< FloorItem mouse is currently over. */ + BeingPopup *mBeingPopup; /**< Being information popup. */ }; -extern Viewport *viewport; /**< The viewport */ +extern Viewport *viewport; /**< The viewport. */ #endif diff --git a/src/gui/widgets/avatarlistbox.cpp b/src/gui/widgets/avatarlistbox.cpp index f5a9ea18..92386739 100644 --- a/src/gui/widgets/avatarlistbox.cpp +++ b/src/gui/widgets/avatarlistbox.cpp @@ -25,6 +25,7 @@ #include "gui/chat.h" #include "gui/gui.h" #include "gui/palette.h" +#include "gui/skin.h" #include "resources/image.h" #include "resources/resourcemanager.h" @@ -44,8 +45,8 @@ AvatarListBox::AvatarListBox(AvatarListModel *model): if (instances == 1) { - onlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png"); - offlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png"); + onlineIcon = SkinLoader::getImageFromTheme("circle-green.png"); + offlineIcon = SkinLoader::getImageFromTheme("circle-gray.png"); } setWidth(200); diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index 6589c96e..36a47859 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -28,7 +28,6 @@ #include "gui/skin.h" #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -54,10 +53,10 @@ struct ButtonData }; static ButtonData const data[BUTTON_COUNT] = { - { "graphics/gui/button.png", 0, 0 }, - { "graphics/gui/buttonhi.png", 9, 4 }, - { "graphics/gui/buttonpress.png", 16, 19 }, - { "graphics/gui/button_disabled.png", 25, 23 } + { "button.png", 0, 0 }, + { "buttonhi.png", 9, 4 }, + { "buttonpress.png", 16, 19 }, + { "button_disabled.png", 25, 23 } }; ImageRect Button::button[BUTTON_COUNT]; @@ -85,14 +84,13 @@ void Button::init() if (mInstances == 0) { // Load the skin - ResourceManager *resman = ResourceManager::getInstance(); Image *btn[BUTTON_COUNT]; int a, x, y, mode; for (mode = 0; mode < BUTTON_COUNT; mode++) { - btn[mode] = resman->getImage(data[mode].file); + btn[mode] = SkinLoader::getImageFromTheme(data[mode].file); a = 0; for (y = 0; y < 3; y++) { diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp index dc6d94b3..0fefbfe9 100644 --- a/src/gui/widgets/checkbox.cpp +++ b/src/gui/widgets/checkbox.cpp @@ -28,7 +28,6 @@ #include "gui/skin.h" #include "resources/image.h" -#include "resources/resourcemanager.h" int CheckBox::instances = 0; float CheckBox::mAlpha = 1.0; @@ -45,8 +44,7 @@ CheckBox::CheckBox(const std::string &caption, bool selected): { if (instances == 0) { - ResourceManager *resman = ResourceManager::getInstance(); - Image *checkBox = resman->getImage("graphics/gui/checkbox.png"); + Image *checkBox = SkinLoader::getImageFromTheme("checkbox.png"); checkBoxNormal = checkBox->getSubImage(0, 0, 9, 10); checkBoxChecked = checkBox->getSubImage(9, 0, 9, 10); checkBoxDisabled = checkBox->getSubImage(18, 0, 9, 10); @@ -114,21 +112,29 @@ void CheckBox::drawBox(gcn::Graphics* graphics) Image *box; if (isEnabled()) + { if (isSelected()) + { if (mHasMouse) box = checkBoxCheckedHi; else box = checkBoxChecked; + } else + { if (mHasMouse) box = checkBoxNormalHi; else box = checkBoxNormal; + } + } else + { if (isSelected()) box = checkBoxDisabledChecked; else box = checkBoxDisabled; + } updateAlpha(); diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp index e7cd949a..2a80cc11 100644 --- a/src/gui/widgets/desktop.cpp +++ b/src/gui/widgets/desktop.cpp @@ -20,6 +20,7 @@ #include "gui/widgets/desktop.h" +#include "configuration.h" #include "graphics.h" #include "log.h" #include "main.h" @@ -32,6 +33,8 @@ #include "resources/resourcemanager.h" #include "resources/wallpaper.h" +#include "utils/stringutils.h" + Desktop::Desktop() : mWallpaper(0) { @@ -39,7 +42,14 @@ Desktop::Desktop() Wallpaper::loadWallpapers(); - mVersionLabel = new Label(FULL_VERSION); + std::string appName = branding.getValue("appName", ""); + + if (appName.empty()) + mVersionLabel = new Label(FULL_VERSION); + else + mVersionLabel = new Label(strprintf("%s (Mana %s)", appName.c_str(), + FULL_VERSION)); + mVersionLabel->setBackgroundColor(gcn::Color(255, 255, 255, 128)); add(mVersionLabel, 25, 2); } diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index 32b42553..eb0cdef2 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -32,7 +32,6 @@ #include "gui/widgets/scrollarea.h" #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -54,17 +53,16 @@ DropDown::DropDown(gcn::ListModel *listModel): if (instances == 0) { // Load the background skin - ResourceManager *resman = ResourceManager::getInstance(); // Get the button skin buttons[1][0] = - resman->getImage("graphics/gui/vscroll_up_default.png"); + SkinLoader::getImageFromTheme("vscroll_up_default.png"); buttons[0][0] = - resman->getImage("graphics/gui/vscroll_down_default.png"); + SkinLoader::getImageFromTheme("vscroll_down_default.png"); buttons[1][1] = - resman->getImage("graphics/gui/vscroll_up_pressed.png"); + SkinLoader::getImageFromTheme("vscroll_up_pressed.png"); buttons[0][1] = - resman->getImage("graphics/gui/vscroll_down_pressed.png"); + SkinLoader::getImageFromTheme("vscroll_down_pressed.png"); buttons[0][0]->setAlpha(mAlpha); buttons[0][1]->setAlpha(mAlpha); @@ -72,7 +70,7 @@ DropDown::DropDown(gcn::ListModel *listModel): buttons[1][1]->setAlpha(mAlpha); // get the border skin - Image *boxBorder = resman->getImage("graphics/gui/deepbox.png"); + Image *boxBorder = SkinLoader::getImageFromTheme("deepbox.png"); int gridx[4] = {0, 3, 28, 31}; int gridy[4] = {0, 3, 28, 31}; int a = 0, x, y; diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp index 41be172f..dd13c679 100644 --- a/src/gui/widgets/emoteshortcutcontainer.cpp +++ b/src/gui/widgets/emoteshortcutcontainer.cpp @@ -32,10 +32,10 @@ #include "log.h" #include "gui/palette.h" +#include "gui/skin.h" #include "resources/emotedb.h" #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -49,9 +49,7 @@ EmoteShortcutContainer::EmoteShortcutContainer(): addMouseListener(this); addWidgetListener(this); - ResourceManager *resman = ResourceManager::getInstance(); - - mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png"); + mBackgroundImg = SkinLoader::getImageFromTheme("item_shortcut_bgr.png"); mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8)); diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index f801822c..b4270912 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -32,6 +32,7 @@ #include "gui/outfitwindow.h" #include "gui/palette.h" #include "gui/sdlinput.h" +#include "gui/skin.h" #include "gui/viewport.h" #include "net/net.h" @@ -39,7 +40,6 @@ #include "resources/image.h" #include "resources/iteminfo.h" -#include "resources/resourcemanager.h" #include "utils/stringutils.h" @@ -67,9 +67,7 @@ ItemContainer::ItemContainer(Inventory *inventory, bool forceQuantity): mItemPopup = new ItemPopup; setFocusable(true); - ResourceManager *resman = ResourceManager::getInstance(); - - mSelImg = resman->getImage("graphics/gui/selection.png"); + mSelImg = SkinLoader::getImageFromTheme("selection.png"); if (!mSelImg) logger->error("Unable to load selection.png"); diff --git a/src/gui/widgets/itemshortcutcontainer.cpp b/src/gui/widgets/itemshortcutcontainer.cpp index 66e053d8..92a3e7d0 100644 --- a/src/gui/widgets/itemshortcutcontainer.cpp +++ b/src/gui/widgets/itemshortcutcontainer.cpp @@ -32,11 +32,11 @@ #include "gui/inventorywindow.h" #include "gui/itempopup.h" #include "gui/palette.h" +#include "gui/skin.h" #include "gui/viewport.h" #include "resources/image.h" #include "resources/iteminfo.h" -#include "resources/resourcemanager.h" #include "utils/stringutils.h" @@ -50,9 +50,7 @@ ItemShortcutContainer::ItemShortcutContainer(): mItemPopup = new ItemPopup; - ResourceManager *resman = ResourceManager::getInstance(); - - mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png"); + mBackgroundImg = SkinLoader::getImageFromTheme("item_shortcut_bgr.png"); mMaxItems = itemShortcut->getItemCount(); mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8)); diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp index 23da2afd..24395db7 100644 --- a/src/gui/widgets/playerbox.cpp +++ b/src/gui/widgets/playerbox.cpp @@ -26,8 +26,9 @@ #include "graphics.h" #include "player.h" +#include "gui/skin.h" + #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -43,8 +44,7 @@ PlayerBox::PlayerBox(const Player *player): if (instances == 0) { // Load the background skin - ResourceManager *resman = ResourceManager::getInstance(); - Image *textbox = resman->getImage("graphics/gui/deepbox.png"); + Image *textbox = SkinLoader::getImageFromTheme("deepbox.png"); int bggridx[4] = {0, 3, 28, 31}; int bggridy[4] = {0, 3, 28, 31}; int a = 0, x, y; diff --git a/src/gui/widgets/popup.cpp b/src/gui/widgets/popup.cpp index 391b0eed..970b21ec 100644 --- a/src/gui/widgets/popup.cpp +++ b/src/gui/widgets/popup.cpp @@ -27,6 +27,7 @@ #include "log.h" #include "gui/skin.h" +#include "gui/viewport.h" #include "gui/widgets/windowcontainer.h" @@ -186,3 +187,9 @@ void Popup::position(int x, int y) setVisible(true); requestMoveToTop(); } + +void Popup::mouseMoved(gcn::MouseEvent &event) +{ + if (viewport) + viewport->hideBeingPopup(); +} diff --git a/src/gui/widgets/popup.h b/src/gui/widgets/popup.h index 449c2f7b..5c9164f6 100644 --- a/src/gui/widgets/popup.h +++ b/src/gui/widgets/popup.h @@ -28,6 +28,8 @@ #include "gui/widgets/container.h" +#include <guichan/mouselistener.hpp> + class Skin; class WindowContainer; @@ -43,7 +45,7 @@ class WindowContainer; * * \ingroup GUI */ -class Popup : public Container +class Popup : public Container, public gcn::MouseListener { public: /** @@ -55,7 +57,7 @@ class Popup : public Container * @param skin The location where the Popup's skin XML can be found. */ Popup(const std::string &name = "", - const std::string &skin = "graphics/gui/gui.xml"); + const std::string &skin = "window.xml"); /** * Destructor. Deletes all the added widgets. @@ -94,6 +96,8 @@ class Popup : public Container */ void setLocationRelativeTo(gcn::Widget *widget); + void mouseMoved(gcn::MouseEvent &event); + /** * Sets the minimum width of the popup. */ diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp index db2a8692..31c32132 100644 --- a/src/gui/widgets/progressbar.cpp +++ b/src/gui/widgets/progressbar.cpp @@ -30,7 +30,6 @@ #include "gui/skin.h" #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -59,8 +58,7 @@ ProgressBar::ProgressBar(float progress, if (mInstances == 0) { - ResourceManager *resman = ResourceManager::getInstance(); - Image *dBorders = resman->getImage("graphics/gui/vscroll_grey.png"); + Image *dBorders = SkinLoader::getImageFromTheme("vscroll_grey.png"); mBorder.grid[0] = dBorders->getSubImage(0, 0, 4, 4); mBorder.grid[1] = dBorders->getSubImage(4, 0, 3, 4); mBorder.grid[2] = dBorders->getSubImage(7, 0, 4, 4); diff --git a/src/gui/widgets/progressindicator.cpp b/src/gui/widgets/progressindicator.cpp index d1b6bb87..f88f6045 100644 --- a/src/gui/widgets/progressindicator.cpp +++ b/src/gui/widgets/progressindicator.cpp @@ -20,6 +20,8 @@ #include "progressindicator.h" +#include "gui/skin.h" + #include "resources/animation.h" #include "resources/imageset.h" #include "resources/resourcemanager.h" @@ -31,9 +33,8 @@ ProgressIndicator::ProgressIndicator() { - ResourceManager *rm = ResourceManager::getInstance(); - ImageSet *images = rm->getImageSet("graphics/gui/progress-indicator.png", - 32, 32); + ImageSet *images = + SkinLoader::getImageSetFromTheme("progress-indicator.png", 32, 32); Animation *anim = new Animation; for (ImageSet::size_type i = 0; i < images->size(); ++i) diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp index adbc4dd7..41c8faf7 100644 --- a/src/gui/widgets/radiobutton.cpp +++ b/src/gui/widgets/radiobutton.cpp @@ -24,8 +24,9 @@ #include "configuration.h" #include "graphics.h" +#include "gui/skin.h" + #include "resources/image.h" -#include "resources/resourcemanager.h" int RadioButton::instances = 0; float RadioButton::mAlpha = 1.0; @@ -43,13 +44,12 @@ RadioButton::RadioButton(const std::string &caption, const std::string &group, { if (instances == 0) { - ResourceManager *resman = ResourceManager::getInstance(); - radioNormal = resman->getImage("graphics/gui/radioout.png"); - radioChecked = resman->getImage("graphics/gui/radioin.png"); - radioDisabled = resman->getImage("graphics/gui/radioout.png"); - radioDisabledChecked = resman->getImage("graphics/gui/radioin.png"); - radioNormalHi = resman->getImage("graphics/gui/radioout_highlight.png"); - radioCheckedHi = resman->getImage("graphics/gui/radioin_highlight.png"); + radioNormal = SkinLoader::getImageFromTheme("radioout.png"); + radioChecked = SkinLoader::getImageFromTheme("radioin.png"); + radioDisabled = SkinLoader::getImageFromTheme("radioout.png"); + radioDisabledChecked = SkinLoader::getImageFromTheme("radioin.png"); + radioNormalHi = SkinLoader::getImageFromTheme("radioout_highlight.png"); + radioCheckedHi = SkinLoader::getImageFromTheme("radioin_highlight.png"); radioNormal->setAlpha(mAlpha); radioChecked->setAlpha(mAlpha); radioDisabled->setAlpha(mAlpha); diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp index 106118da..d0b9b845 100644 --- a/src/gui/widgets/resizegrip.cpp +++ b/src/gui/widgets/resizegrip.cpp @@ -24,8 +24,9 @@ #include "configuration.h" #include "graphics.h" +#include "gui/skin.h" + #include "resources/image.h" -#include "resources/resourcemanager.h" #include <guichan/graphics.hpp> @@ -38,8 +39,7 @@ ResizeGrip::ResizeGrip(const std::string &image) if (mInstances == 0) { // Load the grip image - ResourceManager *resman = ResourceManager::getInstance(); - gripImage = resman->getImage(image); + gripImage = SkinLoader::getImageFromTheme(image); gripImage->setAlpha(mAlpha); } diff --git a/src/gui/widgets/resizegrip.h b/src/gui/widgets/resizegrip.h index 4cc195cc..5ef93f29 100644 --- a/src/gui/widgets/resizegrip.h +++ b/src/gui/widgets/resizegrip.h @@ -39,7 +39,7 @@ class ResizeGrip : public gcn::Widget /** * Constructor. */ - ResizeGrip(const std::string &image = "graphics/gui/resize.png"); + ResizeGrip(const std::string &image = "resize.png"); /** * Destructor. diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp index b3e28329..dea99e8e 100644 --- a/src/gui/widgets/scrollarea.cpp +++ b/src/gui/widgets/scrollarea.cpp @@ -27,7 +27,6 @@ #include "gui/skin.h" #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -96,8 +95,7 @@ void ScrollArea::init() if (instances == 0) { // Load the background skin - ResourceManager *resman = ResourceManager::getInstance(); - Image *textbox = resman->getImage("graphics/gui/deepbox.png"); + Image *textbox = SkinLoader::getImageFromTheme("deepbox.png"); const int bggridx[4] = {0, 3, 28, 31}; const int bggridy[4] = {0, 3, 28, 31}; int a = 0, x, y; @@ -118,8 +116,8 @@ void ScrollArea::init() textbox->decRef(); // Load vertical scrollbar skin - Image *vscroll = resman->getImage("graphics/gui/vscroll_grey.png"); - Image *vscrollHi = resman->getImage("graphics/gui/vscroll_highlight.png"); + Image *vscroll = SkinLoader::getImageFromTheme("vscroll_grey.png"); + Image *vscrollHi = SkinLoader::getImageFromTheme("vscroll_highlight.png"); int vsgridx[4] = {0, 4, 7, 11}; int vsgridy[4] = {0, 4, 15, 19}; @@ -147,21 +145,21 @@ void ScrollArea::init() vscrollHi->decRef(); buttons[UP][0] = - resman->getImage("graphics/gui/vscroll_up_default.png"); + SkinLoader::getImageFromTheme("vscroll_up_default.png"); buttons[DOWN][0] = - resman->getImage("graphics/gui/vscroll_down_default.png"); + SkinLoader::getImageFromTheme("vscroll_down_default.png"); buttons[LEFT][0] = - resman->getImage("graphics/gui/hscroll_left_default.png"); + SkinLoader::getImageFromTheme("hscroll_left_default.png"); buttons[RIGHT][0] = - resman->getImage("graphics/gui/hscroll_right_default.png"); + SkinLoader::getImageFromTheme("hscroll_right_default.png"); buttons[UP][1] = - resman->getImage("graphics/gui/vscroll_up_pressed.png"); + SkinLoader::getImageFromTheme("vscroll_up_pressed.png"); buttons[DOWN][1] = - resman->getImage("graphics/gui/vscroll_down_pressed.png"); + SkinLoader::getImageFromTheme("vscroll_down_pressed.png"); buttons[LEFT][1] = - resman->getImage("graphics/gui/hscroll_left_pressed.png"); + SkinLoader::getImageFromTheme("hscroll_left_pressed.png"); buttons[RIGHT][1] = - resman->getImage("graphics/gui/hscroll_right_pressed.png"); + SkinLoader::getImageFromTheme("hscroll_right_pressed.png"); } instances++; diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp index f02c6b5c..af36518a 100644 --- a/src/gui/widgets/slider.cpp +++ b/src/gui/widgets/slider.cpp @@ -27,7 +27,6 @@ #include "gui/skin.h" #include "resources/image.h" -#include "resources/resourcemanager.h" Image *Slider::hStart, *Slider::hMid, *Slider::hEnd, *Slider::hGrip; Image *Slider::vStart, *Slider::vMid, *Slider::vEnd, *Slider::vGrip; @@ -83,9 +82,8 @@ void Slider::init() // Load resources if (mInstances == 0) { - ResourceManager *resman = ResourceManager::getInstance(); - Image *slider = resman->getImage("graphics/gui/slider.png"); - Image *sliderHi = resman->getImage("graphics/gui/slider_hilight.png"); + Image *slider = SkinLoader::getImageFromTheme("slider.png"); + Image *sliderHi = SkinLoader::getImageFromTheme("slider_hilight.png"); x = 0; y = 0; w = 15; h = 6; diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index 68dc2190..17145eae 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -30,7 +30,6 @@ #include "gui/widgets/tabbedarea.h" #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/dtor.h" @@ -55,10 +54,10 @@ struct TabData }; static TabData const data[TAB_COUNT] = { - { "graphics/gui/tab.png", 0, 0 }, - { "graphics/gui/tab_hilight.png", 9, 4 }, - { "graphics/gui/tabselected.png", 16, 19 }, - { "graphics/gui/tab.png", 25, 23 } + { "tab.png", 0, 0 }, + { "tab_hilight.png", 9, 4 }, + { "tabselected.png", 16, 19 }, + { "tab.png", 25, 23 } }; ImageRect Tab::tabImg[TAB_COUNT]; @@ -91,14 +90,13 @@ void Tab::init() if (mInstances == 0) { // Load the skin - ResourceManager *resman = ResourceManager::getInstance(); Image *tab[TAB_COUNT]; int a, x, y, mode; for (mode = 0; mode < TAB_COUNT; mode++) { - tab[mode] = resman->getImage(data[mode].file); + tab[mode] = SkinLoader::getImageFromTheme(data[mode].file); a = 0; for (y = 0; y < 3; y++) { diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 278b4cb9..e599c37d 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -29,7 +29,6 @@ #include "gui/skin.h" #include "resources/image.h" -#include "resources/resourcemanager.h" #include "utils/copynpaste.h" #include "utils/dtor.h" @@ -53,8 +52,7 @@ TextField::TextField(const std::string &text, bool loseFocusOnTab): if (instances == 0) { // Load the skin - ResourceManager *resman = ResourceManager::getInstance(); - Image *textbox = resman->getImage("graphics/gui/deepbox.png"); + Image *textbox = SkinLoader::getImageFromTheme("deepbox.png"); int gridx[4] = {0, 3, 28, 31}; int gridy[4] = {0, 3, 28, 31}; int a = 0, x, y; diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 8505f552..83c918cf 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -27,6 +27,7 @@ #include "gui/gui.h" #include "gui/palette.h" #include "gui/skin.h" +#include "gui/viewport.h" #include "gui/widgets/layout.h" #include "gui/widgets/resizegrip.h" @@ -430,6 +431,9 @@ void Window::mouseMoved(gcn::MouseEvent &event) default: gui->setCursorType(Gui::CURSOR_POINTER); } + + if (viewport) + viewport->hideBeingPopup(); } void Window::mouseDragged(gcn::MouseEvent &event) diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h index a54016bc..b72be9d4 100644 --- a/src/gui/widgets/window.h +++ b/src/gui/widgets/window.h @@ -57,7 +57,7 @@ class Window : public gcn::Window, gcn::WidgetListener * @param skin The location where the window's skin XML can be found. */ Window(const std::string &caption = "Window", bool modal = false, - Window *parent = NULL, const std::string &skin = "graphics/gui/gui.xml"); + Window *parent = NULL, const std::string &skin = "window.xml"); /** * Destructor. Deletes all the added widgets. |