diff options
Diffstat (limited to 'src/gui/widgets/tabs')
46 files changed, 7369 insertions, 0 deletions
diff --git a/src/gui/widgets/tabs/battletab.cpp b/src/gui/widgets/tabs/battletab.cpp new file mode 100644 index 000000000..fa7e252f0 --- /dev/null +++ b/src/gui/widgets/tabs/battletab.cpp @@ -0,0 +1,48 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/battletab.h" + +#include "chatlogger.h" +#include "configuration.h" + +#include "utils/gettext.h" + +#include "debug.h" + +BattleTab::BattleTab(const Widget2 *const widget) : + // TRANSLATORS: battle chat tab name + ChatTab(widget, _("Battle"), "") +{ + if (config.getBoolValue("showChatHistory")) + loadFromLogFile("#Battle"); +} + +BattleTab::~BattleTab() +{ +} + +void BattleTab::saveToLogFile(const std::string &msg) const +{ + if (chatLogger) + chatLogger->log(std::string("#Battle"), std::string(msg)); +} diff --git a/src/gui/widgets/tabs/battletab.h b/src/gui/widgets/tabs/battletab.h new file mode 100644 index 000000000..b4aa1d1df --- /dev/null +++ b/src/gui/widgets/tabs/battletab.h @@ -0,0 +1,48 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_BATTLETAB_H +#define GUI_WIDGETS_BATTLETAB_H + +#include "gui/widgets/tabs/chattab.h" + +/** + * A tab for a party chat channel. + */ +class BattleTab final : public ChatTab +{ + public: + explicit BattleTab(const Widget2 *const widget); + + A_DELETE_COPY(BattleTab) + + ~BattleTab(); + + int getType() const override A_WARN_UNUSED + { return ChatTab::TAB_BATTLE; } + + void saveToLogFile(const std::string &msg) const override; +}; + +extern BattleTab *battleChatTab; + +#endif // GUI_WIDGETS_BATTLETAB_H diff --git a/src/gui/widgets/tabs/chattab.cpp b/src/gui/widgets/tabs/chattab.cpp new file mode 100644 index 000000000..2c0628581 --- /dev/null +++ b/src/gui/widgets/tabs/chattab.cpp @@ -0,0 +1,547 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/chattab.h" + +#include "chatlogger.h" +#include "client.h" +#include "commandhandler.h" +#include "configuration.h" +#include "soundconsts.h" +#include "soundmanager.h" + +#include "being/localplayer.h" + +#include "gui/windows/helpwindow.h" + +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/itemlinkhandler.h" +#include "gui/widgets/tabbedarea.h" + +#include "net/chathandler.h" +#include "net/net.h" + +#include "resources/iteminfo.h" +#include "resources/itemdb.h" + +#include "utils/gettext.h" + +#include "debug.h" + +static const unsigned int MAX_WORD_SIZE = 50; + +ChatTab::ChatTab(const Widget2 *const widget, const std::string &name, + const std::string &channel) : + Tab(widget), + mTextOutput(new BrowserBox(this, BrowserBox::AUTO_WRAP)), + mScrollArea(new ScrollArea(mTextOutput, false)), + mChannelName(channel), + mAllowHightlight(true), + mRemoveNames(false), + mNoAway(false), + mShowOnline(false) +{ + setCaption(name); + + mTextOutput->setOpaque(false); + mTextOutput->setMaxRow(config.getIntValue("ChatLogLength")); + if (chatWindow) + mTextOutput->setLinkHandler(chatWindow->mItemLinkHandler); + mTextOutput->setAlwaysUpdate(false); + + mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, + gcn::ScrollArea::SHOW_ALWAYS); + mScrollArea->setScrollAmount(0, 1); + + if (chatWindow) + chatWindow->addTab(this); +} + +ChatTab::~ChatTab() +{ + if (chatWindow) + chatWindow->removeTab(this); + + delete mTextOutput; + mTextOutput = nullptr; + delete mScrollArea; + mScrollArea = nullptr; +} + +void ChatTab::chatLog(std::string line, Own own, + const bool ignoreRecord, const bool tryRemoveColors) +{ + // Trim whitespace + trim(line); + + if (line.empty()) + return; + + if (tryRemoveColors && own == BY_OTHER && + config.getBoolValue("removeColors")) + { + line = removeColors(line); + if (line.empty()) + return; + } + + const unsigned lineLim = config.getIntValue("chatMaxCharLimit"); + if (lineLim > 0 && line.length() > lineLim) + line = line.substr(0, lineLim); + + if (line.empty()) + return; + + CHATLOG tmp; + tmp.own = own; + tmp.nick.clear(); + tmp.text = line; + + const size_t pos = line.find(" : "); + if (pos != std::string::npos) + { + if (line.length() <= pos + 3) + return; + + tmp.nick = line.substr(0, pos); + tmp.text = line.substr(pos + 3); + } + else + { + // Fix the owner of welcome message. + if (line.length() > 7 && line.substr(0, 7) == "Welcome") + own = BY_SERVER; + } + + // *implements actions in a backwards compatible way* + if ((own == BY_PLAYER || own == BY_OTHER) && + tmp.text.at(0) == '*' && + tmp.text.at(tmp.text.length()-1) == '*') + { + tmp.text[0] = ' '; + tmp.text.erase(tmp.text.length() - 1); + own = ACT_IS; + } + + std::string lineColor("##C"); + switch (own) + { + case BY_GM: + if (tmp.nick.empty()) + { + // TRANSLATORS: chat message + tmp.nick = std::string(_("Global announcement:")).append(" "); + lineColor = "##G"; + } + else + { + // TRANSLATORS: chat message + tmp.nick = strprintf(_("Global announcement from %s:"), + tmp.nick.c_str()).append(" "); + lineColor = "##g"; // Equiv. to BrowserBox::RED + } + break; + case BY_PLAYER: + tmp.nick.append(": "); + lineColor = "##Y"; + break; + case BY_OTHER: + case BY_UNKNOWN: + tmp.nick.append(": "); + lineColor = "##C"; + break; + case BY_SERVER: + // TRANSLATORS: chat message + tmp.nick.clear(); + tmp.text = line; + lineColor = "##S"; + break; + case BY_CHANNEL: + tmp.nick.clear(); + lineColor = "##2"; // Equiv. to BrowserBox::GREEN + break; + case ACT_WHISPER: + // TRANSLATORS: chat message + tmp.nick = strprintf(_("%s whispers: %s"), tmp.nick.c_str(), ""); + lineColor = "##W"; + break; + case ACT_IS: + lineColor = "##I"; + break; + case BY_LOGGER: + tmp.nick.clear(); + tmp.text = line; + lineColor = "##L"; + break; + default: + break; + } + + if (tmp.nick == ": ") + { + tmp.nick.clear(); + lineColor = "##S"; + } + + // if configured, move magic messages log to debug chat tab + if (localChatTab && this == localChatTab + && ((config.getBoolValue("showMagicInDebug") && own == BY_PLAYER + && tmp.text.length() > 1 && tmp.text.at(0) == '#' + && tmp.text.at(1) != '#') + || (config.getBoolValue("serverMsgInDebug") && (own == BY_SERVER + || tmp.nick.empty())))) + { + if (debugChatTab) + debugChatTab->chatLog(line, own, ignoreRecord, tryRemoveColors); + return; + } + + // Get the current system time + time_t t; + time(&t); + + if (config.getBoolValue("useLocalTime")) + { + const struct tm *timeInfo; + timeInfo = localtime(&t); + 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 + { + // Format the time string properly + std::stringstream timeStr; + timeStr << "[" << ((((t / 60) / 60) % 24 < 10) ? "0" : "") + << static_cast<int>(((t / 60) / 60) % 24) + << ":" << (((t / 60) % 60 < 10) ? "0" : "") + << static_cast<int>((t / 60) % 60) + << "] "; + line = std::string(lineColor).append(timeStr.str()).append( + tmp.nick).append(tmp.text); + } + + if (config.getBoolValue("enableChatLog")) + saveToLogFile(line); + + mTextOutput->setMaxRow(config.getIntValue("chatMaxLinesLimit")); + + // We look if the Vertical Scroll Bar is set at the max before + // adding a row, otherwise the max will always be a row higher + // at comparison. + if (mScrollArea->getVerticalScrollAmount() + 2 >= + mScrollArea->getVerticalMaxScroll()) + { + addRow(line); + mScrollArea->setVerticalScrollAmount( + mScrollArea->getVerticalMaxScroll()); + } + else + { + addRow(line); + } + + if (chatWindow && this == localChatTab) + chatWindow->addToAwayLog(line); + + mScrollArea->logic(); + if (own != BY_PLAYER) + { + if (own == BY_SERVER && (getType() == TAB_PARTY + || getType() == TAB_GUILD)) + { + return; + } + + const TabbedArea *const tabArea = getTabbedArea(); + if (!tabArea) + return; + + if (this != tabArea->getSelectedTab()) + { + if (getFlash() == 0) + { + if (chatWindow && chatWindow->findHighlight(tmp.text)) + { + setFlash(2); + soundManager.playGuiSound(SOUND_HIGHLIGHT); + } + else + { + setFlash(1); + } + } + else if (getFlash() == 2) + { + if (chatWindow && chatWindow->findHighlight(tmp.text)) + soundManager.playGuiSound(SOUND_HIGHLIGHT); + } + } + + if ((getAllowHighlight() || own == BY_GM) + && (this != tabArea->getSelectedTab() + || (client->getIsMinimized() || (!client->getMouseFocused() + && !client->getInputFocused())))) + { + if (own == BY_GM) + { + if (chatWindow) + chatWindow->unHideWindow(); + soundManager.playGuiSound(SOUND_GLOBAL); + } + else if (own != BY_SERVER) + { + if (chatWindow) + chatWindow->unHideWindow(); + playNewMessageSound(); + } + client->newChatMessage(); + } + } +} + +void ChatTab::chatLog(const std::string &nick, std::string msg) +{ + const Own byWho = (nick == player_node->getName() ? BY_PLAYER : BY_OTHER); + if (byWho == BY_OTHER && config.getBoolValue("removeColors")) + msg = removeColors(msg); + chatLog(std::string(nick).append(" : ").append(msg), byWho, false, false); +} + +void ChatTab::chatInput(const std::string &message) +{ + std::string msg = message; + trim(msg); + + if (msg.empty()) + return; + + // Check for item link + size_t start = msg.find('['); + size_t sz = msg.size(); + while (start + 1 < sz && start != std::string::npos + && msg[start + 1] != '@') + { + const size_t end = msg.find(']', start); + if (start + 1 != end && end != std::string::npos) + { + // Catch multiple embeds and ignore them + // so it doesn't crash the client. + while ((msg.find('[', start + 1) != std::string::npos) && + (msg.find('[', start + 1) < end)) + { + start = msg.find('[', start + 1); + } + + std::string temp; + if (start + 1 < sz && end < sz && end > start + 1) + { + temp = msg.substr(start + 1, end - start - 1); + + const ItemInfo &itemInfo = ItemDB::get(temp); + if (itemInfo.getId() != 0) + { + msg.insert(end, "@@"); + msg.insert(start + 1, "|"); + msg.insert(start + 1, toString(itemInfo.getId())); + msg.insert(start + 1, "@@"); + sz = msg.size(); + } + } + } + start = msg.find('[', start + 1); + } + + Commands::replaceVars(msg); + + switch (msg[0]) + { + case '/': + handleCommand(std::string(msg, 1)); + break; + case '?': + if (msg.size() > 1) + handleHelp(std::string(msg, 1)); + else + handleInput(msg); + break; + default: + handleInput(msg); + break; + } +} + +void ChatTab::scroll(const int amount) +{ + const int range = mScrollArea->getHeight() / 8 * amount; + gcn::Rectangle scr; + scr.y = mScrollArea->getVerticalScrollAmount() + range; + scr.height = abs(range); + mTextOutput->showPart(scr); +} + +void ChatTab::clearText() +{ + mTextOutput->clearRows(); +} + +void ChatTab::handleInput(const std::string &msg) +{ + if (chatWindow) + { + Net::getChatHandler()->talk(chatWindow->doReplace(msg), + mChannelName); + } + else + { + Net::getChatHandler()->talk(msg, mChannelName); + } +} + +void ChatTab::handleCommand(const std::string &msg) +{ + if (commandHandler) + commandHandler->handleCommands(msg, this); +} + +void ChatTab::handleHelp(const std::string &msg) +{ + if (commandHandler) + helpWindow->search(msg); +} + +bool ChatTab::handleCommands(const std::string &type, const std::string &args) +{ + // need split to commands and call each + + return handleCommand(type, args); +} + +void ChatTab::saveToLogFile(const std::string &msg) const +{ + if (chatLogger) + { + if (getType() == TAB_INPUT) + { + chatLogger->log(msg); + } + else if (getType() == TAB_DEBUG + && config.getBoolValue("enableDebugLog")) + { + chatLogger->log("#Debug", msg); + } + } +} + +int ChatTab::getType() const +{ + if (getCaption() == "General" || getCaption() == _("General")) + return TAB_INPUT; + else if (getCaption() == "Debug" || getCaption() == _("Debug")) + return TAB_DEBUG; + else + return TAB_UNKNOWN; +} + +void ChatTab::addRow(std::string &line) +{ + if (line.find("[@@http") == std::string::npos) + { + size_t idx = 0; + for (size_t f = 0; f < line.length(); f++) + { + if (line.at(f) == ' ') + { + idx = f; + } + else if (f - idx > MAX_WORD_SIZE) + { + line.insert(f, " "); + idx = f; + } + } + } + mTextOutput->addRow(line); +} + +void ChatTab::loadFromLogFile(const std::string &name) +{ + if (chatLogger) + { + std::list<std::string> list; + chatLogger->loadLast(name, list, 5); + std::list<std::string>::const_iterator i = list.begin(); + while (i != list.end()) + { + std::string line("##9" + *i); + addRow(line); + ++i; + } + } +} + +void ChatTab::addNewRow(std::string &line) +{ + if (mScrollArea->getVerticalScrollAmount() >= + mScrollArea->getVerticalMaxScroll()) + { + addRow(line); + mScrollArea->setVerticalScrollAmount( + mScrollArea->getVerticalMaxScroll()); + } + else + { + addRow(line); + } + mScrollArea->logic(); +} + +void ChatTab::playNewMessageSound() const +{ + soundManager.playGuiSound(SOUND_WHISPER); +} + +void ChatTab::showOnline(const std::string &nick, + const bool isOnline) +{ + if (!mShowOnline) + return; + + if (isOnline) + { + // TRANSLATORS: chat message + chatLog(strprintf(_("%s is now Online."), nick.c_str())); + } + else + { + // TRANSLATORS: chat message + chatLog(strprintf(_("%s is now Offline."), nick.c_str())); + } +} diff --git a/src/gui/widgets/tabs/chattab.h b/src/gui/widgets/tabs/chattab.h new file mode 100644 index 000000000..e7744a8c1 --- /dev/null +++ b/src/gui/widgets/tabs/chattab.h @@ -0,0 +1,212 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_CHATTAB_H +#define GUI_WIDGETS_CHATTAB_H + +#include "gui/windows/chatwindow.h" + +#include "gui/widgets/browserbox.h" +#include "gui/widgets/tabs/tab.h" + +#include "localconsts.h" + +class ScrollArea; + +const std::string GENERAL_CHANNEL = ""; +const std::string TRADE_CHANNEL = ""; + +/** + * A tab for the chat window. This is special to ease chat handling. + */ +class ChatTab : public Tab +{ + public: + enum Type + { + TAB_UNKNOWN = 0, + TAB_INPUT, + TAB_WHISPER, + TAB_PARTY, + TAB_GUILD, + TAB_DEBUG, + TAB_TRADE, + TAB_BATTLE, + TAB_LANG, + TAB_GM + }; + + /** + * Constructor. + */ + ChatTab(const Widget2 *const widget, const std::string &name, + const std::string &channel); + + A_DELETE_COPY(ChatTab) + + virtual ~ChatTab(); + + /** + * Adds a line of text to our message list. Parameters: + * + * @param line Text message. + * @param own Type of message (usually the owner-type). + * @param channelName which channel to send the message to. + * @param ignoreRecord should this not be recorded? + * @param removeColors try remove color if configured + */ + void chatLog(std::string line, Own own = BY_SERVER, + const bool ignoreRecord = false, + const bool tryRemoveColors = true); + + /** + * Adds the text to the message list + * + * @param msg The message text which is to be sent. + */ + void chatLog(const std::string &nick, std::string msg); + + /** + * Determines whether the message is a command or message, then + * sends the given message to the game server to be said, or to the + * command handler + * + * @param msg The message text which is to be sent. + */ + void chatInput(const std::string &msg); + + /** + * Scrolls the chat window + * + * @param amount direction and amount to scroll. Negative numbers scroll + * up, positive numbers scroll down. The absolute amount indicates the + * amount of 1/8ths of chat window real estate that should be scrolled. + */ + void scroll(const int amount); + + /** + * Clears the text from the tab + */ + void clearText(); + + /** + * Add any extra help text to the output. Allows tabs to define help + * for commands defined by the tab itself. + */ + virtual void showHelp() + { } + + /** + * Handle special commands. Allows a tab to handle commands it + * defines itself. + * + * @returns true if the command was handled + * false if the command was not handled + */ + virtual bool handleCommand(const std::string &type A_UNUSED, + const std::string &args A_UNUSED) + { return false; } + + /** + * Handle special commands. Allows a tab to handle commands it + * defines itself. + * + * @returns true if the command was handled + * false if the command was not handled + */ + virtual bool handleCommands(const std::string &type, + const std::string &args); + + /** + * Returns type of the being. + */ + virtual int getType() const A_WARN_UNUSED; + + virtual void saveToLogFile(const std::string &msg) const; + + const std::list<std::string> &getRows() const A_WARN_UNUSED + { return mTextOutput->getRows(); } + + bool hasRows() const A_WARN_UNUSED + { return mTextOutput->hasRows(); } + + void loadFromLogFile(const std::string &name); + + bool getAllowHighlight() const A_WARN_UNUSED + { return mAllowHightlight; } + + void setAllowHighlight(const bool n) + { mAllowHightlight = n; } + + bool getRemoveNames() const A_WARN_UNUSED + { return mRemoveNames; } + + void setRemoveNames(const bool n) + { mRemoveNames = n; } + + bool getNoAway() const A_WARN_UNUSED + { return mNoAway; } + + void setNoAway(const bool n) + { mNoAway = n; } + + void addNewRow(std::string &line); + + void showOnline(const std::string &nick, + const bool isOnline); + + virtual void playNewMessageSound() const; + + const std::string &getChannelName() const + { return mChannelName; } + + protected: + friend class ChatWindow; + friend class WhisperWindow; + + virtual void setCurrent() override + { setFlash(0); } + + virtual void handleInput(const std::string &msg); + + virtual void handleCommand(const std::string &msg); + + virtual void handleHelp(const std::string &msg); + + virtual void getAutoCompleteList(StringVect&) const + {} + + void addRow(std::string &line); + + BrowserBox *mTextOutput; + ScrollArea *mScrollArea; + std::string mChannelName; + bool mAllowHightlight; + bool mRemoveNames; + bool mNoAway; + bool mShowOnline; +}; + +extern ChatTab *localChatTab; +extern ChatTab *debugChatTab; + +#endif // GUI_WIDGETS_CHATTAB_H diff --git a/src/gui/widgets/tabs/gmtab.cpp b/src/gui/widgets/tabs/gmtab.cpp new file mode 100644 index 000000000..25ec67f19 --- /dev/null +++ b/src/gui/widgets/tabs/gmtab.cpp @@ -0,0 +1,62 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/gmtab.h" + +#include "chatlogger.h" + +#include "utils/gettext.h" + +#include "debug.h" + +GmTab::GmTab(const Widget2 *const widget) : + // TRANSLATORS: gb tab name + ChatTab(widget, _("GM"), "") +{ + setTabColor(&getThemeColor(Theme::GM_CHAT_TAB), + &getThemeColor(Theme::GM_CHAT_TAB_OUTLINE)); + setHighlightedTabColor(&getThemeColor(Theme::GM_CHAT_TAB_HIGHLIGHTED), + &getThemeColor(Theme::GM_CHAT_TAB_HIGHLIGHTED_OUTLINE)); + setSelectedTabColor(&getThemeColor(Theme::GM_CHAT_TAB_SELECTED), + &getThemeColor(Theme::GM_CHAT_TAB_SELECTED_OUTLINE)); +} + +GmTab::~GmTab() +{ +} + +void GmTab::handleInput(const std::string &msg) +{ + ChatTab::handleInput("@wgm " + msg); +} + +void GmTab::handleCommand(const std::string &msg A_UNUSED) +{ +} + +void GmTab::saveToLogFile(const std::string &msg) const +{ + if (chatLogger) + chatLogger->log("#GM", msg); +} + +void GmTab::getAutoCompleteList(StringVect &names A_UNUSED) const +{ +} diff --git a/src/gui/widgets/tabs/gmtab.h b/src/gui/widgets/tabs/gmtab.h new file mode 100644 index 000000000..28ccabe8a --- /dev/null +++ b/src/gui/widgets/tabs/gmtab.h @@ -0,0 +1,53 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_GMTAB_H +#define GUI_WIDGETS_GMTAB_H + +#include "gui/widgets/tabs/chattab.h" + +/** + * A tab for whispers from a single player. + */ +class GmTab final : public ChatTab +{ + public: + explicit GmTab(const Widget2 *const widget); + + A_DELETE_COPY(GmTab) + + ~GmTab(); + + int getType() const override A_WARN_UNUSED + { return ChatTab::TAB_GM; } + + void saveToLogFile(const std::string &msg) const override; + + protected: + void getAutoCompleteList(StringVect &names) const override; + + void handleInput(const std::string &msg) override; + + void handleCommand(const std::string &msg) override; +}; + +extern GmTab *gmChatTab; + +#endif // GUI_WIDGETS_GMTAB_H diff --git a/src/gui/widgets/tabs/guildchattab.cpp b/src/gui/widgets/tabs/guildchattab.cpp new file mode 100644 index 000000000..4188a8843 --- /dev/null +++ b/src/gui/widgets/tabs/guildchattab.cpp @@ -0,0 +1,152 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/guildchattab.h" + +#include "chatlogger.h" +#include "configuration.h" +#include "guildmanager.h" +#include "soundconsts.h" +#include "soundmanager.h" + +#include "utils/gettext.h" + +#include "debug.h" + +GuildChatTab::GuildChatTab(const Widget2 *const widget) : + // TRANSLATORS: guild chat tab name + ChatTab(widget, _("Guild"), "") +{ + setTabColor(&getThemeColor(Theme::GUILD_CHAT_TAB), + &getThemeColor(Theme::GUILD_CHAT_TAB_OUTLINE)); + setHighlightedTabColor(&getThemeColor(Theme::GUILD_CHAT_TAB_HIGHLIGHTED), + &getThemeColor(Theme::GUILD_CHAT_TAB_HIGHLIGHTED_OUTLINE)); + setSelectedTabColor(&getThemeColor(Theme::GUILD_CHAT_TAB_SELECTED), + &getThemeColor(Theme::GUILD_CHAT_TAB_SELECTED_OUTLINE)); + mShowOnline = config.getBoolValue("showGuildOnline"); + config.addListener("showGuildOnline", this); +} + +GuildChatTab::~GuildChatTab() +{ + config.removeListeners(this); +} + +bool GuildChatTab::handleCommand(const std::string &type, + const std::string &args) +{ + if (type == "help") + { + if (args == "invite") + { + // TRANSLATORS: guild chat tab help + chatLog(_("Command: /invite <nick>")); + // TRANSLATORS: guild chat tab help + chatLog(_("This command invites <nick> to the guild you're in.")); + // TRANSLATORS: guild chat tab help + chatLog(_("If the <nick> has spaces in it, enclose it in " + "double quotes (\").")); + } + else if (args == "leave") + { + // TRANSLATORS: guild chat tab help + chatLog(_("Command: /leave")); + // TRANSLATORS: guild chat tab help + chatLog(_("This command causes the player to leave the guild.")); + } + else + { + return false; + } + } + else if (type == "invite" && guildManager) + { + guildManager->invite(args); + } + else if (type == "leave" && guildManager) + { + guildManager->leave(); + } + else if (type == "kick" && guildManager) + { + guildManager->kick(args); + } + else if (type == "notice" && guildManager) + { + guildManager->notice(args); + } + else + { + return false; + } + + return true; +} + +void GuildChatTab::handleInput(const std::string &msg) +{ + if (!guildManager) + return; + + if (chatWindow) + guildManager->chat(chatWindow->doReplace(msg)); + else + guildManager->chat(msg); +} + +void GuildChatTab::showHelp() +{ + // TRANSLATORS: guild chat tab help + chatLog(_("/help > Display this help.")); + // TRANSLATORS: guild chat tab help + chatLog(_("/invite > Invite a player to your guild")); + // TRANSLATORS: guild chat tab help + chatLog(_("/leave > Leave the guild you are in")); + // TRANSLATORS: guild chat tab help + chatLog(_("/kick > Kick someone from the guild you are in")); +} + +void GuildChatTab::getAutoCompleteList(StringVect &names) const +{ + if (!guildManager) + return; + + guildManager->getNames(names); + names.push_back("/notice "); +} + +void GuildChatTab::saveToLogFile(const std::string &msg) const +{ + if (chatLogger) + chatLogger->log("#Guild", msg); +} + +void GuildChatTab::playNewMessageSound() const +{ + soundManager.playGuiSound(SOUND_GUILD); +} + +void GuildChatTab::optionChanged(const std::string &value) +{ + if (value == "showGuildOnline") + mShowOnline = config.getBoolValue("showGuildOnline"); +} diff --git a/src/gui/widgets/tabs/guildchattab.h b/src/gui/widgets/tabs/guildchattab.h new file mode 100644 index 000000000..f7aebcf55 --- /dev/null +++ b/src/gui/widgets/tabs/guildchattab.h @@ -0,0 +1,60 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_GUILDCHATTAB_H +#define GUI_WIDGETS_GUILDCHATTAB_H + +#include "gui/widgets/tabs/chattab.h" + +/** + * A tab for a guild chat channel. + */ +class GuildChatTab final : public ChatTab, public ConfigListener +{ + public: + explicit GuildChatTab(const Widget2 *const widget); + + A_DELETE_COPY(GuildChatTab) + + ~GuildChatTab(); + + bool handleCommand(const std::string &type, + const std::string &args) override; + + void showHelp() override; + + void saveToLogFile(const std::string &msg) const override; + + int getType() const override A_WARN_UNUSED + { return ChatTab::TAB_GUILD; } + + void playNewMessageSound() const override; + + void optionChanged(const std::string &value) override; + + protected: + void handleInput(const std::string &msg) override; + + void getAutoCompleteList(StringVect &names) const override; +}; + +#endif // GUI_WIDGETS_GUILDCHATTAB_H diff --git a/src/gui/widgets/tabs/langtab.cpp b/src/gui/widgets/tabs/langtab.cpp new file mode 100644 index 000000000..7bea453c7 --- /dev/null +++ b/src/gui/widgets/tabs/langtab.cpp @@ -0,0 +1,43 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/langtab.h" + +#include "chatlogger.h" + +#include "utils/gettext.h" + +#include "debug.h" + +LangTab::LangTab(const Widget2 *const widget, const std::string &lang) : + // TRANSLATORS: lang chat tab name + ChatTab(widget, _("Lang"), lang + " ") +{ +} + +LangTab::~LangTab() +{ +} + +void LangTab::saveToLogFile(const std::string &msg) const +{ + if (chatLogger) + chatLogger->log(std::string("#Lang"), std::string(msg)); +} diff --git a/src/gui/widgets/tabs/langtab.h b/src/gui/widgets/tabs/langtab.h new file mode 100644 index 000000000..fa4e7c08c --- /dev/null +++ b/src/gui/widgets/tabs/langtab.h @@ -0,0 +1,43 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_LANGTAB_H +#define GUI_WIDGETS_LANGTAB_H + +#include "gui/widgets/tabs/chattab.h" + +class LangTab final : public ChatTab +{ + public: + LangTab(const Widget2 *const widget, const std::string &lang); + + A_DELETE_COPY(LangTab) + + ~LangTab(); + + int getType() const override A_WARN_UNUSED + { return ChatTab::TAB_LANG; } + + void saveToLogFile(const std::string &msg) const override; +}; + +extern LangTab *langChatTab; + +#endif // GUI_WIDGETS_LANGTAB_H diff --git a/src/gui/widgets/tabs/setup_audio.cpp b/src/gui/widgets/tabs/setup_audio.cpp new file mode 100644 index 000000000..219cf30f2 --- /dev/null +++ b/src/gui/widgets/tabs/setup_audio.cpp @@ -0,0 +1,204 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_audio.h" + +#include "main.h" +#include "map.h" + +#include "configuration.h" +#include "soundmanager.h" + +#include "gui/viewport.h" + +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/namesmodel.h" +#include "gui/widgets/scrollarea.h" + +#include "utils/gettext.h" + +#include "debug.h" + +class SoundsModel final : public NamesModel +{ +public: + SoundsModel() : + NamesModel() + { + mNames.push_back(gettext("(no sound)")); + Theme::fillSoundsList(mNames); + } + + ~SoundsModel() + { } +}; + +Setup_Audio::Setup_Audio(const Widget2 *const widget) : + SetupTabScroll(widget), + mSoundModel(new SoundsModel), + mChannelsList(new SetupItemNames) +{ + // TRANSLATORS: audio tab in settings + setName(_("Audio")); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + place(0, 0, mScroll, 10, 10); + + // TRANSLATORS: settings option + new SetupItemLabel(_("Basic settings"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable Audio"), "", "sound", this, "soundEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable music"), "", + "playMusic", this, "playMusicEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable game sfx"), "", + "playBattleSound", this, "playBattleSoundEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable gui sfx"), "", + "playGuiSound", this, "playGuiSoundEvent"); + + // TRANSLATORS: settings option + new SetupItemSlider(_("Sfx volume"), "", "sfxVolume", + this, "sfxVolumeEvent", 0, soundManager.getMaxVolume(), 150, true); + + // TRANSLATORS: settings option + new SetupItemSlider(_("Music volume"), "", "musicVolume", + this, "musicVolumeEvent", 0, soundManager.getMaxVolume(), 150, true); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable music fade out"), "", + "fadeoutmusic", this, "fadeoutmusicEvent"); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Audio frequency"), "", + "audioFrequency", this, "audioFrequencyEvent", 14000, 192000); + + // TRANSLATORS: audio type + mChannelsList->push_back(_("mono")); + // TRANSLATORS: audio type + mChannelsList->push_back(_("stereo")); + // TRANSLATORS: audio type + mChannelsList->push_back(_("surround")); + // TRANSLATORS: audio type + mChannelsList->push_back(_("surround+center+lfe")); + // TRANSLATORS: settings option + new SetupItemSlider2(_("Audio channels"), "", "audioChannels", this, + "audioChannels", 1, 4, mChannelsList); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Sound effects"), "", this); + + // TRANSLATORS: settings option + new SetupItemSound(_("Information dialog sound"), "", + "soundinfo", this, "soundinfoEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Request dialog sound"), "", + "soundrequest", this, "soundrequestEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Whisper message sound"), "", + "soundwhisper", this, "soundwhisperEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Guild / Party message sound"), "", + "soundguild", this, "soundguildEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Highlight message sound"), "", + "soundhighlight", this, "soundhighlightEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Global message sound"), "", + "soundglobal", this, "soundglobalEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Error message sound"), "", + "sounderror", this, "sounderrorEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Trade request sound"), "", + "soundtrade", this, "soundtradeEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Show window sound"), "", + "soundshowwindow", this, "soundshowwindowEvent", mSoundModel); + + // TRANSLATORS: settings option + new SetupItemSound(_("Hide window sound"), "", + "soundhidewindow", this, "soundhidewindowEvent", mSoundModel); + + // TRANSLATORS: settings group + new SetupItemLabel(_("Other"), "", this); + +#ifdef USE_MUMBLE + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable mumble voice chat"), "", + "enableMumble", this, "enableMumbleEvent"); +#endif + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Download music"), "", + "download-music", this, "download-musicEvent"); + + setDimension(gcn::Rectangle(0, 0, 550, 350)); +} + +Setup_Audio::~Setup_Audio() +{ + delete mSoundModel; + mSoundModel = nullptr; + + delete mChannelsList; + mChannelsList = nullptr; +} + +void Setup_Audio::apply() +{ + SetupTabScroll::apply(); + if (config.getBoolValue("sound")) + { + soundManager.init(); + if (viewport && config.getBoolValue("playMusic")) + { + const Map *const map = viewport->getMap(); + if (map) + soundManager.playMusic(map->getMusicFile()); + } + else + { + soundManager.stopMusic(); + } + } + else + { + soundManager.close(); + } +} diff --git a/src/gui/widgets/tabs/setup_audio.h b/src/gui/widgets/tabs/setup_audio.h new file mode 100644 index 000000000..98cdc5470 --- /dev/null +++ b/src/gui/widgets/tabs/setup_audio.h @@ -0,0 +1,45 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_AUDIO_H +#define GUI_SETUP_AUDIO_H + +#include "gui/widgets/setupitem.h" + +class Setup_Audio final : public SetupTabScroll +{ + public: + explicit Setup_Audio(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Audio) + + ~Setup_Audio(); + + void apply() override; + + private: + gcn::ListModel *mSoundModel; + + SetupItemNames *mChannelsList; +}; + +#endif // GUI_SETUP_AUDIO_H diff --git a/src/gui/widgets/tabs/setup_chat.cpp b/src/gui/widgets/tabs/setup_chat.cpp new file mode 100644 index 000000000..e5acd10e5 --- /dev/null +++ b/src/gui/widgets/tabs/setup_chat.cpp @@ -0,0 +1,208 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_chat.h" + +#include "gui/windows/chatwindow.h" + +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/setupitem.h" + +#include "utils/gettext.h" + +#include "debug.h" + +extern int serverVersion; + +Setup_Chat::Setup_Chat(const Widget2 *const widget) : + SetupTabScroll(widget) +{ + // TRANSLATORS: settings tab name + setName(_("Chat")); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + place(0, 0, mScroll, 10, 10); + + // TRANSLATORS: settings group + new SetupItemLabel(_("Window"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Auto hide chat window"), "", + "autohideChat", this, "autohideChatEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Protect chat focus"), "", + "protectChatFocus", this, "protectChatFocusEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Colors"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Remove colors from received chat messages"), "", + "removeColors", this, "removeColorsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show chat colors list"), "", + "showChatColorsList", this, "showChatColorsListEvent"); + + + // TRANSLATORS: settings option + new SetupItemLabel(_("Commands"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Allow magic and GM commands in all chat tabs"), + "", "allowCommandsInChatTabs", this, "allowCommandsInChatTabsEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Limits"), "", this); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Limit max chars in chat line"), "", + "chatMaxCharLimit", this, "chatMaxCharLimitEvent", 0, 500); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Limit max lines in chat"), "", + "chatMaxLinesLimit", this, "chatMaxLinesLimitEvent", 0, 500); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Logs"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable chat Log"), "", + "enableChatLog", this, "enableChatLogEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable debug chat Log"), "", + "enableDebugLog", this, "enableDebugLogEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show chat history"), "", + "showChatHistory", this, "showChatHistoryEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show party online messages"), "", + "showPartyOnline", this, "showPartyOnlineEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show guild online messages"), "", + "showGuildOnline", this, "showGuildOnlineEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Messages"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Hide shop messages"), "", + "hideShopMessages", this, "hideShopMessagesEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Tabs"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Put all whispers in tabs"), "", + "whispertab", this, "whispertabEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Log magic messages in debug tab"), "", + "showMagicInDebug", this, "showMagicInDebugEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show server messages in debug tab"), "", + "serverMsgInDebug", this, "serverMsgInDebugEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable trade tab"), "", + "enableTradeTab", this, "enableTradeTabEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable gm tab"), "", + "enableGmTab", this, "enableGmTabEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable language tab"), "", + "enableLangTab", this, "enableLangTabEvent", false); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show all languages messages"), "", + "showAllLang", this, "showAllLangEvent", false); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable battle tab"), "", + "enableBattleTab", this, "enableBattleTabEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show battle events"), "", + "showBattleEvents", this, "showBattleEventsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Resize chat tabs if need"), "", + "hideChatInput", this, "hideChatInputEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Time"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Use local time"), "", + "useLocalTime", this, "useLocalTimeEvent"); + + // TRANSLATORS: settings group + new SetupItemLabel(_("Other"), "", this); + + // TRANSLATORS: settings option + new SetupItemTextField(_("Highlight words (separated by comma)"), "", + "highlightWords", this, "highlightWordsEvent"); + + // TRANSLATORS: settings option + new SetupItemTextField(_("Globals ignore names (separated by comma)"), "", + "globalsFilter", this, "globalsFilterEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show MVP messages"), "", + "showMVP", this, "showMVPEvent"); + + setDimension(gcn::Rectangle(0, 0, 550, 350)); +} + +void Setup_Chat::apply() +{ + SetupTabScroll::apply(); + + if (chatWindow) + { + chatWindow->adjustTabSize(); + chatWindow->parseHighlights(); + } +} + +void Setup_Chat::externalUpdated() +{ + reread("enableLangTab"); + reread("showAllLang"); +} diff --git a/src/gui/widgets/tabs/setup_chat.h b/src/gui/widgets/tabs/setup_chat.h new file mode 100644 index 000000000..108f67a7f --- /dev/null +++ b/src/gui/widgets/tabs/setup_chat.h @@ -0,0 +1,40 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_CHAT_H +#define GUI_SETUP_CHAT_H + +#include "gui/widgets/tabs/setuptabscroll.h" + +class Setup_Chat final : public SetupTabScroll +{ + public: + explicit Setup_Chat(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Chat) + + void apply() override; + + void externalUpdated() override; +}; + +#endif // GUI_SETUP_CHAT_H diff --git a/src/gui/widgets/tabs/setup_colors.cpp b/src/gui/widgets/tabs/setup_colors.cpp new file mode 100644 index 000000000..f5b834b6a --- /dev/null +++ b/src/gui/widgets/tabs/setup_colors.cpp @@ -0,0 +1,445 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_colors.h" + +#include "gui/gui.h" +#include "gui/sdlfont.h" +#include "gui/userpalette.h" + +#include "gui/widgets/browserbox.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/listbox.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/slider.h" +#include "gui/widgets/textfield.h" +#include "gui/widgets/textpreview.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include <string> +#include <cmath> + +#include "debug.h" + +// TRANSLATORS: color selection preview message +const char *const Setup_Colors::rawmsg = + N_("This is what the color looks like"); + +Setup_Colors::Setup_Colors(const Widget2 *const widget) : + SetupTab(widget), + gcn::SelectionListener(), + mColorBox(new ListBox(this, userPalette, "")), + mScroll(new ScrollArea(mColorBox, true, "setup_colors_background.xml")), + mPreview(new BrowserBox(this, BrowserBox::AUTO_WRAP)), + mTextPreview(new TextPreview(this, gettext(rawmsg))), + mPreviewBox(new ScrollArea(mPreview, true, + "setup_colors_preview_background.xml")), + mSelected(-1), + // TRANSLATORS: colors tab. label. + mGradTypeLabel(new Label(this, _("Type:"))), + mGradTypeSlider(new Slider(0, 3)), + mGradTypeText(new Label(this)), + // TRANSLATORS: colors tab. label. + mGradDelayLabel(new Label(this, _("Delay:"))), + mGradDelaySlider(new Slider(20, 100)), + mGradDelayText(new TextField(this)), + // TRANSLATORS: colors tab. label. + mRedLabel(new Label(this, _("Red:"))), + mRedSlider(new Slider(0, 255)), + mRedText(new TextField(this)), + // TRANSLATORS: colors tab. label. + mGreenLabel(new Label(this, _("Green:"))), + mGreenSlider(new Slider(0, 255)), + mGreenText(new TextField(this)), + // TRANSLATORS: colors tab. label. + mBlueLabel(new Label(this, _("Blue:"))), + mBlueSlider(new Slider(0, 255)), + mBlueText(new TextField(this)) +{ + // TRANSLATORS: settings colors tab name + setName(_("Colors")); + mColorBox->addSelectionListener(this); + mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mPreview->setOpaque(false); + + // don't do anything with links + mPreview->setLinkHandler(nullptr); + + mPreviewBox->setHeight(20); + mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, + gcn::ScrollArea::SHOW_NEVER); + + mGradTypeSlider->setWidth(180); + mGradTypeSlider->setActionEventId("slider_grad"); + mGradTypeSlider->setValue(0); + mGradTypeSlider->addActionListener(this); + mGradTypeSlider->setEnabled(false); + + // TRANSLATORS: color type + std::string longText = _("Static"); + + const gcn::Font *const font = getFont(); + if (getFont()->getWidth(_("Pulse")) > font->getWidth(longText)) + { + // TRANSLATORS: color type + longText = _("Pulse"); + } + if (getFont()->getWidth(_("Rainbow")) > font->getWidth(longText)) + { + // TRANSLATORS: color type + longText = _("Rainbow"); + } + if (getFont()->getWidth(_("Spectrum")) > font->getWidth(longText)) + { + // TRANSLATORS: color type + longText = _("Spectrum"); + } + + mGradTypeText->setCaption(longText); + + mGradDelayText->setWidth(40); + mGradDelayText->setRange(20, 100); + mGradDelayText->setNumeric(true); + mGradDelayText->setEnabled(false); + + mGradDelaySlider->setWidth(180); + mGradDelaySlider->setValue(mGradDelayText->getValue()); + mGradDelaySlider->setActionEventId("slider_graddelay"); + mGradDelaySlider->addActionListener(this); + mGradDelaySlider->setEnabled(false); + + mRedText->setWidth(40); + mRedText->setRange(0, 255); + mRedText->setNumeric(true); + mRedText->setEnabled(false); + + mRedSlider->setWidth(180); + mRedSlider->setValue(mRedText->getValue()); + mRedSlider->setActionEventId("slider_red"); + mRedSlider->addActionListener(this); + mRedSlider->setEnabled(false); + + mGreenText->setWidth(40); + mGreenText->setRange(0, 255); + mGreenText->setNumeric(true); + mGreenText->setEnabled(false); + + mGreenSlider->setWidth(180); + mGreenSlider->setValue(mGreenText->getValue()); + mGreenSlider->setActionEventId("slider_green"); + mGreenSlider->addActionListener(this); + mGreenSlider->setEnabled(false); + + mBlueText->setWidth(40); + mBlueText->setRange(0, 255); + mBlueText->setNumeric(true); + mBlueText->setEnabled(false); + + mBlueSlider->setWidth(180); + mBlueSlider->setValue(mBlueText->getValue()); + mBlueSlider->setActionEventId("slider_blue"); + mBlueSlider->addActionListener(this); + mBlueSlider->setEnabled(false); + + setOpaque(false); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mScroll, 6, 6).setPadding(2); + place(0, 6, mPreviewBox, 6).setPadding(2); + place(0, 7, mGradTypeLabel, 3); + place(3, 7, mGradTypeSlider); + place(4, 7, mGradTypeText, 2).setPadding(1); + place(0, 8, mRedLabel, 3); + place(3, 8, mRedSlider); + place(5, 8, mRedText).setPadding(1); + place(0, 9, mGreenLabel, 3); + place(3, 9, mGreenSlider); + place(5, 9, mGreenText).setPadding(1); + place(0, 10, mBlueLabel, 3); + place(3, 10, mBlueSlider); + place(5, 10, mBlueText).setPadding(1); + place(0, 11, mGradDelayLabel, 3); + place(3, 11, mGradDelaySlider); + place(5, 11, mGradDelayText).setPadding(1); + + mGradTypeText->setCaption(""); + + setDimension(gcn::Rectangle(0, 0, 365, 350)); +} + +Setup_Colors::~Setup_Colors() +{ + if (mPreviewBox && mPreviewBox->getContent() == mPreview) + { + delete mTextPreview; + mTextPreview = nullptr; + } + else + { + delete mPreview; + mPreview = nullptr; + } +} + +void Setup_Colors::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + if (eventId == "slider_grad") + { + updateGradType(); + updateColor(); + return; + } + + if (eventId == "slider_graddelay") + { + mGradDelayText->setText(toString( + std::floor(mGradDelaySlider->getValue()))); + updateColor(); + return; + } + if (eventId == "slider_red") + { + mRedText->setText(toString(std::floor(mRedSlider->getValue()))); + updateColor(); + return; + } + if (eventId == "slider_green") + { + mGreenText->setText(toString(std::floor(mGreenSlider->getValue()))); + updateColor(); + return; + } + if (eventId == "slider_blue") + { + mBlueText->setText(toString(std::floor(mBlueSlider->getValue()))); + updateColor(); + return; + } +} + +void Setup_Colors::valueChanged(const gcn::SelectionEvent &event A_UNUSED) +{ + if (!userPalette) + return; + + mSelected = mColorBox->getSelected(); + const int type = userPalette->getColorTypeAt(mSelected); + const gcn::Color *col = &userPalette->getColor(type); + const Palette::GradientType grad = userPalette->getGradientType(type); + const int delay = userPalette->getGradientDelay(type); + + mPreview->clearRows(); + mPreviewBox->setContent(mTextPreview); + mTextPreview->setFont(boldFont); + mTextPreview->setTextColor(col); + mTextPreview->setTextBGColor(nullptr); + mTextPreview->setOpaque(false); + mTextPreview->setShadow(true); + mTextPreview->setOutline(true); + mTextPreview->useTextAlpha(false); + + switch (type) + { + case UserPalette::AIR_COLLISION_HIGHLIGHT: + case UserPalette::WATER_COLLISION_HIGHLIGHT: + case UserPalette::GROUNDTOP_COLLISION_HIGHLIGHT: + case UserPalette::COLLISION_HIGHLIGHT: + case UserPalette::PORTAL_HIGHLIGHT: + case UserPalette::HOME_PLACE: + case UserPalette::ROAD_POINT: + mTextPreview->setBGColor(col); + mTextPreview->setOpaque(true); + mTextPreview->setOutline(false); + mTextPreview->setShadow(false); + break; + case UserPalette::ATTACK_RANGE_BORDER: + case UserPalette::HOME_PLACE_BORDER: + mTextPreview->setFont(gui->getFont()); + mTextPreview->setTextColor(col); + mTextPreview->setOutline(false); + mTextPreview->setShadow(false); + break; + case UserPalette::PARTICLE: + case UserPalette::EXP_INFO: + case UserPalette::PICKUP_INFO: + case UserPalette::HIT_PLAYER_MONSTER: + case UserPalette::HIT_MONSTER_PLAYER: + case UserPalette::HIT_CRITICAL: + case UserPalette::MISS: + case UserPalette::HIT_LOCAL_PLAYER_MONSTER: + case UserPalette::HIT_LOCAL_PLAYER_CRITICAL: + case UserPalette::HIT_LOCAL_PLAYER_MISS: + case UserPalette::ATTACK_RANGE: + case UserPalette::MONSTER_ATTACK_RANGE: + case UserPalette::FLOOR_ITEM_TEXT: + mTextPreview->setShadow(false); + break; + default: + break; + } + + switch (type) + { + case UserPalette::PORTAL_HIGHLIGHT: + case UserPalette::ATTACK_RANGE: + case UserPalette::ATTACK_RANGE_BORDER: + case UserPalette::MONSTER_ATTACK_RANGE: + case UserPalette::HOME_PLACE: + case UserPalette::HOME_PLACE_BORDER: + case UserPalette::AIR_COLLISION_HIGHLIGHT: + case UserPalette::WATER_COLLISION_HIGHLIGHT: + case UserPalette::GROUNDTOP_COLLISION_HIGHLIGHT: + case UserPalette::COLLISION_HIGHLIGHT: + case UserPalette::WALKABLE_HIGHLIGHT: + case UserPalette::ROAD_POINT: + case UserPalette::MONSTER_HP: + case UserPalette::MONSTER_HP2: + case UserPalette::PLAYER_HP: + case UserPalette::PLAYER_HP2: + case UserPalette::FLOOR_ITEM_TEXT: + // TRANSLATORS: colors tab. label. + mGradDelayLabel->setCaption(_("Alpha:")); + mGradDelayText->setRange(0, 255); + mGradDelaySlider->setScale(0, 255); + break; + default: + // TRANSLATORS: colors tab. label. + mGradDelayLabel->setCaption(_("Delay:")); + mGradDelayText->setRange(20, 100); + mGradDelaySlider->setScale(20, 100); + break; + } + if (grad != Palette::STATIC && grad != Palette::PULSE) + { // If nonstatic color, don't display the current, but the committed + // color at the sliders + col = &userPalette->getCommittedColor(type); + } + else if (grad == Palette::PULSE) + { + col = &userPalette->getTestColor(type); + } + + setEntry(mGradDelaySlider, mGradDelayText, delay); + setEntry(mRedSlider, mRedText, col->r); + setEntry(mGreenSlider, mGreenText, col->g); + setEntry(mBlueSlider, mBlueText, col->b); + + mGradTypeSlider->setValue(grad); + updateGradType(); + mGradTypeSlider->setEnabled(true); +} + +void Setup_Colors::setEntry(Slider *const s, TextField *const t, + const int value) +{ + if (s) + s->setValue(value); + if (t) + t->setText(toString(value)); +} + +void Setup_Colors::apply() +{ + if (userPalette) + userPalette->commit(); +} + +void Setup_Colors::cancel() +{ + if (!userPalette) + return; + + userPalette->rollback(); + const int type = userPalette->getColorTypeAt(mSelected); + const gcn::Color *const col = &userPalette->getColor(type); + mGradTypeSlider->setValue(userPalette->getGradientType(type)); + const int delay = userPalette->getGradientDelay(type); + setEntry(mGradDelaySlider, mGradDelayText, delay); + setEntry(mRedSlider, mRedText, col->r); + setEntry(mGreenSlider, mGreenText, col->g); + setEntry(mBlueSlider, mBlueText, col->b); +} + +void Setup_Colors::updateGradType() +{ + if (mSelected == -1 || !userPalette) + return; + + mSelected = mColorBox->getSelected(); + const int type = userPalette->getColorTypeAt(mSelected); + const Palette::GradientType grad = userPalette->getGradientType(type); + + mGradTypeText->setCaption( + // TRANSLATORS: color type + (grad == Palette::STATIC) ? _("Static") : + // TRANSLATORS: color type + (grad == Palette::PULSE) ? _("Pulse") : + // TRANSLATORS: color type + (grad == Palette::RAINBOW) ? _("Rainbow") : _("Spectrum")); + + const bool enable = (grad == Palette::STATIC || grad == Palette::PULSE); + const bool delayEnable = true; + + mGradDelayText->setEnabled(delayEnable); + mGradDelaySlider->setEnabled(delayEnable); + + mRedText->setEnabled(enable); + mRedSlider->setEnabled(enable); + mGreenText->setEnabled(enable); + mGreenSlider->setEnabled(enable); + mBlueText->setEnabled(enable); + mBlueSlider->setEnabled(enable); +} + +void Setup_Colors::updateColor() +{ + if (mSelected == -1 || !userPalette) + return; + + const int type = userPalette->getColorTypeAt(mSelected); + const Palette::GradientType grad = static_cast<Palette::GradientType>( + static_cast<int>(mGradTypeSlider->getValue())); + const int delay = static_cast<int>(mGradDelaySlider->getValue()); + userPalette->setGradient(type, grad); + userPalette->setGradientDelay(type, delay); + + if (grad == Palette::STATIC) + { + userPalette->setColor(type, + static_cast<int>(mRedSlider->getValue()), + static_cast<int>(mGreenSlider->getValue()), + static_cast<int>(mBlueSlider->getValue())); + } + else if (grad == Palette::PULSE) + { + userPalette->setTestColor(type, gcn::Color( + static_cast<int>(mRedSlider->getValue()), + static_cast<int>(mGreenSlider->getValue()), + static_cast<int>(mBlueSlider->getValue()))); + } +} diff --git a/src/gui/widgets/tabs/setup_colors.h b/src/gui/widgets/tabs/setup_colors.h new file mode 100644 index 000000000..fcc6a378f --- /dev/null +++ b/src/gui/widgets/tabs/setup_colors.h @@ -0,0 +1,93 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_COLORS_H +#define GUI_SETUP_COLORS_H + +#include "gui/widgets/tabs/setuptab.h" + +#include <guichan/selectionlistener.hpp> + +#include <string> + +class BrowserBox; +class Label; +class ListBox; +class ScrollArea; +class Slider; +class TextField; +class TextPreview; + +class Setup_Colors final : public SetupTab, + public gcn::SelectionListener +{ + public: + explicit Setup_Colors(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Colors) + + ~Setup_Colors(); + + void apply() override; + + void cancel() override; + + void action(const gcn::ActionEvent &event) override; + + void valueChanged(const gcn::SelectionEvent &event) override; + + private: + static const char *const rawmsg; + + ListBox *mColorBox; + ScrollArea *mScroll; + BrowserBox *mPreview; + TextPreview *mTextPreview; + ScrollArea *mPreviewBox; + int mSelected; + + Label *mGradTypeLabel; + Slider *mGradTypeSlider; + Label *mGradTypeText; + + Label *mGradDelayLabel; + Slider *mGradDelaySlider; + TextField *mGradDelayText; + + Label *mRedLabel; + Slider *mRedSlider; + TextField *mRedText; + + Label *mGreenLabel; + Slider *mGreenSlider; + TextField *mGreenText; + + Label *mBlueLabel; + Slider *mBlueSlider; + TextField *mBlueText; + + static void setEntry(Slider *const s, TextField *const t, + const int value); + void updateColor(); + void updateGradType(); +}; + +#endif // GUI_SETUP_COLORS_H diff --git a/src/gui/widgets/tabs/setup_input.cpp b/src/gui/widgets/tabs/setup_input.cpp new file mode 100644 index 000000000..35fa4204a --- /dev/null +++ b/src/gui/widgets/tabs/setup_input.cpp @@ -0,0 +1,414 @@ +/* + * Custom keyboard shortcuts configuration + * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au> + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_input.h" + +#include "configuration.h" + +#include "input/inputmanager.h" +#include "input/keyboardconfig.h" + +#include "gui/setupactiondata.h" + +#include "gui/windows/okdialog.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/listbox.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/tabstrip.h" + +#include <guichan/listmodel.hpp> + +#include "debug.h" + +static int selectedData = 0; +static const int setupGroups = 9; + +/** + * The list model for key function list. + * + * \ingroup Interface + */ +class KeyListModel final : public gcn::ListModel +{ + public: + KeyListModel() : + mDataNum(0), + mSize(0) + { + } + + A_DELETE_COPY(KeyListModel) + + /** + * Returns the number of elements in container. + */ + int getNumberOfElements() override + { return mSize; } + + /** + * Returns element from container. + */ + std::string getElementAt(int i) override + { return setupActionData[selectedData][i].text; } + + /** + * Sets element from container. + */ + void setElementAt(const int i, const std::string &caption) + { setupActionData[selectedData][i].text = caption; } + + void setSize(const int size) + { mSize = size; } + + void setDataNum(const int num) + { mDataNum = num; } + + private: + int mDataNum; + int mSize; +}; + +Setup_Input::Setup_Input(const Widget2 *const widget) : + SetupTab(widget), + mKeyListModel(new KeyListModel), + mKeyList(new ListBox(this, mKeyListModel, "")), + // TRANSLATORS: button in input settings tab + mAssignKeyButton(new Button(this, _("Assign"), "assign", this)), + // TRANSLATORS: button in input settings tab + mUnassignKeyButton(new Button(this, _("Unassign"), "unassign", this)), + // TRANSLATORS: button in input settings tab + mDefaultButton(new Button(this, _("Default"), "default", this)), + // TRANSLATORS: button in input settings tab + mResetKeysButton(new Button(this, _("Reset all keys"), "resetkeys", this)), + mTabs(new TabStrip(this, config.getIntValue("fontSize") + 10)), + mScrollArea(new ScrollArea(mKeyList, true, "setup_input_background.xml")), + mKeySetting(false), + mActionDataSize(new int [9]) +{ + inputManager.setSetupInput(this); + // TRANSLATORS: setting tab name + setName(_("Input")); + + selectedData = 0; + + for (int f = 0; f < setupGroups; f ++) + { + int cnt = 0; + while (!setupActionData[f][cnt].name.empty()) + cnt ++; + mActionDataSize[f] = cnt; + } + + mKeyListModel->setSize(mActionDataSize[0]); + refreshKeys(); + if (gui) + mKeyList->setFont(reinterpret_cast<gcn::Font*>(gui->getHelpFont())); + mKeyList->addActionListener(this); + + mScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + mAssignKeyButton->addActionListener(this); + mAssignKeyButton->setEnabled(false); + mUnassignKeyButton->addActionListener(this); + mUnassignKeyButton->setEnabled(false); + mResetKeysButton->addActionListener(this); + mDefaultButton->addActionListener(this); + + mTabs->addActionListener(this); + mTabs->setActionEventId("tabs_"); + int k = 0; + while (pages[k]) + { + mTabs->addButton(gettext(pages[k]), pages[k]); + k ++; + } + + fixTranslations(); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mTabs, 5); + place(0, 1, mScrollArea, 5, 5).setPadding(2); + place(0, 6, mResetKeysButton); + place(2, 6, mAssignKeyButton); + place(3, 6, mUnassignKeyButton); + place(4, 6, mDefaultButton); + + int width = 600; + if (config.getIntValue("screenwidth") >= 730) + width += 100; + + setDimension(gcn::Rectangle(0, 0, width, 350)); +} + +Setup_Input::~Setup_Input() +{ + delete mKeyList; + mKeyList = nullptr; + delete mKeyListModel; + mKeyListModel = nullptr; + + delete mAssignKeyButton; + mAssignKeyButton = nullptr; + delete mUnassignKeyButton; + mUnassignKeyButton = nullptr; + delete mResetKeysButton; + mResetKeysButton = nullptr; + delete [] mActionDataSize; + mActionDataSize = nullptr; + delete mScrollArea; + mScrollArea = nullptr; +} + +void Setup_Input::apply() +{ + keyUnresolved(); + int key1, key2; + + if (inputManager.hasConflicts(key1, key2)) + { + const std::string str1 = keyToString(key1); + const std::string str2 = keyToString(key2); + + // TRANSLATORS: input settings error header + new OkDialog(_("Key Conflict(s) Detected."), + // TRANSLATORS: input settings error + strprintf(_("Conflict \"%s\" and \"%s\" keys. " + "Resolve them, or gameplay may result in strange behaviour."), + gettext(str1.c_str()), gettext(str2.c_str())), DIALOG_ERROR); + } + keyboard.setEnabled(true); + inputManager.store(); +} + +void Setup_Input::cancel() +{ + keyUnresolved(); + inputManager.retrieve(); + keyboard.setEnabled(true); + refreshKeys(); +} + +void Setup_Input::action(const gcn::ActionEvent &event) +{ + const std::string id = event.getId(); + + if (event.getSource() == mKeyList) + { + if (!mKeySetting) + { + const int i(mKeyList->getSelected()); + if (i >= 0 && i < mActionDataSize[selectedData]) + { + if (setupActionData[selectedData][i].actionId + == static_cast<int>(Input::KEY_NO_VALUE)) + { + mAssignKeyButton->setEnabled(false); + mUnassignKeyButton->setEnabled(false); + } + else + { + mAssignKeyButton->setEnabled(true); + mUnassignKeyButton->setEnabled(true); + } + } + } + } + else if (id == "assign") + { + mKeySetting = true; + mAssignKeyButton->setEnabled(false); + keyboard.setEnabled(false); + const int i(mKeyList->getSelected()); + if (i >= 0 && i < mActionDataSize[selectedData]) + { + const SetupActionData &key = setupActionData[selectedData][i]; + const int ik = key.actionId; + inputManager.setNewKeyIndex(ik); + mKeyListModel->setElementAt(i, std::string( + gettext(key.name.c_str())).append(": ?")); + } + } + else if (id == "unassign") + { + const int i(mKeyList->getSelected()); + if (i >= 0 && i < mActionDataSize[selectedData]) + { + const SetupActionData &key = setupActionData[selectedData][i]; + const int ik = key.actionId; + inputManager.setNewKeyIndex(ik); + refreshAssignedKey(mKeyList->getSelected()); + inputManager.unassignKey(); + inputManager.setNewKeyIndex(static_cast<int>(Input::KEY_NO_VALUE)); + } + mAssignKeyButton->setEnabled(true); + } + else if (id == "resetkeys") + { + inputManager.resetKeys(); + inputManager.update(); + refreshKeys(); + } + else if (id == "default") + { + const int i(mKeyList->getSelected()); + if (i >= 0 && i < mActionDataSize[selectedData]) + { + const SetupActionData &key = setupActionData[selectedData][i]; + const int ik = key.actionId; + inputManager.makeDefault(ik); + refreshKeys(); + } + } + else if (strStartWith(id, "tabs_")) + { + int k = 0; + std::string str("tabs_"); + while (pages[k]) + { + if (str + pages[k] == id) + break; + k ++; + } + if (pages[k] && str + pages[k] == id) + { + selectedData = k; + mKeyListModel->setSize(mActionDataSize[k]); + refreshKeys(); + mKeyList->setSelected(0); + } + } +} + +void Setup_Input::refreshAssignedKey(const int index) +{ + const SetupActionData &key = setupActionData[selectedData][index]; + if (key.actionId == static_cast<int>(Input::KEY_NO_VALUE)) + { + const std::string str(" \342\200\225\342\200\225\342\200\225" + "\342\200\225\342\200\225 "); + mKeyListModel->setElementAt(index, + str + gettext(key.name.c_str()) + str); + } + else + { + std::string str = gettext(key.name.c_str()); + unsigned int sz = 20; + if (mainGraphics->mWidth > 800) + sz = 30; + while (str.size() < sz) + str.append(" "); + mKeyListModel->setElementAt(index, strprintf("%s: %s", str.c_str(), + inputManager.getKeyStringLong(key.actionId).c_str())); + } +} + +void Setup_Input::newKeyCallback(const int index) +{ + mKeySetting = false; + const int i = keyToSetupData(index); + if (i >= 0) + refreshAssignedKey(i); + mAssignKeyButton->setEnabled(true); +} + +int Setup_Input::keyToSetupData(const int index) const +{ + for (int i = 0; i < mActionDataSize[selectedData]; i++) + { + const SetupActionData &key = setupActionData[selectedData][i]; + if (key.actionId == index) + return i; + } + return -1; +} + +std::string Setup_Input::keyToString(const int index) const +{ + for (int f = 0; f < setupGroups; f ++) + { + for (int i = 0; i < mActionDataSize[f]; i++) + { + const SetupActionData &key = setupActionData[f][i]; + if (key.actionId == index) + return key.name; + } + } + // TRANSLATORS: unknown key name + return _("unknown"); +} + +void Setup_Input::refreshKeys() +{ + for (int i = 0; i < mActionDataSize[selectedData]; i++) + refreshAssignedKey(i); +} + +void Setup_Input::keyUnresolved() +{ + if (mKeySetting) + { + newKeyCallback(inputManager.getNewKeyIndex()); + inputManager.setNewKeyIndex(static_cast<int>(Input::KEY_NO_VALUE)); + } +} + +void Setup_Input::fixTranslation(SetupActionData *const actionDatas, + const int actionStart, const int actionEnd, + const std::string &text) const +{ + int k = 0; + + while (!actionDatas[k].name.empty()) + { + SetupActionData &data = actionDatas[k]; + + const int actionId = data.actionId; + if (actionId >= actionStart && actionId <= actionEnd) + { + data.name = strprintf(gettext(text.c_str()), + actionId - actionStart + 1); + } + k ++; + } +} + +void Setup_Input::fixTranslations() const +{ + fixTranslation(setupActionData1, static_cast<int>(Input::KEY_SHORTCUT_1), + static_cast<int>(Input::KEY_SHORTCUT_20), "Item Shortcut %d"); + + fixTranslation(setupActionData3, static_cast<int>(Input::KEY_EMOTE_1), + static_cast<int>(Input::KEY_EMOTE_48), "Emote Shortcut %d"); + + fixTranslation(setupActionData4, static_cast<int>(Input::KEY_OUTFIT_1), + static_cast<int>(Input::KEY_OUTFIT_48), "Outfit Shortcut %d"); + + fixTranslation(setupActionData7, static_cast<int>( + Input::KEY_MOVE_TO_POINT_1), + static_cast<int>(Input::KEY_MOVE_TO_POINT_48), + "Move to point Shortcut %d"); +} diff --git a/src/gui/widgets/tabs/setup_input.h b/src/gui/widgets/tabs/setup_input.h new file mode 100644 index 000000000..03113913e --- /dev/null +++ b/src/gui/widgets/tabs/setup_input.h @@ -0,0 +1,104 @@ +/* + * Custom keyboard shortcuts configuration + * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au> + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_INPUT_H +#define GUI_SETUP_INPUT_H + +#include "gui/widgets/tabs/setuptab.h" + +#include <string> + +class Button; +class ListBox; +class KeyListModel; +class ScrollArea; +class TabStrip; + +struct SetupActionData; + +class Setup_Input final : public SetupTab +{ + public: + /** + * Constructor + */ + explicit Setup_Input(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Input) + + /** + * Destructor + */ + ~Setup_Input(); + + void apply() override; + + void cancel() override; + + void action(const gcn::ActionEvent &event) override; + + /** + * Get an update on the assigned key. + */ + void refreshAssignedKey(const int index); + + /** + * The callback function when a new key has been pressed. + */ + void newKeyCallback(const int index); + + /** + * Shorthand method to update all the keys. + */ + void refreshKeys(); + + /** + * If a key function is unresolved, then this reverts it. + */ + void keyUnresolved(); + + int keyToSetupData(const int index) const A_WARN_UNUSED; + + std::string keyToString(const int index) const A_WARN_UNUSED; + + private: + void fixTranslations() const; + + void fixTranslation(SetupActionData *const actionDatas, + const int actionStart, const int actionEnd, + const std::string &text) const; + + KeyListModel *mKeyListModel; + ListBox *mKeyList; + + Button *mAssignKeyButton; + Button *mUnassignKeyButton; + Button *mDefaultButton; + Button *mResetKeysButton; + TabStrip *mTabs; + ScrollArea *mScrollArea; + bool mKeySetting; /**< flag to check if key being set. */ + int *mActionDataSize; +}; + +#endif // GUI_SETUP_INPUT_H diff --git a/src/gui/widgets/tabs/setup_joystick.cpp b/src/gui/widgets/tabs/setup_joystick.cpp new file mode 100644 index 000000000..15b6959a9 --- /dev/null +++ b/src/gui/widgets/tabs/setup_joystick.cpp @@ -0,0 +1,187 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_joystick.h" + +#include "configuration.h" + +#include "input/joystick.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/checkbox.h" +#include "gui/widgets/dropdown.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/namesmodel.h" + +#include "utils/gettext.h" + +#include "debug.h" + +extern Joystick *joystick; + +Setup_Joystick::Setup_Joystick(const Widget2 *const widget) : + SetupTab(widget), + mCalibrateLabel(new Label(this, + // TRANSLATORS: joystick settings tab label + _("Press the button to start calibration"))), + // TRANSLATORS: joystick settings tab button + mCalibrateButton(new Button(this, _("Calibrate"), "calibrate", this)), + // TRANSLATORS: joystick settings tab button + mDetectButton(new Button(this, _("Detect joysticks"), "detect", this)), + mOriginalJoystickEnabled(config.getBoolValue("joystickEnabled")), + // TRANSLATORS: joystick settings tab checkbox + mJoystickEnabled(new CheckBox(this, _("Enable joystick"))), + mNamesModel(new NamesModel), + mNamesDropDown(new DropDown(this, mNamesModel)), + // TRANSLATORS: joystick settings tab checkbox + mUseInactiveCheckBox(new CheckBox(this, _("Use joystick if client " + "window inactive"), config.getBoolValue("useInactiveJoystick"))) +{ + // TRANSLATORS: joystick settings tab name + setName(_("Joystick")); + + Joystick::getNames(mNamesModel->getNames()); + + mJoystickEnabled->setSelected(mOriginalJoystickEnabled); + mJoystickEnabled->setActionEventId("joystick"); + mJoystickEnabled->addActionListener(this); + mCalibrateButton->setEnabled(mOriginalJoystickEnabled); + + mNamesDropDown->setActionEventId("name"); + mNamesDropDown->addActionListener(this); + + if (joystick) + { + mNamesDropDown->setSelected(joystick->getNumber()); + } + else + { + unsigned sel = config.getIntValue("selectedJoystick"); + if (sel >= mNamesModel->size()) + sel = 0; + mNamesDropDown->setSelected(sel); + } + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mJoystickEnabled); + place(0, 1, mNamesDropDown); + place(0, 2, mUseInactiveCheckBox); + place(0, 3, mDetectButton); + place(0, 4, mCalibrateLabel); + place(0, 5, mCalibrateButton); + + setDimension(gcn::Rectangle(0, 0, 365, 75)); +} + +Setup_Joystick::~Setup_Joystick() +{ + delete mNamesModel; + mNamesModel = nullptr; +} + +void Setup_Joystick::action(const gcn::ActionEvent &event) +{ + const gcn::Widget *const source = event.getSource(); + if (source == mJoystickEnabled) + { + setTempEnabled(mJoystickEnabled->isSelected()); + } + else if (source == mNamesDropDown) + { + if (joystick) + joystick->setNumber(mNamesDropDown->getSelected()); + } + else if (source == mDetectButton) + { + if (joystick) + { + joystick->reload(); + Joystick::getNames(mNamesModel->getNames()); + mNamesDropDown->setSelected(joystick->getNumber()); + } + } + else + { + if (!joystick) + return; + + if (joystick->isCalibrating()) + { + // TRANSLATORS: joystick settings tab button + mCalibrateButton->setCaption(_("Calibrate")); + mCalibrateLabel->setCaption + // TRANSLATORS: joystick settings tab label + (_("Press the button to start calibration")); + joystick->finishCalibration(); + } + else + { + // TRANSLATORS: joystick settings tab button + mCalibrateButton->setCaption(_("Stop")); + mCalibrateLabel->setCaption( + // TRANSLATORS: joystick settings tab label + _("Rotate the stick and don't press buttons")); + joystick->startCalibration(); + } + } +} + +void Setup_Joystick::setTempEnabled(const bool sel) +{ + Joystick::setEnabled(sel); + mCalibrateButton->setEnabled(sel); + if (joystick) + { + if (sel) + joystick->open(); + else + joystick->close(); + } +} + +void Setup_Joystick::cancel() +{ + if (joystick) + joystick->setEnabled(mOriginalJoystickEnabled); + + if (mOriginalJoystickEnabled != mJoystickEnabled->isSelected()) + setTempEnabled(mOriginalJoystickEnabled); + + mJoystickEnabled->setSelected(mOriginalJoystickEnabled); +} + +void Setup_Joystick::apply() +{ + if (!joystick) + return; + + config.setValue("joystickEnabled", + joystick ? joystick->isEnabled() : false); + + config.setValue("useInactiveJoystick", mUseInactiveCheckBox->isSelected()); + if (joystick) + joystick->setUseInactive(mUseInactiveCheckBox->isSelected()); +} diff --git a/src/gui/widgets/tabs/setup_joystick.h b/src/gui/widgets/tabs/setup_joystick.h new file mode 100644 index 000000000..3110da9b6 --- /dev/null +++ b/src/gui/widgets/tabs/setup_joystick.h @@ -0,0 +1,62 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_JOYSTICK_H +#define GUI_SETUP_JOYSTICK_H + +#include "gui/widgets/tabs/setuptab.h" + +class Button; +class CheckBox; +class DropDown; +class Label; +class NamesModel; + +class Setup_Joystick final : public SetupTab +{ + public: + explicit Setup_Joystick(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Joystick) + + ~Setup_Joystick(); + + void apply() override; + + void cancel() override; + + void action(const gcn::ActionEvent &event) override; + + void setTempEnabled(const bool sel); + + private: + Label *mCalibrateLabel; + Button *mCalibrateButton; + Button *mDetectButton; + bool mOriginalJoystickEnabled; + CheckBox *mJoystickEnabled; + NamesModel *mNamesModel; + DropDown *mNamesDropDown; + CheckBox *mUseInactiveCheckBox; +}; + +#endif // GUI_SETUP_JOYSTICK_H diff --git a/src/gui/widgets/tabs/setup_other.cpp b/src/gui/widgets/tabs/setup_other.cpp new file mode 100644 index 000000000..ec4e2fe06 --- /dev/null +++ b/src/gui/widgets/tabs/setup_other.cpp @@ -0,0 +1,404 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_other.h" + +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/namesmodel.h" +#include "gui/widgets/setupitem.h" +#include "gui/widgets/scrollarea.h" + +#include "configuration.h" + +#include "utils/gettext.h" + +#include "debug.h" + +static const int shortcutsListSize = 3; + +static const char *const shortcutsList[] = +{ + // TRANSLATORS: show buttons at top right corner type + N_("Always show"), + // TRANSLATORS: show buttons at top right corner type + N_("Auto hide in small resolution"), + // TRANSLATORS: show buttons at top right corner type + N_("Always auto hide") +}; + +static const int proxyTypeListSize = 8; + +static const char *const proxyTypeList[] = +{ + // TRANSLATORS: Proxy type selection + N_("System proxy"), + // TRANSLATORS: Proxy type selection + N_("Direct connection"), + "HTTP", + "HTTP 1.0", + "SOCKS4", + "SOCKS4A", + "SOCKS5", + // TRANSLATORS: Proxy type selection + N_("SOCKS5 hostname") +}; + +static const int densityListSize = 7; + +static const char *const densityList[] = +{ + // TRANSLATORS: screen density type + N_("default"), + // TRANSLATORS: screen density type + N_("low"), + // TRANSLATORS: screen density type + N_("medium"), + // TRANSLATORS: screen density type + N_("tv"), + // TRANSLATORS: screen density type + N_("high"), + // TRANSLATORS: screen density type + N_("xhigh"), + // TRANSLATORS: screen density type + N_("xxhigh") +}; + +Setup_Other::Setup_Other(const Widget2 *const widget) : + SetupTabScroll(widget), + mProxyTypeList(new NamesModel), + mShortcutsList(new NamesModel), + mDensityList(new NamesModel) +{ + // TRANSLATORS: misc tab in settings + setName(_("Misc")); + + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + place(0, 0, mScroll, 10, 10); + + // TRANSLATORS: settings option + new SetupItemLabel(_("Monsters"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show damage inflicted to monsters"), "", + "showMonstersTakedDamage", this, "showMonstersTakedDamageEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Auto target only reachable monsters"), "", + "targetOnlyReachable", this, "targetOnlyReachableEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Highlight monster attack range"), "", + "highlightMonsterAttackRange", this, + "highlightMonsterAttackRangeEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show monster hp bar"), "", + "showMobHP", this, "showMobHPEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Cycle monster targets"), "", + "cycleMonsters", this, "cycleMonstersEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Map"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show warps particles"), "", + "warpParticle", this, "warpParticleEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Highlight map portals"), "", + "highlightMapPortals", this, "highlightMapPortalsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Highlight floor items"), "", + "floorItemsHighlight", this, "floorItemsHighlightEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Highlight player attack range"), "", + "highlightAttackRange", this, "highlightAttackRangeEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show extended minimaps"), "", + "showExtMinimaps", this, "showExtMinimapsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Draw path"), "", "drawPath", + this, "drawPathEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Draw hotkeys on map"), "", "drawHotKeys", + this, "drawHotKeysEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable lazy scrolling"), "", + "enableLazyScrolling", this, "enableLazyScrollingEvent"); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Scroll laziness"), "", "ScrollLaziness", + this, "ScrollLazinessEvent", 1, 160); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Scroll radius"), "", "ScrollRadius", + this, "ScrollRadiusEvent", 0, 32); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Auto resize minimaps"), "", "autoresizeminimaps", + this, "autoresizeminimapsEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Moving"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Auto fix position"), "", + "autofixPos", this, "autofixPosEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Attack while moving"), "", + "attackMoving", this, "attackMovingEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Attack next target"), "", + "attackNext", this, "attackNextEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Sync player move"), "", "syncPlayerMove", + this, "syncPlayerMoveEvent"); + + // TRANSLATORS: settings option + new SetupItemTextField(_("Crazy move A program"), "", + "crazyMoveProgram", this, "crazyMoveProgramEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Mouse relative moves " + "(good for touch interfaces)"), "", "mouseDirectionMove", + this, "mouseDirectionMoveEvent"); + + // TRANSLATORS: settings group + new SetupItemLabel(_("Player"), "", this); + + new SetupItemCheckBox(_("Show own hp bar"), "", + "showOwnHP", this, "showOwnHPEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable quick stats"), "", + "quickStats", this, "quickStatsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Cycle player targets"), "", + "cyclePlayers", this, "cyclePlayersEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show job exp messages"), "", + "showJobExp", this, "showJobExpEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show players popups"), "", + "showBeingPopup", this, "showBeingPopupEvent"); + + // TRANSLATORS: settings option + new SetupItemTextField(_("Afk message"), "", + "afkMessage", this, "afkMessageEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show job"), "", "showJob", + this, "showJobEvent", false); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable attack filter"), "", + "enableAttackFilter", this, "enableAttackFilterEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable pickup filter"), "", + "enablePickupFilter", this, "enablePickupFilterEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable advert protocol"), "", + "enableAdvert", this, "enableAdvertEvent"); + + new SetupItemCheckBox(_("Enable weight notifications"), "", + "weightMsg", this, "weightMsgEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Shop"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Accept sell/buy requests"), "", + "autoShop", this, "autoShopEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable shop mode"), "", + "tradebot", this, "tradebotEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("NPC"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Cycle npc targets"), "", + "cycleNPC", this, "cycleNPCEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Log NPC dialogue"), "", "logNpcInGui", + this, "logNpcInGuiEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Bots support"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable auction bot support"), "", + "enableAuctionBot", this, "enableAuctionBotEvent", false); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable guild bot support and disable native " + "guild support"), "", "enableGuildBot", this, + "enableGuildBotEvent", false); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Keyboard"), "", this); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Repeat delay"), "", + "repeateDelay", this, "repeateDelayEvent", 0, 10000); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Repeat interval"), "", + "repeateInterval", this, "repeateIntervalEvent", 0, 10000); + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Custom repeat interval"), "", + "repeateInterval2", this, "repeateInterval2Event", 0, 10000); + + // TRANSLATORS: settings group + new SetupItemLabel(_("Windows"), "", this); + + mShortcutsList->fillFromArray(&shortcutsList[0], shortcutsListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Shortcut buttons"), "", "autohideButtons", this, + "autohideButtonsEvent", mShortcutsList, 200); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Proxy server"), "", this); + + mProxyTypeList->fillFromArray(&proxyTypeList[0], proxyTypeListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Proxy type"), "", "downloadProxyType", this, + "downloadProxyTypeEvent", mProxyTypeList, 200); + + // TRANSLATORS: settings option + new SetupItemTextField(_("Proxy address:port"), "", + "downloadProxy", this, "downloadProxyEvent"); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Other"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable server side attack"), "", + "serverAttack", this, "serverAttackEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable double clicks"), "", + "doubleClick", this, "doubleClickEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable bot checker"), "", + "enableBotCheker", this, "enableBotChekerEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable buggy servers protection " + "(do not disable)"), "", "enableBuggyServers", this, + "enableBuggyServersEvent", false); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable debug log"), "", + "debugLog", this, "debugLogEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable OpenGL log"), "", + "debugOpenGL", this, "debugOpenGLEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable input log"), "", + "logInput", this, "logInputEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Low traffic mode"), "", "lowTraffic", + this, "lowTrafficEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Hide shield sprite"), "", "hideShield", + this, "hideShieldEvent"); + +#ifndef ANDROID + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Use FBO for screenshots (only for opengl)"), + "", "usefbo", this, "usefboEvent"); +#endif + + // TRANSLATORS: settings option + new SetupItemIntTextField(_("Network delay between sub servers"), + "", "networksleep", this, "networksleepEvent", 0, 10000); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show background"), "", "showBackground", + this, "showBackgroundEvent"); + + mDensityList->fillFromArray(&densityList[0], densityListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Screen density override"), "", + "screenDensity", this, "screenDensityEvent", mDensityList, 100); + + setDimension(gcn::Rectangle(0, 0, 550, 350)); +} + +Setup_Other::~Setup_Other() +{ + delete mProxyTypeList; + mProxyTypeList = nullptr; + delete mShortcutsList; + mShortcutsList = nullptr; + delete mDensityList; + mDensityList = nullptr; +} + +void Setup_Other::apply() +{ + SetupTabScroll::apply(); + + logger->setDebugLog(config.getBoolValue("debugLog")); +} + +void Setup_Other::externalUpdated() +{ + reread("showJob"); + reread("enableGuildBot"); + reread("enableAuctionBot"); + reread("enableBuggyServers"); +} diff --git a/src/gui/widgets/tabs/setup_other.h b/src/gui/widgets/tabs/setup_other.h new file mode 100644 index 000000000..10e83517b --- /dev/null +++ b/src/gui/widgets/tabs/setup_other.h @@ -0,0 +1,49 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_OTHER_H +#define GUI_SETUP_OTHER_H + +#include "gui/widgets/tabs/setuptabscroll.h" + +class NamesModel; + +class Setup_Other final : public SetupTabScroll +{ + public: + explicit Setup_Other(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Other) + + ~Setup_Other(); + + void apply() override; + + void externalUpdated() override; + + protected: + NamesModel *mProxyTypeList; + NamesModel *mShortcutsList; + NamesModel *mDensityList; +}; + +#endif // GUI_SETUP_OTHER_H diff --git a/src/gui/widgets/tabs/setup_perfomance.cpp b/src/gui/widgets/tabs/setup_perfomance.cpp new file mode 100644 index 000000000..25d91841e --- /dev/null +++ b/src/gui/widgets/tabs/setup_perfomance.cpp @@ -0,0 +1,163 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_perfomance.h" + +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/namesmodel.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/setupitem.h" + +#include "utils/gettext.h" + +#include "debug.h" + +static const int texturesListSize = 4; + +static const char *const texturesList[] = +{ + // TRANSLATORS: texture compression type + N_("No"), + "s3tc", + "fxt1", + "ARB" +}; + +Setup_Perfomance::Setup_Perfomance(const Widget2 *const widget) : + SetupTabScroll(widget), + mTexturesList(new NamesModel) +{ + // TRANSLATORS: settings tab name + setName(_("Performance")); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + place(0, 0, mScroll, 10, 10); + + // TRANSLATORS: settings option + new SetupItemLabel(_("Better performance (enable for better performance)"), + "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Auto adjust performance"), "", + "adjustPerfomance", this, "adjustPerfomanceEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Hw acceleration"), "", + "hwaccel", this, "hwaccelEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable opacity cache (Software, can " + "use much memory)"), "", "alphaCache", this, "alphaCacheEvent"); + +#ifndef USE_SDL2 + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable map reduce (Software)"), "", + "enableMapReduce", this, "enableMapReduceEvent"); +#endif + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable compound sprite delay (Software)"), "", + "enableCompoundSpriteDelay", this, "enableCompoundSpriteDelayEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable delayed images load (OpenGL)"), "", + "enableDelayedAnimations", this, "enableDelayedAnimationsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable texture sampler (OpenGL)"), "", + "useTextureSampler", this, "useTextureSamplerEvent"); + + + // TRANSLATORS: settings option + new SetupItemLabel(_("Better quality (disable for better performance)"), + "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable alpha channel fix (Software, can " + "be very slow)"), "Can slow down drawing", "enableAlphaFix", + this, "enableAlphaFixEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show beings transparency"), "", + "beingopacity", this, "beingopacityEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable reorder sprites."), "", + "enableReorderSprites", this, "enableReorderSpritesEvent"); + + + // TRANSLATORS: settings option + new SetupItemLabel(_("Small memory (enable for lower memory usage)"), + "", this); + +#ifndef USE_SDL2 + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Disable advanced beings caching (Software)"), "", + "disableAdvBeingCaching", this, "disableAdvBeingCachingEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Disable beings caching (Software)"), "", + "disableBeingCaching", this, "disableBeingCachingEvent"); +#endif + + // TRANSLATORS: settings group + new SetupItemLabel(_("Different options (enable or disable can " + "improve performance)"), "", this); + + + mTexturesList->fillFromArray(&texturesList[0], texturesListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Enable texture compression (OpenGL)"), "", + "compresstextures", this, "compresstexturesEvent", mTexturesList, 100); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable rectangular texture extension (OpenGL)"), + "", "rectangulartextures", this, "rectangulartexturesEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Use new texture internal format (OpenGL)"), + "", "newtextures", this, "newtexturesEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable texture atlases (OpenGL)"), "", + "useAtlases", this, "useAtlasesEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Cache all sprites per map (can use " + "additinal memory)"), "", "uselonglivesprites", this, + "uselonglivespritesEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Cache all sounds (can use additinal memory)"), + "", "uselonglivesounds", this, + "uselonglivesoundsEvent"); + + setDimension(gcn::Rectangle(0, 0, 550, 350)); +} + +Setup_Perfomance::~Setup_Perfomance() +{ + delete mTexturesList; + mTexturesList = nullptr; +} diff --git a/src/gui/widgets/tabs/setup_perfomance.h b/src/gui/widgets/tabs/setup_perfomance.h new file mode 100644 index 000000000..1695dec1f --- /dev/null +++ b/src/gui/widgets/tabs/setup_perfomance.h @@ -0,0 +1,43 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_PERFOMANCE_H +#define GUI_SETUP_PERFOMANCE_H + +#include "gui/widgets/tabs/setuptabscroll.h" + +class NamesModel; + +class Setup_Perfomance final : public SetupTabScroll +{ + public: + explicit Setup_Perfomance(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Perfomance) + + ~Setup_Perfomance(); + + private: + NamesModel *mTexturesList; +}; + +#endif // GUI_SETUP_PERFOMANCE_H diff --git a/src/gui/widgets/tabs/setup_players.cpp b/src/gui/widgets/tabs/setup_players.cpp new file mode 100644 index 000000000..68d1b2eb8 --- /dev/null +++ b/src/gui/widgets/tabs/setup_players.cpp @@ -0,0 +1,104 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_players.h" + +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/setupitem.h" + +#include "utils/gettext.h" + +#include "debug.h" + +Setup_Players::Setup_Players(const Widget2 *const widget) : + SetupTabScroll(widget) +{ + // TRANSLATORS: settings tab name + setName(_("Players")); + + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + place(0, 0, mScroll, 10, 10); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show gender"), "", + "showgender", this, "showgenderEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show level"), "", + "showlevel", this, "showlevelEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show own name"), "", + "showownname", this, "showownnameEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable extended mouse targeting"), "", + "extMouseTargeting", this, "extMouseTargetingEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Target dead players"), "", + "targetDeadPlayers", this, "targetDeadPlayersEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Visible names"), "", + "visiblenames", this, "visiblenamesEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Auto move names"), "", + "moveNames", this, "moveNamesEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Secure trades"), "", + "securetrades", this, "securetradesEvent"); + + // TRANSLATORS: settings option + new SetupItemTextField(_("Unsecure chars in names"), "", + "unsecureChars", this, "unsecureCharsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show statuses"), "", + "showPlayersStatus", this, "showPlayersStatusEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show ip addresses on screenshots"), "", + "showip", this, "showipEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Allow self heal with mouse click"), "", + "selfMouseHeal", this, "selfMouseHealEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Group friends in who is online window"), "", + "groupFriends", this, "groupFriendsEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Hide erased players nicks"), "", + "hideErased", this, "hideErasedEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Use special diagonal speed in players moving"), + "", "useDiagonalSpeed", this, "useDiagonalSpeedEvent"); + + setDimension(gcn::Rectangle(0, 0, 550, 350)); +} diff --git a/src/gui/widgets/tabs/setup_players.h b/src/gui/widgets/tabs/setup_players.h new file mode 100644 index 000000000..af0709c08 --- /dev/null +++ b/src/gui/widgets/tabs/setup_players.h @@ -0,0 +1,36 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_PLAYERS_H +#define GUI_SETUP_PLAYERS_H + +#include "gui/widgets/tabs/setuptabscroll.h" + +class Setup_Players final : public SetupTabScroll +{ + public: + explicit Setup_Players(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Players) +}; + +#endif // GUI_SETUP_PLAYERS_H diff --git a/src/gui/widgets/tabs/setup_relations.cpp b/src/gui/widgets/tabs/setup_relations.cpp new file mode 100644 index 000000000..4e1bdb376 --- /dev/null +++ b/src/gui/widgets/tabs/setup_relations.cpp @@ -0,0 +1,445 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_relations.h" + +#include "actorspritemanager.h" + +#include "being/localplayer.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/checkbox.h" +#include "gui/widgets/dropdown.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/guitable.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" + +static const int COLUMNS_NR = 2; // name plus listbox +static const int NAME_COLUMN = 0; +static const unsigned int RELATION_CHOICE_COLUMN = 1; + +static const unsigned int ROW_HEIGHT = 12; +// The following column widths really shouldn't be hardcoded +// but should scale with the size of the widget... except +// that, right now, the widget doesn't exactly scale either. +static const unsigned int NAME_COLUMN_WIDTH = 230; +static const unsigned int RELATION_CHOICE_COLUMN_WIDTH = 80; + +#define WIDGET_AT(row, column) (((row) * COLUMNS_NR) + column) + +#include "debug.h" + +static const char *const table_titles[COLUMNS_NR] = +{ + // TRANSLATORS: relations table header + N_("Name"), + // TRANSLATORS: relations table header + N_("Relation") +}; + +static const char *const RELATION_NAMES[PlayerRelation::RELATIONS_NR] = +{ + // TRANSLATORS: relation type + N_("Neutral"), + // TRANSLATORS: relation type + N_("Friend"), + // TRANSLATORS: relation type + N_("Disregarded"), + // TRANSLATORS: relation type + N_("Ignored"), + // TRANSLATORS: relation type + N_("Erased"), + // TRANSLATORS: relation type + N_("Blacklisted"), + // TRANSLATORS: relation type + N_("Enemy") +}; + +class PlayerRelationListModel final : public gcn::ListModel +{ +public: + ~PlayerRelationListModel() + { } + + int getNumberOfElements() override + { + return PlayerRelation::RELATIONS_NR; + } + + std::string getElementAt(int i) override + { + if (i >= getNumberOfElements() || i < 0) + return ""; + return gettext(RELATION_NAMES[i]); + } +}; + +class PlayerTableModel final : public Widget2, public TableModel +{ +public: + explicit PlayerTableModel(const Widget2 *const widget) : + Widget2(widget), + TableModel(), + mPlayers(nullptr), + mWidgets(), + mListModel(new PlayerRelationListModel) + { + playerRelationsUpdated(); + } + + A_DELETE_COPY(PlayerTableModel) + + ~PlayerTableModel() + { + freeWidgets(); + delete mListModel; + mListModel = nullptr; + delete mPlayers; + mPlayers = nullptr; + } + + int getRows() const override + { + if (mPlayers) + return static_cast<int>(mPlayers->size()); + else + return 0; + } + + int getColumns() const override + { + return COLUMNS_NR; + } + + int getRowHeight() const override + { + return ROW_HEIGHT; + } + + int getColumnWidth(const int index) const override + { + if (index == NAME_COLUMN) + return NAME_COLUMN_WIDTH; + else + return RELATION_CHOICE_COLUMN_WIDTH; + } + + void playerRelationsUpdated() + { + signalBeforeUpdate(); + + freeWidgets(); + StringVect *const player_names = player_relations.getPlayers(); + + if (!player_names) + return; + + delete mPlayers; + mPlayers = player_names; + + // set up widgets + for (unsigned int r = 0, sz = static_cast<unsigned int>( + player_names->size()); r < sz; ++r) + { + const std::string name = (*player_names)[r]; + gcn::Widget *const widget = new Label(this, name); + mWidgets.push_back(widget); + + DropDown *const choicebox = new DropDown(this, mListModel); + choicebox->setSelected(player_relations.getRelation(name)); + mWidgets.push_back(choicebox); + } + + signalAfterUpdate(); + } + + void updateModelInRow(const int row) const + { + const DropDown *const choicebox = static_cast<DropDown *>( + getElementAt(row, RELATION_CHOICE_COLUMN)); + player_relations.setRelation(getPlayerAt(row), + static_cast<PlayerRelation::Relation>( + choicebox->getSelected())); + } + + + gcn::Widget *getElementAt(int row, int column) const override + { + return mWidgets[WIDGET_AT(row, column)]; + } + + void freeWidgets() + { + delete mPlayers; + mPlayers = nullptr; + + delete_all(mWidgets); + mWidgets.clear(); + } + + std::string getPlayerAt(const int index) const + { + if (index < 0 || index >= static_cast<signed>(mPlayers->size())) + return ""; + return (*mPlayers)[index]; + } + +protected: + StringVect *mPlayers; + std::vector<gcn::Widget *> mWidgets; + PlayerRelationListModel *mListModel; +}; + +/** + * Class for choosing one of the various `what to do when ignoring a player' options + */ +class IgnoreChoicesListModel final : public gcn::ListModel +{ +public: + ~IgnoreChoicesListModel() + { } + + int getNumberOfElements() override + { + return static_cast<int>(player_relations.getPlayerIgnoreStrategies() + ->size()); + } + + std::string getElementAt(int i) override + { + if (i >= getNumberOfElements() || i < 0) + return "???"; + + return (*player_relations.getPlayerIgnoreStrategies()) + [i]->mDescription; + } +}; + +static const std::string ACTION_DELETE("delete"); +static const std::string ACTION_TABLE("table"); +static const std::string ACTION_STRATEGY("strategy"); + +Setup_Relations::Setup_Relations(const Widget2 *const widget) : + SetupTab(widget), + PlayerRelationsListener(), + mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)), + mPlayerTableModel(new PlayerTableModel(this)), + mPlayerTable(new GuiTable(mPlayerTableModel)), + mPlayerTitleTable(new GuiTable(this, mPlayerTableTitleModel)), + mPlayerScrollArea(new ScrollArea(mPlayerTable)), + // TRANSLATORS: relation dialog button + mDefaultTrading(new CheckBox(this, _("Allow trading"), + player_relations.getDefault() & PlayerRelation::TRADE)), + // TRANSLATORS: relation dialog button + mDefaultWhisper(new CheckBox(this, _("Allow whispers"), + player_relations.getDefault() & PlayerRelation::WHISPER)), + mDeleteButton(new Button(this, _("Delete"), ACTION_DELETE, this)), + mIgnoreActionChoicesModel(new IgnoreChoicesListModel), + mIgnoreActionChoicesBox(new DropDown(widget, mIgnoreActionChoicesModel)) +{ + // TRANSLATORS: relation dialog name + setName(_("Relations")); + + mPlayerTable->setOpaque(false); + + mPlayerTableTitleModel->fixColumnWidth(NAME_COLUMN, NAME_COLUMN_WIDTH); + mPlayerTableTitleModel->fixColumnWidth(RELATION_CHOICE_COLUMN, + RELATION_CHOICE_COLUMN_WIDTH); + mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf)); + + + for (int i = 0; i < COLUMNS_NR; i++) + { + mPlayerTableTitleModel->set(0, i, new Label( + this, gettext(table_titles[i]))); + } + + mPlayerTitleTable->setLinewiseSelection(true); + + mPlayerScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mPlayerTable->setActionEventId(ACTION_TABLE); + mPlayerTable->setLinewiseSelection(true); + mPlayerTable->addActionListener(this); + + // TRANSLATORS: relation dialog label + Label *const ignore_action_label = new Label(this, _("When ignoring:")); + + mIgnoreActionChoicesBox->setActionEventId(ACTION_STRATEGY); + mIgnoreActionChoicesBox->addActionListener(this); + + int ignore_strategy_index = 0; // safe default + + if (player_relations.getPlayerIgnoreStrategy()) + { + ignore_strategy_index = player_relations.getPlayerIgnoreStrategyIndex( + player_relations.getPlayerIgnoreStrategy()->mShortName); + if (ignore_strategy_index < 0) + ignore_strategy_index = 0; + } + mIgnoreActionChoicesBox->setSelected(ignore_strategy_index); + mIgnoreActionChoicesBox->adjustHeight(); + + reset(); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mPlayerTitleTable, 6); + place(0, 1, mPlayerScrollArea, 6, 4).setPadding(2); + place(0, 5, mDeleteButton); + place(3, 5, ignore_action_label, 1); + place(4, 5, mIgnoreActionChoicesBox, 2).setPadding(2); + place(3, 6, mDefaultTrading, 3); + place(3, 7, mDefaultWhisper, 3); + + player_relations.addListener(this); + + setDimension(gcn::Rectangle(0, 0, 500, 350)); +} + +Setup_Relations::~Setup_Relations() +{ + player_relations.removeListener(this); + delete mIgnoreActionChoicesModel; + mIgnoreActionChoicesModel = nullptr; +} + + +void Setup_Relations::reset() +{ + // We now have to search through the list of ignore choices to find the + // current selection. We could use an index into the table of config + // options in player_relations instead of strategies to sidestep this. + int selection = 0; + for (size_t i = 0, sz = player_relations.getPlayerIgnoreStrategies() + ->size(); i < sz; ++ i) + { + if ((*player_relations.getPlayerIgnoreStrategies())[i] == + player_relations.getPlayerIgnoreStrategy()) + { + selection = static_cast<int>(i); + break; + } + } + mIgnoreActionChoicesBox->setSelected(selection); +} + +void Setup_Relations::apply() +{ + player_relations.store(); + + const unsigned int old_default_relations = player_relations.getDefault() & + ~(PlayerRelation::TRADE | PlayerRelation::WHISPER); + player_relations.setDefault(old_default_relations + | (mDefaultTrading->isSelected() ? PlayerRelation::TRADE : 0) + | (mDefaultWhisper->isSelected() ? PlayerRelation::WHISPER : 0)); + + if (actorSpriteManager) + actorSpriteManager->updatePlayerNames(); + + if (player_node) + player_node->setCheckNameSetting(true); +} + +void Setup_Relations::cancel() +{ +} + +void Setup_Relations::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + if (eventId == ACTION_TABLE) + { + // temporarily eliminate ourselves: we are fully aware of this change, + // so there is no need for asynchronous updates. (In fact, thouse + // might destroy the widet that triggered them, which would be rather + // embarrassing.) + player_relations.removeListener(this); + + const int row = mPlayerTable->getSelectedRow(); + if (row >= 0) + mPlayerTableModel->updateModelInRow(row); + + player_relations.addListener(this); + } + else if (eventId == ACTION_DELETE) + { + const int player_index = mPlayerTable->getSelectedRow(); + + if (player_index < 0) + return; + + player_relations.removePlayer(mPlayerTableModel->getPlayerAt( + player_index)); + } + else if (eventId == ACTION_STRATEGY) + { + PlayerIgnoreStrategy *const s = + (*player_relations.getPlayerIgnoreStrategies())[ + mIgnoreActionChoicesBox->getSelected()]; + + player_relations.setPlayerIgnoreStrategy(s); + } +} + +void Setup_Relations::updatedPlayer(const std::string &name A_UNUSED) +{ + mPlayerTableModel->playerRelationsUpdated(); + mDefaultTrading->setSelected( + player_relations.getDefault() & PlayerRelation::TRADE); + mDefaultWhisper->setSelected( + player_relations.getDefault() & PlayerRelation::WHISPER); + if (player_node) + player_node->updateName(); +} + +void Setup_Relations::updateAll() +{ + PlayerTableModel *const model = new PlayerTableModel(this); + mPlayerTable->setModel(model); + delete mPlayerTableModel; + mPlayerTableModel = model; + int ignore_strategy_index = 0; // safe default + + if (player_relations.getPlayerIgnoreStrategy()) + { + ignore_strategy_index = player_relations.getPlayerIgnoreStrategyIndex( + player_relations.getPlayerIgnoreStrategy()->mShortName); + if (ignore_strategy_index < 0) + ignore_strategy_index = 0; + } + mIgnoreActionChoicesBox->setSelected(ignore_strategy_index); + mIgnoreActionChoicesBox->adjustHeight(); + reset(); +} +void Setup_Relations::externalUpdated() +{ + mDefaultTrading->setSelected( + player_relations.getDefault() & PlayerRelation::TRADE); + mDefaultWhisper->setSelected( + player_relations.getDefault() & PlayerRelation::WHISPER); +} diff --git a/src/gui/widgets/tabs/setup_relations.h b/src/gui/widgets/tabs/setup_relations.h new file mode 100644 index 000000000..789dd5f3e --- /dev/null +++ b/src/gui/widgets/tabs/setup_relations.h @@ -0,0 +1,83 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_RELATIONS_H +#define GUI_SETUP_RELATIONS_H + +#include "being/playerrelations.h" + +#include "gui/widgets/tabs/setuptab.h" + +class Button; +class CheckBox; +class DropDown; +class GuiTable; +class PlayerTableModel; +class ScrollArea; +class StaticTableModel; + +namespace gcn +{ + class ListModel; +} + +class Setup_Relations final : public SetupTab, + public PlayerRelationsListener +{ +public: + explicit Setup_Relations(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Relations) + + ~Setup_Relations(); + + void apply() override; + + void cancel() override; + + void reset(); + + void action(const gcn::ActionEvent &event) override; + + void updatedPlayer(const std::string &name); + + void updateAll(); + + void externalUpdated() override; + +private: + StaticTableModel *mPlayerTableTitleModel; + PlayerTableModel *mPlayerTableModel; + GuiTable *mPlayerTable; + GuiTable *mPlayerTitleTable; + ScrollArea *mPlayerScrollArea; + + CheckBox *mDefaultTrading; + CheckBox *mDefaultWhisper; + + Button *mDeleteButton; + + gcn::ListModel *mIgnoreActionChoicesModel; + DropDown *mIgnoreActionChoicesBox; +}; + +#endif // GUI_SETUP_RELATIONS_H diff --git a/src/gui/widgets/tabs/setup_theme.cpp b/src/gui/widgets/tabs/setup_theme.cpp new file mode 100644 index 000000000..dde3ad04e --- /dev/null +++ b/src/gui/widgets/tabs/setup_theme.cpp @@ -0,0 +1,541 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_theme.h" + +#include "gui/gui.h" + +#include "gui/windows/okdialog.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/dropdown.h" +#include "gui/widgets/extendedlistmodel.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/namesmodel.h" + +#include "configuration.h" + +#include "utils/gettext.h" + +#include "resources/resourcemanager.h" + +#include "debug.h" + +const char* ACTION_THEME = "theme"; +const char* ACTION_FONT = "font"; +const char* ACTION_LANG = "lang"; +const char* ACTION_BOLD_FONT = "bold font"; +const char* ACTION_PARTICLE_FONT = "particle font"; +const char* ACTION_HELP_FONT = "help font"; +const char* ACTION_SECURE_FONT = "secure font"; +const char* ACTION_JAPAN_FONT = "japan font"; +const char* ACTION_INFO = "info"; + +class ThemesModel final : public NamesModel +{ +public: + ThemesModel() : + NamesModel() + { + mNames.push_back(gettext("(default)")); + Theme::fillSkinsList(mNames); + } + + ~ThemesModel() + { } +}; + +class FontsModel final : public NamesModel +{ +public: + FontsModel() : + NamesModel() + { Theme::fillFontsList(mNames); } + + ~FontsModel() + { } +}; + +const int maxFontSizes = 16; + +const char *SIZE_NAME[maxFontSizes] = +{ + // TRANSLATORS: font size + N_("Very small (8)"), + // TRANSLATORS: font size + N_("Very small (9)"), + // TRANSLATORS: font size + N_("Tiny (10)"), + // TRANSLATORS: font size + N_("Small (11)"), + // TRANSLATORS: font size + N_("Medium (12)"), + // TRANSLATORS: font size + N_("Normal (13)"), + // TRANSLATORS: font size + N_("Large (14)"), + // TRANSLATORS: font size + N_("Large (15)"), + // TRANSLATORS: font size + N_("Large (16)"), + // TRANSLATORS: font size + N_("Big (17)"), + // TRANSLATORS: font size + N_("Big (18)"), + // TRANSLATORS: font size + N_("Big (19)"), + // TRANSLATORS: font size + N_("Very big (20)"), + // TRANSLATORS: font size + N_("Very big (21)"), + // TRANSLATORS: font size + N_("Very big (22)"), + // TRANSLATORS: font size + N_("Huge (23)"), +}; + +class FontSizeChoiceListModel final : public gcn::ListModel +{ +public: + ~FontSizeChoiceListModel() + { } + + int getNumberOfElements() override A_WARN_UNUSED + { return maxFontSizes; } + + std::string getElementAt(int i) override A_WARN_UNUSED + { + if (i >= getNumberOfElements() || i < 0) + return "???"; + + return gettext(SIZE_NAME[i]); + } +}; + +struct Language final +{ + std::string name; + std::string value; + std::string icon; +}; + +const int langs_count = 17; + +const Language LANG_NAME[langs_count] = +{ + // TRANSLATORS: language + {N_("(default)"), "", ""}, + // TRANSLATORS: language + {N_("Chinese (China)"), "zh_CN", "cn.png"}, + // TRANSLATORS: language + {N_("Czech"), "cs_CZ", "cz.png"}, + // TRANSLATORS: language + {N_("English"), "C", "en.png"}, + // TRANSLATORS: language + {N_("Finnish"), "fi_FI", "fi.png"}, + // TRANSLATORS: language + {N_("French"), "fr_FR", "fr.png"}, + // TRANSLATORS: language + {N_("German"), "de_DE", "de.png"}, + // TRANSLATORS: language + {N_("Indonesian"), "id_ID", "id.png"}, + // TRANSLATORS: language + {N_("Italian"), "it_IT", "it.png"}, + // TRANSLATORS: language + {N_("Polish"), "pl_PL", "pl.png"}, + // TRANSLATORS: language + {N_("Japanese"), "ja_JP", "jp.png"}, + // TRANSLATORS: language + {N_("Dutch (Belgium/Flemish)"), "nl_BE", "nl_BE.png"}, + // TRANSLATORS: language + {N_("Portuguese"), "pt_PT", "pt.png"}, + // TRANSLATORS: language + {N_("Portuguese (Brazilian)"), "pt_BR", "pt_BR.png"}, + // TRANSLATORS: language + {N_("Russian"), "ru_RU", "ru.png"}, + // TRANSLATORS: language + {N_("Spanish (Castilian)"), "es_ES", "es.png"}, + // TRANSLATORS: language + {N_("Turkish"), "tr_TR", "tr.png"} +}; + +class LangListModel final : public ExtendedListModel +{ +public: + LangListModel() + { + ResourceManager *const resman = ResourceManager::getInstance(); + for (int f = 0; f < langs_count; f ++) + { + mIcons[f] = resman->getImage("graphics/flags/" + + LANG_NAME[f].icon); + } + } + + A_DELETE_COPY(LangListModel) + + ~LangListModel() + { + for (int f = 0; f < langs_count; f ++) + { + Image *const img = mIcons[f]; + if (img) + img->decRef(); + } + } + + int getNumberOfElements() override A_WARN_UNUSED + { return langs_count; } + + std::string getElementAt(int i) override A_WARN_UNUSED + { + if (i >= getNumberOfElements() || i < 0) + return "???"; + + return gettext(LANG_NAME[i].name.c_str()); + } + + const Image *getImageAt(int i) override A_WARN_UNUSED + { + if (i >= getNumberOfElements() || i < 0) + return nullptr; + return mIcons[i]; + } + + Image *mIcons[langs_count]; +}; + +Setup_Theme::Setup_Theme(const Widget2 *const widget) : + SetupTab(widget), + // TRANSLATORS: theme settings label + mThemeLabel(new Label(this, _("Gui theme"))), + mThemesModel(new ThemesModel), + mThemeDropDown(new DropDown(this, mThemesModel)), + mTheme(config.getStringValue("theme")), + mInfo(Theme::loadInfo(mTheme)), + mFontsModel(new FontsModel), + // TRANSLATORS: theme settings label + mFontLabel(new Label(this, _("Main Font"))), + mFontDropDown(new DropDown(this, mFontsModel)), + mFont(config.getStringValue("font")), + mLangListModel(new LangListModel), + // TRANSLATORS: theme settings label + mLangLabel(new Label(this, _("Language"))), + mLangDropDown(new DropDown(this, mLangListModel, true)), + mLang(config.getStringValue("lang")), + // TRANSLATORS: theme settings label + mBoldFontLabel(new Label(this, _("Bold font"))), + mBoldFontDropDown(new DropDown(this, mFontsModel)), + mBoldFont(config.getStringValue("boldFont")), + // TRANSLATORS: theme settings label + mParticleFontLabel(new Label(this, _("Particle font"))), + mParticleFontDropDown(new DropDown(this, mFontsModel)), + mParticleFont(config.getStringValue("particleFont")), + // TRANSLATORS: theme settings label + mHelpFontLabel(new Label(this, _("Help font"))), + mHelpFontDropDown(new DropDown(this, mFontsModel)), + mHelpFont(config.getStringValue("helpFont")), + // TRANSLATORS: theme settings label + mSecureFontLabel(new Label(this, _("Secure font"))), + mSecureFontDropDown(new DropDown(this, mFontsModel)), + mSecureFont(config.getStringValue("secureFont")), + // TRANSLATORS: theme settings label + mJapanFontLabel(new Label(this, _("Japanese font"))), + mJapanFontDropDown(new DropDown(this, mFontsModel)), + mJapanFont(config.getStringValue("japanFont")), + mFontSizeListModel(new FontSizeChoiceListModel), + // TRANSLATORS: theme settings label + mFontSizeLabel(new Label(this, _("Font size"))), + mFontSize(config.getIntValue("fontSize")), + mFontSizeDropDown(new DropDown(this, mFontSizeListModel)), + mNpcFontSizeListModel(new FontSizeChoiceListModel), + // TRANSLATORS: theme settings label + mNpcFontSizeLabel(new Label(this, _("Npc font size"))), + mNpcFontSize(config.getIntValue("npcfontSize")), + mNpcFontSizeDropDown(new DropDown(this, mNpcFontSizeListModel)), + // TRANSLATORS: button name with information about selected theme + mInfoButton(new Button(this, _("i"), ACTION_INFO, this)), + mThemeInfo() +{ + // TRANSLATORS: theme settings tab name + setName(_("Theme")); + + mThemeDropDown->setActionEventId(ACTION_THEME); + mThemeDropDown->addActionListener(this); + mFontDropDown->setActionEventId(ACTION_FONT); + mFontDropDown->addActionListener(this); + mLangDropDown->setActionEventId(ACTION_LANG); + mLangDropDown->addActionListener(this); + mBoldFontDropDown->setActionEventId(ACTION_BOLD_FONT); + mBoldFontDropDown->addActionListener(this); + mParticleFontDropDown->setActionEventId(ACTION_PARTICLE_FONT); + mParticleFontDropDown->addActionListener(this); + mHelpFontDropDown->setActionEventId(ACTION_HELP_FONT); + mHelpFontDropDown->addActionListener(this); + mSecureFontDropDown->setActionEventId(ACTION_SECURE_FONT); + mSecureFontDropDown->addActionListener(this); + mJapanFontDropDown->setActionEventId(ACTION_JAPAN_FONT); + mJapanFontDropDown->addActionListener(this); + mFontSizeDropDown->setSelected(mFontSize - 9); + mFontSizeDropDown->adjustHeight(); + mNpcFontSizeDropDown->setSelected(mNpcFontSize - 9); + mNpcFontSizeDropDown->adjustHeight(); + + const std::string skin = Theme::getThemeName(); + if (!skin.empty()) + mThemeDropDown->setSelectedString(skin); + else + mThemeDropDown->setSelected(0); + + const std::string str = config.getStringValue("lang"); + for (int f = 0; f < langs_count; f ++) + { + if (LANG_NAME[f].value == str) + { + mLangDropDown->setSelected(f); + break; + } + } + + mFontDropDown->setSelectedString(getFileName( + config.getStringValue("font"))); + mBoldFontDropDown->setSelectedString(getFileName( + config.getStringValue("boldFont"))); + mParticleFontDropDown->setSelectedString(getFileName( + config.getStringValue("particleFont"))); + mHelpFontDropDown->setSelectedString(getFileName( + config.getStringValue("helpFont"))); + mSecureFontDropDown->setSelectedString(getFileName( + config.getStringValue("secureFont"))); + mJapanFontDropDown->setSelectedString(getFileName( + config.getStringValue("japanFont"))); + + updateInfo(); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, mThemeLabel, 5); + place(0, 1, mLangLabel, 5); + place(0, 2, mFontSizeLabel, 5); + place(0, 3, mNpcFontSizeLabel, 5); + place(0, 4, mFontLabel, 5); + place(0, 5, mBoldFontLabel, 5); + place(0, 6, mParticleFontLabel, 5); + place(0, 7, mHelpFontLabel, 5); + place(0, 8, mSecureFontLabel, 5); + place(0, 9, mJapanFontLabel, 5); + + place(6, 0, mThemeDropDown, 10); + place(6, 1, mLangDropDown, 10); + place(6, 2, mFontSizeDropDown, 10); + place(6, 3, mNpcFontSizeDropDown, 10); + place(6, 4, mFontDropDown, 10); + place(6, 5, mBoldFontDropDown, 10); + place(6, 6, mParticleFontDropDown, 10); + place(6, 7, mHelpFontDropDown, 10); + place(6, 8, mSecureFontDropDown, 10); + place(6, 9, mJapanFontDropDown, 10); + + place(17, 0, mInfoButton, 1); + + int size = mainGraphics->mWidth - 10; + const int maxWidth = mFontSize * 30 + 290; + if (size < 465) + size = 465; + else if (size > maxWidth) + size = maxWidth; + + setDimension(gcn::Rectangle(0, 0, size, 500)); +} + +Setup_Theme::~Setup_Theme() +{ + delete mInfo; + mInfo = nullptr; + + delete mThemesModel; + mThemesModel = nullptr; + + delete mFontsModel; + mFontsModel = nullptr; + + delete mFontSizeListModel; + mFontSizeListModel = nullptr; + + delete mNpcFontSizeListModel; + mNpcFontSizeListModel = nullptr; + + delete mLangListModel; + mLangListModel = nullptr; + + delete mInfo; + mInfo = nullptr; +} + +void Setup_Theme::updateInfo() +{ + delete mInfo; + mInfo = Theme::loadInfo(mTheme); + if (mInfo) + { + // TRANSLATORS: theme info dialog + mThemeInfo = std::string(_("Name: ")).append(mInfo->name) + .append("\n").append(_("Copyright:")).append("\n") + .append(mInfo->copyright); + } + else + { + mThemeInfo.clear(); + } + replaceAll(mThemeInfo, "\\n", "\n"); + mInfoButton->setEnabled(!mThemeInfo.empty()); +} + +void Setup_Theme::action(const gcn::ActionEvent &event) +{ + const std::string &eventId = event.getId(); + if (eventId == ACTION_THEME) + { + if (mThemeDropDown->getSelected() == 0) + mTheme.clear(); + else + mTheme = mThemeDropDown->getSelectedString(); + updateInfo(); + } + else if (eventId == ACTION_FONT) + { + mFont = mFontDropDown->getSelectedString(); + } + else if (eventId == ACTION_LANG) + { + const int id = mLangDropDown->getSelected(); + if (id < 0 || id >= langs_count) + mLang.clear(); + else + mLang = LANG_NAME[id].value; + } + else if (eventId == ACTION_BOLD_FONT) + { + mBoldFont = mBoldFontDropDown->getSelectedString(); + } + else if (eventId == ACTION_PARTICLE_FONT) + { + mParticleFont = mParticleFontDropDown->getSelectedString(); + } + else if (eventId == ACTION_HELP_FONT) + { + mHelpFont = mHelpFontDropDown->getSelectedString(); + } + else if (eventId == ACTION_SECURE_FONT) + { + mSecureFont = mSecureFontDropDown->getSelectedString(); + } + else if (eventId == ACTION_JAPAN_FONT) + { + mJapanFont = mJapanFontDropDown->getSelectedString(); + } + else if (eventId == ACTION_INFO) + { + // TRANSLATORS: theme info dialog header + new OkDialog(_("Theme info"), mThemeInfo, DIALOG_OK, + false, true, nullptr, 600); + } +} + +void Setup_Theme::cancel() +{ + mTheme = config.getStringValue("theme"); + mLang = config.getStringValue("lang"); + mFont = getFileName(config.getStringValue("font")); + mBoldFont = getFileName(config.getStringValue("boldFont")); + mParticleFont = getFileName(config.getStringValue("particleFont")); + mHelpFont = getFileName(config.getStringValue("helpFont")); + mSecureFont = getFileName(config.getStringValue("secureFont")); + mJapanFont = getFileName(config.getStringValue("japanFont")); +} + +#define updateField(name1, name2) if (!mInfo->name1.empty()) \ + name2 = mInfo->name1; + +void Setup_Theme::apply() +{ + if (config.getStringValue("theme") != mTheme) + { + // TRANSLATORS: theme message dialog + new OkDialog(_("Theme Changed"), _("Restart your client for " + "the change to take effect.")); + } + + config.setValue("selectedSkin", ""); + if (config.getStringValue("theme") != mTheme && mInfo) + { + updateField(font, mFont); + updateField(boldFont, mBoldFont); + updateField(particleFont, mParticleFont); + updateField(helpFont, mHelpFont); + updateField(secureFont, mSecureFont); + updateField(japanFont, mJapanFont); + if (mInfo->fontSize) + { + const int size = mInfo->fontSize - 9; + if (size >= 0) + mFontSizeDropDown->setSelected(size); + } + if (mInfo->npcfontSize) + { + const int size = mInfo->npcfontSize - 9; + if (size >= 0) + mNpcFontSizeDropDown->setSelected(size); + } + if (mInfo->guiAlpha > 0.01F) + config.setValue("guialpha", mInfo->guiAlpha); + } + config.setValue("theme", mTheme); + config.setValue("lang", mLang); + if (config.getValue("font", "dejavusans.ttf") != mFont + || config.getValue("boldFont", "dejavusans-bold.ttf") != mBoldFont + || config.getValue("particleFont", "dejavusans.ttf") != mParticleFont + || config.getValue("helpFont", "dejavusansmono.ttf") != mHelpFont + || config.getValue("secureFont", "dejavusansmono.ttf") != mSecureFont + || config.getValue("japanFont", "mplus-1p-regular.ttf") != mJapanFont + || config.getIntValue("fontSize") + != static_cast<int>(mFontSizeDropDown->getSelected()) + 9 + || config.getIntValue("npcfontSize") + != static_cast<int>(mNpcFontSizeDropDown->getSelected()) + 9) + { + config.setValue("font", "fonts/" + getFileName(mFont)); + config.setValue("boldFont", "fonts/" + getFileName(mBoldFont)); + config.setValue("particleFont", "fonts/" + getFileName(mParticleFont)); + config.setValue("helpFont", "fonts/" + getFileName(mHelpFont)); + config.setValue("secureFont", "fonts/" + getFileName(mSecureFont)); + config.setValue("japanFont", "fonts/" + getFileName(mJapanFont)); + config.setValue("fontSize", mFontSizeDropDown->getSelected() + 9); + config.setValue("npcfontSize", + mNpcFontSizeDropDown->getSelected() + 9); + gui->updateFonts(); + } +} + +#undef updateField diff --git a/src/gui/widgets/tabs/setup_theme.h b/src/gui/widgets/tabs/setup_theme.h new file mode 100644 index 000000000..96d07aa15 --- /dev/null +++ b/src/gui/widgets/tabs/setup_theme.h @@ -0,0 +1,105 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_THEME_H +#define GUI_SETUP_THEME_H + +#include "gui/widgets/tabs/setuptab.h" + +class Button; +class DropDown; +class FontsModel; +class FontSizeChoiceListModel; +class Label; +class LangListModel; +class ThemesModel; + +class Setup_Theme final : public SetupTab +{ + public: + explicit Setup_Theme(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Theme) + + ~Setup_Theme(); + + void apply() override; + + void cancel() override; + + void action(const gcn::ActionEvent &event) override; + + void updateInfo(); + + private: + Label *mThemeLabel; + ThemesModel *mThemesModel; + DropDown *mThemeDropDown; + std::string mTheme; + ThemeInfo *mInfo; + + FontsModel *mFontsModel; + Label *mFontLabel; + DropDown *mFontDropDown; + std::string mFont; + + LangListModel *mLangListModel; + + Label *mLangLabel; + DropDown *mLangDropDown; + std::string mLang; + + Label *mBoldFontLabel; + DropDown *mBoldFontDropDown; + std::string mBoldFont; + + Label *mParticleFontLabel; + DropDown *mParticleFontDropDown; + std::string mParticleFont; + + Label *mHelpFontLabel; + DropDown *mHelpFontDropDown; + std::string mHelpFont; + + Label *mSecureFontLabel; + DropDown *mSecureFontDropDown; + std::string mSecureFont; + + Label *mJapanFontLabel; + DropDown *mJapanFontDropDown; + std::string mJapanFont; + + FontSizeChoiceListModel *mFontSizeListModel; + Label *mFontSizeLabel; + int mFontSize; + DropDown *mFontSizeDropDown; + + FontSizeChoiceListModel *mNpcFontSizeListModel; + Label *mNpcFontSizeLabel; + int mNpcFontSize; + DropDown *mNpcFontSizeDropDown; + + Button *mInfoButton; + std::string mThemeInfo; +}; + +#endif // GUI_SETUP_THEME_H diff --git a/src/gui/widgets/tabs/setup_touch.cpp b/src/gui/widgets/tabs/setup_touch.cpp new file mode 100644 index 000000000..e3081427d --- /dev/null +++ b/src/gui/widgets/tabs/setup_touch.cpp @@ -0,0 +1,139 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_touch.h" + +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/scrollarea.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include "debug.h" + +static const int sizeListSize = 4; + +static const char *const sizeList[] = +{ + // TRANSLATORS: onscreen button size + N_("Small"), + // TRANSLATORS: onscreen button size + N_("Normal"), + // TRANSLATORS: onscreen button size + N_("Medium"), + // TRANSLATORS: onscreen button size + N_("Large") +}; + +static const int formatListSize = 2; + +static const char *const formatList[] = +{ + "2x1", + "2x2", +}; + +Setup_Touch::Setup_Touch(const Widget2 *const widget) : + SetupTabScroll(widget), + mSizeList(new NamesModel), + mFormatList(new NamesModel), + mActionsList(new TouchActionsModel) +{ + // TRANSLATORS: touch settings tab + setName(_("Touch")); + + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + place(0, 0, mScroll, 10, 10); + mSizeList->fillFromArray(&sizeList[0], sizeListSize); + mFormatList->fillFromArray(&formatList[0], formatListSize); + + // TRANSLATORS: settings option + new SetupItemLabel(_("Onscreen keyboard"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show onscreen keyboard icon"), "", + "showScreenKeyboard", this, "showScreenKeyboardEvent"); + + // TRANSLATORS: settings option + new SetupActionDropDown(_("Keyboard icon action"), "", + "screenActionKeyboard", this, "screenActionKeyboardEvent", + mActionsList, 250); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Onscreen joystick"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show onscreen joystick"), "", + "showScreenJoystick", this, "showScreenJoystickEvent"); + + // TRANSLATORS: settings option + new SetupItemDropDown(_("Joystick size"), "", "screenJoystickSize", this, + "screenJoystickEvent", mSizeList, 100); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Onscreen buttons"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show onscreen buttons"), "", + "showScreenButtons", this, "showScreenButtonsEvent"); + + // TRANSLATORS: settings option + new SetupItemDropDown(_("Buttons format"), "", "screenButtonsFormat", this, + "screenButtonsFormatEvent", mFormatList, 100); + + // TRANSLATORS: settings option + new SetupItemDropDown(_("Buttons size"), "", "screenButtonsSize", this, + "screenButtonsSizeEvent", mSizeList, 100); + + // TRANSLATORS: settings option + new SetupActionDropDown(strprintf(_("Button %u action"), 1U), "", + "screenActionButton0", this, "screenActionButton0Event", + mActionsList, 250); + + // TRANSLATORS: settings option + new SetupActionDropDown(strprintf(_("Button %u action"), 2U), "", + "screenActionButton1", this, "screenActionButton1Event", + mActionsList, 250); + + // TRANSLATORS: settings option + new SetupActionDropDown(strprintf(_("Button %u action"), 3U), "", + "screenActionButton2", this, "screenActionButton2Event", + mActionsList, 250); + + // TRANSLATORS: settings option + new SetupActionDropDown(strprintf(_("Button %u action"), 4U), "", + "screenActionButton3", this, "screenActionButton3Event", + mActionsList, 250); + + setDimension(gcn::Rectangle(0, 0, 550, 350)); +} + +Setup_Touch::~Setup_Touch() +{ + delete mSizeList; + mSizeList = nullptr; + delete mFormatList; + mFormatList = nullptr; + delete mActionsList; + mActionsList = nullptr; +} diff --git a/src/gui/widgets/tabs/setup_touch.h b/src/gui/widgets/tabs/setup_touch.h new file mode 100644 index 000000000..b908ce19d --- /dev/null +++ b/src/gui/widgets/tabs/setup_touch.h @@ -0,0 +1,41 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_TOUCH_H +#define GUI_SETUP_TOUCH_H + +#include "gui/widgets/setuptouchitem.h" + +class Setup_Touch final : public SetupTabScroll +{ + public: + explicit Setup_Touch(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Touch) + + ~Setup_Touch(); + + protected: + NamesModel *mSizeList; + NamesModel *mFormatList; + TouchActionsModel *mActionsList; +}; + +#endif // GUI_SETUP_TOUCH_H diff --git a/src/gui/widgets/tabs/setup_video.cpp b/src/gui/widgets/tabs/setup_video.cpp new file mode 100644 index 000000000..bd53763cc --- /dev/null +++ b/src/gui/widgets/tabs/setup_video.cpp @@ -0,0 +1,576 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_video.h" + +#include "client.h" +#include "configuration.h" + +#include "graphicsmanager.h" + +#include "gui/windows/okdialog.h" +#include "gui/windows/textdialog.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/checkbox.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/listbox.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/slider.h" +#include "gui/widgets/dropdown.h" + +#include "render/rendererslistsdl.h" + +#include "utils/gettext.h" +#include "utils/sdlhelper.h" + +#include "test/testmain.h" + +#include <guichan/listmodel.hpp> + +#include <algorithm> + +#include "debug.h" + +extern Graphics *mainGraphics; + +class ModeListModel final : public gcn::ListModel +{ + public: + ModeListModel(); + + A_DELETE_COPY(ModeListModel) + + ~ModeListModel() + { } + + /** + * Returns the number of elements in container. + */ + int getNumberOfElements() override + { return static_cast<int>(mVideoModes.size()); } + + /** + * Returns element from container. + */ + std::string getElementAt(int i) + { return mVideoModes[i]; } + + /** + * Returns the index corresponding to the given video mode. + * E.g.: "800x600". + * or -1 if not found. + */ + int getIndexOf(const std::string &widthXHeightMode); + + private: + void addCustomMode(const std::string &mode); + + StringVect mVideoModes; +}; + +#ifndef ANDROID +static bool modeSorter(const std::string &mode1, const std::string &mode2) +{ + const int width1 = atoi(mode1.substr(0, mode1.find("x")).c_str()); + const int height1 = atoi(mode1.substr(mode1.find("x") + 1).c_str()); + if (!width1 || !height1) + return false; + + const int width2 = atoi(mode2.substr(0, mode2.find("x")).c_str()); + const int height2 = atoi(mode2.substr(mode2.find("x") + 1).c_str()); + if (!width2 || !height2) + return false; + if (width1 != width2) + return width1 < width2; + + if (height1 != height2) + return height1 < height2; + + return false; +} +#endif + +ModeListModel::ModeListModel() : + mVideoModes() +{ + SDL::getAllVideoModes(mVideoModes); +#ifndef ANDROID + addCustomMode("640x480"); + addCustomMode("800x600"); + addCustomMode("1024x768"); + addCustomMode("1280x1024"); + addCustomMode("1400x900"); + addCustomMode("1500x990"); + addCustomMode(toString(mainGraphics->mWidth).append("x") + .append(toString(mainGraphics->mHeight))); + + std::sort(mVideoModes.begin(), mVideoModes.end(), modeSorter); + mVideoModes.push_back("custom"); +#endif +} + +void ModeListModel::addCustomMode(const std::string &mode) +{ + StringVectCIter it = mVideoModes.begin(); + const StringVectCIter it_end = mVideoModes.end(); + while (it != it_end) + { + if (*it == mode) + return; + ++ it; + } + mVideoModes.push_back(mode); +} + +int ModeListModel::getIndexOf(const std::string &widthXHeightMode) +{ + std::string currentMode(""); + for (int i = 0; i < getNumberOfElements(); i++) + { + currentMode = getElementAt(i); + if (currentMode == widthXHeightMode) + return i; + } + return -1; +} + +class OpenGLListModel final : public gcn::ListModel +{ +public: + ~OpenGLListModel() + { } + + int getNumberOfElements() override + { return renderModesListSize; } + + std::string getElementAt(int i) override + { + if (i >= getNumberOfElements() || i < 0) + return "???"; + return gettext(OPENGL_NAME[i]); + } +}; + +Setup_Video::Setup_Video(const Widget2 *const widget) : + SetupTab(widget), + gcn::KeyListener(), + mFullScreenEnabled(config.getBoolValue("screen")), + mOpenGLEnabled(intToRenderType(config.getIntValue("opengl"))), + mFps(config.getIntValue("fpslimit")), + mAltFps(config.getIntValue("altfpslimit")), + mModeListModel(new ModeListModel), + mOpenGLListModel(new OpenGLListModel), + mModeList(new ListBox(widget, mModeListModel, "")), + // TRANSLATORS: video settings checkbox + mFsCheckBox(new CheckBox(this, _("Full screen"), mFullScreenEnabled)), + mOpenGLDropDown(new DropDown(widget, mOpenGLListModel)), + // TRANSLATORS: video settings checkbox + mFpsCheckBox(new CheckBox(this, _("FPS limit:"))), + mFpsSlider(new Slider(2, 160)), + mFpsLabel(new Label(this)), + mAltFpsSlider(new Slider(2, 160)), + // TRANSLATORS: video settings label + mAltFpsLabel(new Label(this, _("Alt FPS limit: "))), +#if !defined(ANDROID) && !defined(__APPLE__) + // TRANSLATORS: video settings button + mDetectButton(new Button(this, _("Detect best mode"), "detect", this)), +#endif + mDialog(nullptr), + mCustomCursorEnabled(config.getBoolValue("customcursor")), + mEnableResize(config.getBoolValue("enableresize")), + mNoFrame(config.getBoolValue("noframe")), + mCustomCursorCheckBox(new CheckBox(this, +#ifdef ANDROID + // TRANSLATORS: video settings checkbox + _("Show cursor"), +#else + // TRANSLATORS: video settings checkbox + _("Custom cursor"), +#endif + mCustomCursorEnabled)), + // TRANSLATORS: video settings checkbox + mEnableResizeCheckBox(new CheckBox(this, _("Enable resize"), + mEnableResize)), + // TRANSLATORS: video settings checkbox + mNoFrameCheckBox(new CheckBox(this, _("No frame"), mNoFrame)) +{ + // TRANSLATORS: video settings tab name + setName(_("Video")); + + ScrollArea *const scrollArea = new ScrollArea(mModeList, + true, "setup_video_background.xml"); + scrollArea->setWidth(150); + scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + + mOpenGLDropDown->setSelected(renderToIndex[mOpenGLEnabled]); + + mModeList->setEnabled(true); + + // TRANSLATORS: video settings label + mFpsLabel->setCaption(mFps > 0 ? toString(mFps) : _("None")); + mFpsLabel->setWidth(60); + // TRANSLATORS: video settings label + mAltFpsLabel->setCaption(_("Alt FPS limit: ") + (mAltFps > 0 + ? toString(mAltFps) : _("None"))); + mAltFpsLabel->setWidth(150); + mFpsSlider->setValue(mFps); + mFpsSlider->setEnabled(mFps > 0); + mAltFpsSlider->setValue(mAltFps); + mAltFpsSlider->setEnabled(mAltFps > 0); + mFpsCheckBox->setSelected(mFps > 0); + + // Pre-select the current video mode. + const std::string videoMode = toString(mainGraphics->mWidth).append("x") + .append(toString(mainGraphics->mHeight)); + mModeList->setSelected(mModeListModel->getIndexOf(videoMode)); + + mModeList->setActionEventId("videomode"); + mCustomCursorCheckBox->setActionEventId("customcursor"); + mFpsCheckBox->setActionEventId("fpslimitcheckbox"); + mFpsSlider->setActionEventId("fpslimitslider"); + mAltFpsSlider->setActionEventId("altfpslimitslider"); + mOpenGLDropDown->setActionEventId("opengl"); + mEnableResizeCheckBox->setActionEventId("enableresize"); + mNoFrameCheckBox->setActionEventId("noframe"); + + mModeList->addActionListener(this); + mCustomCursorCheckBox->addActionListener(this); + mFpsCheckBox->addActionListener(this); + mFpsSlider->addActionListener(this); + mAltFpsSlider->addActionListener(this); + mOpenGLDropDown->addActionListener(this); + mEnableResizeCheckBox->addActionListener(this); + mNoFrameCheckBox->addActionListener(this); + + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + + place(0, 0, scrollArea, 1, 5).setPadding(2); + place(0, 5, mOpenGLDropDown, 1); + + place(1, 0, mFsCheckBox, 2); + + place(1, 1, mCustomCursorCheckBox, 3); + + place(1, 2, mEnableResizeCheckBox, 2); + place(1, 3, mNoFrameCheckBox, 2); + + place(0, 6, mFpsSlider); + place(1, 6, mFpsCheckBox).setPadding(3); + place(2, 6, mFpsLabel).setPadding(1); + + place(0, 7, mAltFpsSlider); + place(1, 7, mAltFpsLabel).setPadding(3); + +#if !defined(ANDROID) && !defined(__APPLE__) + place(0, 8, mDetectButton); +#else + mNoFrameCheckBox->setEnabled(false); + mEnableResizeCheckBox->setEnabled(false); + mFsCheckBox->setEnabled(false); +#endif + + int width = 600; + + if (config.getIntValue("screenwidth") >= 730) + width += 100; + + setDimension(gcn::Rectangle(0, 0, width, 300)); +} + +Setup_Video::~Setup_Video() +{ + delete mModeListModel; + mModeListModel = nullptr; + delete mModeList; + mModeList = nullptr; + delete mOpenGLListModel; + mOpenGLListModel = nullptr; + delete mDialog; + mDialog = nullptr; +} + +void Setup_Video::apply() +{ + // Full screen changes + bool fullscreen = mFsCheckBox->isSelected(); + if (fullscreen != config.getBoolValue("screen")) + { + /* The OpenGL test is only necessary on Windows, since switching + * to/from full screen works fine on Linux. On Windows we'd have to + * reinitialize the OpenGL state and reload all textures. + * + * See http://libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode + */ + +#if defined(WIN32) || defined(__APPLE__) || defined(ANDROID) + // checks for opengl usage + if (intToRenderType(config.getIntValue("opengl")) == RENDER_SOFTWARE) + { +#endif + if (!mainGraphics->setFullscreen(fullscreen)) + { + fullscreen = !fullscreen; + if (!mainGraphics->setFullscreen(fullscreen)) + { + std::stringstream errorMsg; + if (fullscreen) + { + // TRANSLATORS: video error message + errorMsg << _("Failed to switch to windowed mode " + "and restoration of old mode also " + "failed!") << std::endl; + } + else + { + // TRANSLATORS: video error message + errorMsg << _("Failed to switch to fullscreen mode" + " and restoration of old mode also " + "failed!") << std::endl; + } + logger->safeError(errorMsg.str()); + } + } +#if defined(WIN32) || defined(__APPLE__) || defined(ANDROID) + } + else + { + // TRANSLATORS: video settings warning + new OkDialog(_("Switching to Full Screen"), + // TRANSLATORS: video settings warning + _("Restart needed for changes to take effect.")); + } +#endif + config.setValue("screen", fullscreen); + } + + const int sel = mOpenGLDropDown->getSelected(); + RenderType mode = RENDER_SOFTWARE; + if (sel >= 0 && static_cast<unsigned int>(sel) < sizeof(indexToRender)) + mode = indexToRender[mOpenGLDropDown->getSelected()]; + + // OpenGL change + if (mode != mOpenGLEnabled) + { + config.setValue("opengl", static_cast<int>(mode)); + + // OpenGL can currently only be changed by restarting, notify user. + // TRANSLATORS: video settings warning + new OkDialog(_("Changing to OpenGL"), + // TRANSLATORS: video settings warning + _("Applying change to OpenGL requires restart.")); + } + + mFps = mFpsCheckBox->isSelected() ? + static_cast<int>(mFpsSlider->getValue()) : 0; + + mAltFps = static_cast<int>(mAltFpsSlider->getValue()); + + mFpsSlider->setEnabled(mFps > 0); + + mAltFpsSlider->setEnabled(mAltFps > 0); + + // FPS change + config.setValue("fpslimit", mFps); + config.setValue("altfpslimit", mAltFps); + + // We sync old and new values at apply time + mFullScreenEnabled = config.getBoolValue("screen"); + mCustomCursorEnabled = config.getBoolValue("customcursor"); + + mOpenGLEnabled = intToRenderType(config.getIntValue("opengl")); + mEnableResize = config.getBoolValue("enableresize"); + mNoFrame = config.getBoolValue("noframe"); +} + +void Setup_Video::cancel() +{ + mFpsCheckBox->setSelected(mFps > 0); + mFsCheckBox->setSelected(mFullScreenEnabled); + mOpenGLDropDown->setSelected(renderToIndex[mOpenGLEnabled]); + mCustomCursorCheckBox->setSelected(mCustomCursorEnabled); + mFpsSlider->setValue(mFps); + mFpsSlider->setEnabled(mFps > 0); + mAltFpsSlider->setValue(mAltFps); + mAltFpsSlider->setEnabled(mAltFps > 0); + mFpsLabel->setCaption(mFpsCheckBox->isSelected() + // TRANSLATORS: video settings label + ? toString(mFps) : _("None")); + // TRANSLATORS: video settings label + mAltFpsLabel->setCaption(_("Alt FPS limit: ") + toString(mAltFps)); + mEnableResizeCheckBox->setSelected(mEnableResize); + mNoFrameCheckBox->setSelected(mNoFrame); + + config.setValue("screen", mFullScreenEnabled); + + // Set back to the current video mode. + std::string videoMode = toString(mainGraphics->mWidth).append("x") + .append(toString(mainGraphics->mHeight)); + mModeList->setSelected(mModeListModel->getIndexOf(videoMode)); + config.setValue("screenwidth", mainGraphics->mWidth); + config.setValue("screenheight", mainGraphics->mHeight); + + config.setValue("customcursor", mCustomCursorEnabled); + config.setValue("opengl", static_cast<int>(mOpenGLEnabled)); + config.setValue("enableresize", mEnableResize); + config.setValue("noframe", mNoFrame); +} + +void Setup_Video::action(const gcn::ActionEvent &event) +{ + const std::string &id = event.getId(); + + if (id == "videomode") + { + std::string mode = mModeListModel->getElementAt( + mModeList->getSelected()); + + if (mode == "custom") + { + if (mDialog) + { + mode = mDialog->getText(); + mDialog = nullptr; + } + else + { + mDialog = new TextDialog( + // TRANSLATORS: resolution question dialog + _("Custom resolution (example: 1024x768)"), + // TRANSLATORS: resolution question dialog + _("Enter new resolution: ")); + mDialog->setActionEventId("videomode"); + mDialog->addActionListener(this); + return; + } + } + const int width = atoi(mode.substr(0, mode.find("x")).c_str()); + const int height = atoi(mode.substr(mode.find("x") + 1).c_str()); + if (!width || !height) + return; + + if (width != mainGraphics->mWidth || height != mainGraphics->mHeight) + { +#if defined(WIN32) || defined(__APPLE__) || defined(ANDROID) + if (intToRenderType(config.getIntValue("opengl")) + == RENDER_SOFTWARE) + { + client->resizeVideo(width, height); + } + else + { + if (width < mainGraphics->mWidth + || height < mainGraphics->mHeight) + { + // TRANSLATORS: video settings warning + new OkDialog(_("Screen Resolution Changed"), + // TRANSLATORS: video settings warning + _("Restart your client for the change to take effect.") + + std::string("\n") + _("Some windows may be moved to " + "fit the lowered resolution.")); + } + else + { + // TRANSLATORS: video settings warning + new OkDialog(_("Screen Resolution Changed"), + // TRANSLATORS: video settings warning + _("Restart your client for the change" + " to take effect.")); + } + } +#else + mainGraphics->setWindowSize(width, height); + client->resizeVideo(width, height); +#endif + } + + config.setValue("oldscreen", config.getBoolValue("screen")); + config.setValue("oldscreenwidth", mainGraphics->mWidth); + config.setValue("oldscreenheight", mainGraphics->mHeight); + config.setValue("screenwidth", width); + config.setValue("screenheight", height); + } + if (id == "~videomode") + { + mDialog = nullptr; + } + else if (id == "customcursor") + { + config.setValue("customcursor", mCustomCursorCheckBox->isSelected()); + } + else if (id == "fpslimitcheckbox" || id == "fpslimitslider") + { + int tempFps = static_cast<int>(mFpsSlider->getValue()); + if (id == "fpslimitcheckbox" && !mFpsSlider->isEnabled()) + tempFps = 60; + else + tempFps = tempFps > 0 ? tempFps : 60; + mFps = mFpsCheckBox->isSelected() ? tempFps : 0; + // TRANSLATORS: video settings label + const std::string text = mFps > 0 ? toString(mFps) : _("None"); + + mFpsLabel->setCaption(text); + mFpsSlider->setValue(mFps); + mFpsSlider->setEnabled(mFps > 0); + } + else if (id == "altfpslimitslider") + { + int tempFps = static_cast<int>(mAltFpsSlider->getValue()); + tempFps = tempFps > 0 ? tempFps : static_cast<int>( + mAltFpsSlider->getScaleStart()); + mAltFps = tempFps; + // TRANSLATORS: video settings label + const std::string text = mAltFps > 0 ? toString(mAltFps) : _("None"); + + // TRANSLATORS: video settings label + mAltFpsLabel->setCaption(_("Alt FPS limit: ") + text); + 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()); + } +#if defined(USE_OPENGL) && !defined(ANDROID) && !defined(__APPLE__) + else if (id == "detect") + { + TestMain *test = graphicsManager.startDetection(); + if (test) + { + const int val = test->getConfig().getValueInt("opengl", -1); + if (val >= 0 && static_cast<unsigned int>(val) + < sizeof(renderToIndex) / sizeof(int)) + { + mOpenGLDropDown->setSelected(renderToIndex[val]); + } + delete test; + } + } +#endif +} diff --git a/src/gui/widgets/tabs/setup_video.h b/src/gui/widgets/tabs/setup_video.h new file mode 100644 index 000000000..e8fb415c9 --- /dev/null +++ b/src/gui/widgets/tabs/setup_video.h @@ -0,0 +1,82 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_VIDEO_H +#define GUI_SETUP_VIDEO_H + +#include "gui/widgets/tabs/setuptab.h" + +#include <guichan/keylistener.hpp> + +class Button; +class CheckBox; +class DropDown; +class Label; +class ListBox; +class ModeListModel; +class OpenGLListModel; +class Slider; +class TextDialog; + +class Setup_Video final : public SetupTab, public gcn::KeyListener +{ + public: + explicit Setup_Video(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Video) + + ~Setup_Video(); + + void apply() override; + + void cancel() override; + + void action(const gcn::ActionEvent &event) override; + + private: + bool mFullScreenEnabled; + RenderType mOpenGLEnabled; + int mFps; + int mAltFps; + ModeListModel *mModeListModel; + OpenGLListModel *mOpenGLListModel; + ListBox *mModeList; + CheckBox *mFsCheckBox; + DropDown *mOpenGLDropDown; + CheckBox *mFpsCheckBox; + Slider *mFpsSlider; + Label *mFpsLabel; + Slider *mAltFpsSlider; + Label *mAltFpsLabel; +#if !defined(ANDROID) && !defined(__APPLE__) + Button *mDetectButton; +#endif + TextDialog *mDialog; + bool mCustomCursorEnabled; + bool mEnableResize; + bool mNoFrame; + CheckBox *mCustomCursorCheckBox; + CheckBox *mEnableResizeCheckBox; + CheckBox *mNoFrameCheckBox; +}; + +#endif // GUI_SETUP_VIDEO_H diff --git a/src/gui/widgets/tabs/setup_visual.cpp b/src/gui/widgets/tabs/setup_visual.cpp new file mode 100644 index 000000000..f19b3508f --- /dev/null +++ b/src/gui/widgets/tabs/setup_visual.cpp @@ -0,0 +1,213 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setup_visual.h" + +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/namesmodel.h" +#include "gui/widgets/scrollarea.h" + +#include "client.h" + +#include "utils/gettext.h" + +#include "debug.h" + +static const int speachListSize = 4; + +static const char *const speachList[] = +{ + // TRANSLATORS: speach type + N_("No text"), + // TRANSLATORS: speach type + N_("Text"), + // TRANSLATORS: speach type + N_("Bubbles, no names"), + // TRANSLATORS: speach type + N_("Bubbles with names") +}; + +static const int ambientFxListSize = 3; + +static const char *const ambientFxList[] = +{ + // TRANSLATORS: ambient effect type + N_("off"), + // TRANSLATORS: ambient effect type + N_("low"), + // TRANSLATORS: ambient effect type + N_("high") +}; + +static const int particleTypeListSize = 3; + +static const char *const particleTypeList[] = +{ + // TRANSLATORS: patricle effects type + N_("best quality"), + // TRANSLATORS: patricle effects type + N_("normal"), + // TRANSLATORS: patricle effects type + N_("best performance") +}; + +static const int vSyncListSize = 3; + +static const char *const vSyncList[] = +{ + // TRANSLATORS: vsync type + N_("default"), + // TRANSLATORS: vsync type + N_("off"), + // TRANSLATORS: vsync type + N_("on") +}; + +Setup_Visual::Setup_Visual(const Widget2 *const widget) : + SetupTabScroll(widget), + mSpeachList(new NamesModel), + mAmbientFxList(new NamesModel), + mParticleList(new SetupItemNames), + mParticleTypeList(new NamesModel), + mVSyncList(new NamesModel) +{ + // TRANSLATORS: settings tab name + setName(_("Visual")); + // Do the layout + LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); + place(0, 0, mScroll, 10, 10); + + mPreferredFirstItemSize = 150; + + // TRANSLATORS: settings option + new SetupItemLabel(_("Notifications"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show pickup notifications in chat"), "", + "showpickupchat", this, "showpickupchatEvent"); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Show pickup notifications as particle effects"), + "", "showpickupparticle", this, "showpickupparticleEvent"); + + // TRANSLATORS: settings option + new SetupItemLabel(_("Effects"), "", this); + +#ifndef ANDROID + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Grab mouse and keyboard input"), + "", "grabinput", this, "grabinputEvent"); +#endif + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Blurring textures (OpenGL)"), + "", "blur", this, "blurEvent"); + + // TRANSLATORS: settings option + new SetupItemSlider(_("Gui opacity"), "", "guialpha", + this, "guialphaEvent", 0.1, 1.0, 150, true); + + mSpeachList->fillFromArray(&speachList[0], speachListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Overhead text"), "", "speech", this, + "speechEvent", mSpeachList, 200); + + mAmbientFxList->fillFromArray(&ambientFxList[0], ambientFxListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Ambient FX"), "", "OverlayDetail", this, + "OverlayDetailEvent", mAmbientFxList, 100); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Particle effects"), "", + "particleeffects", this, "particleeffectsEvent"); + + // TRANSLATORS: particle details + mParticleList->push_back(_("low")); + // TRANSLATORS: particle details + mParticleList->push_back(_("medium")); + // TRANSLATORS: particle details + mParticleList->push_back(_("high")); + // TRANSLATORS: particle details + mParticleList->push_back(_("max")); + (new SetupItemSlider2(_("Particle detail"), "", "particleEmitterSkip", + this, "particleEmitterSkipEvent", 0, 3, + mParticleList, true))->setInvertValue(3); + + mParticleTypeList->fillFromArray(&particleTypeList[0], + particleTypeListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Particle physics"), "", "particleFastPhysics", + this, "particleFastPhysicsEvent", mParticleTypeList, 200); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Gamma"), "", this); + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Enable gamma control"), + "", "enableGamma", this, "enableGammaEvent"); + + // TRANSLATORS: settings option + new SetupItemSlider(_("Gamma"), "", "gamma", + this, "gammeEvent", 1, 20, 350, true); + + + // TRANSLATORS: settings group + new SetupItemLabel(_("Other"), "", this); + + mVSyncList->fillFromArray(&vSyncList[0], vSyncListSize); + // TRANSLATORS: settings option + new SetupItemDropDown(_("Vsync"), "", "vsync", this, + "vsyncEvent", mVSyncList, 100); + +#if defined(WIN32) || defined(__APPLE__) + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Center game window"), + "", "centerwindow", this, "centerwindowEvent"); +#endif + + // TRANSLATORS: settings option + new SetupItemCheckBox(_("Allow screensaver to run"), + "", "allowscreensaver", this, "allowscreensaverEvent"); + + setDimension(gcn::Rectangle(0, 0, 550, 350)); +} + +Setup_Visual::~Setup_Visual() +{ + delete mSpeachList; + mSpeachList = nullptr; + delete mAmbientFxList; + mAmbientFxList = nullptr; + delete mParticleList; + mParticleList = nullptr; + delete mParticleTypeList; + mParticleTypeList = nullptr; + delete mVSyncList; + mVSyncList = nullptr; +} + +void Setup_Visual::apply() +{ + SetupTabScroll::apply(); + Client::applyGrabMode(); +} diff --git a/src/gui/widgets/tabs/setup_visual.h b/src/gui/widgets/tabs/setup_visual.h new file mode 100644 index 000000000..e1492d028 --- /dev/null +++ b/src/gui/widgets/tabs/setup_visual.h @@ -0,0 +1,48 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009-2010 Andrei Karas + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_SETUP_VISUAL_H +#define GUI_SETUP_VISUAL_H + +#include "gui/widgets/setupitem.h" + +class NamesModel; + +class Setup_Visual final : public SetupTabScroll +{ + public: + explicit Setup_Visual(const Widget2 *const widget); + + A_DELETE_COPY(Setup_Visual) + + ~Setup_Visual(); + + void apply() override; + + private: + NamesModel *mSpeachList; + NamesModel *mAmbientFxList; + SetupItemNames *mParticleList; + NamesModel *mParticleTypeList; + NamesModel *mVSyncList; +}; + +#endif // GUI_SETUP_VISUAL_H diff --git a/src/gui/widgets/tabs/setuptab.cpp b/src/gui/widgets/tabs/setuptab.cpp new file mode 100644 index 000000000..79df5e4bb --- /dev/null +++ b/src/gui/widgets/tabs/setuptab.cpp @@ -0,0 +1,39 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setuptab.h" + +#include "debug.h" + +SetupTab::SetupTab(const Widget2 *const widget) : + Container(widget), + gcn::ActionListener(), + gcn::WidgetListener(), + mName() +{ + setOpaque(false); + addWidgetListener(this); +} + +void SetupTab::externalUpdated() +{ +} diff --git a/src/gui/widgets/tabs/setuptab.h b/src/gui/widgets/tabs/setuptab.h new file mode 100644 index 000000000..ab866ba28 --- /dev/null +++ b/src/gui/widgets/tabs/setuptab.h @@ -0,0 +1,74 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_SETUPTAB_H +#define GUI_WIDGETS_SETUPTAB_H + +#include "gui/widgets/container.h" + +#include <guichan/actionlistener.hpp> +#include <guichan/widgetlistener.hpp> + +#include <string> + +#include "localconsts.h" + +/** + * A container for the contents of a tab in the setup window. + */ +class SetupTab : public Container, + public gcn::ActionListener, + public gcn::WidgetListener +{ + public: + A_DELETE_COPY(SetupTab) + + const std::string &getName() const A_WARN_UNUSED + { return mName; } + + /** + * Called when the Apply button is pressed in the setup window. + */ + virtual void apply() = 0; + + /** + * Called when the Cancel button is pressed in the setup window. + */ + virtual void cancel() = 0; + + virtual void externalUpdated(); + + protected: + explicit SetupTab(const Widget2 *const widget); + + /** + * Sets the name displayed on the tab. Should be set in the + * constructor of a subclass. + */ + void setName(const std::string &name) + { mName = name; } + + private: + std::string mName; +}; + +#endif // GUI_WIDGETS_SETUPTAB_H diff --git a/src/gui/widgets/tabs/setuptabscroll.cpp b/src/gui/widgets/tabs/setuptabscroll.cpp new file mode 100644 index 000000000..48a27a550 --- /dev/null +++ b/src/gui/widgets/tabs/setuptabscroll.cpp @@ -0,0 +1,134 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/setuptabscroll.h" + +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/setupitem.h" +#include "gui/widgets/vertcontainer.h" + +#include "debug.h" + +SetupTabScroll::SetupTabScroll(const Widget2 *const widget) : + SetupTab(widget), + mContainer(new VertContainer(this, 25, false, 8)), + mScroll(new ScrollArea(mContainer, false)), + mItems(), + mAllItems(), + mPreferredFirstItemSize(200) +{ + mScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + mScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO); +} + +SetupTabScroll::~SetupTabScroll() +{ + mScroll = nullptr; + + delete mContainer; + mContainer = nullptr; + + std::set<SetupItem*>::iterator it = mAllItems.begin(); + const std::set<SetupItem*>::iterator it_end = mAllItems.end(); + while (it != it_end) + { + delete *it; + ++ it; + } + mAllItems.clear(); +} + +void SetupTabScroll::addControl(SetupItem *const widget) +{ + const std::string actionId = widget->getActionEventId(); + if (!actionId.empty()) + { + const std::map<std::string, SetupItem*>::iterator iter + = mItems.find(actionId); + if (iter != mItems.end()) + { + delete (*iter).second; + mItems.erase(iter); + } + mItems[actionId] = widget; + } + mAllItems.insert(widget); +} + +void SetupTabScroll::addControl(SetupItem *const widget, + const std::string &event) +{ + const std::map<std::string, SetupItem*>::iterator iter + = mItems.find(event); + if (iter != mItems.end()) + { + delete (*iter).second; + mItems.erase(iter); + } + mItems[event] = widget; + mAllItems.insert(widget); +} + +void SetupTabScroll::apply() +{ + for (std::map<std::string, SetupItem*>::const_iterator + iter = mItems.begin(), iter_end = mItems.end(); + iter != iter_end; ++ iter) + { + if ((*iter).second) + (*iter).second->apply((*iter).first); + } +} + +void SetupTabScroll::cancel() +{ + for (std::map<std::string, SetupItem*>::const_iterator + iter = mItems.begin(), iter_end = mItems.end(); + iter != iter_end; ++ iter) + { + if ((*iter).second) + (*iter).second->cancel((*iter).first); + } +} + +void SetupTabScroll::externalUpdated() +{ + for (std::map<std::string, SetupItem*>::const_iterator + iter = mItems.begin(), iter_end = mItems.end(); + iter != iter_end; ++ iter) + { + SetupItem *const widget = (*iter).second; + if (widget && !widget->isMainConfig()) + widget->externalUpdated((*iter).first); + } +} + +void SetupTabScroll::widgetResized(const gcn::Event &event A_UNUSED) +{ + mScroll->setWidth(getWidth() - 12); + mScroll->setHeight(getHeight() - 12 - 12); +} + +void SetupTabScroll::reread(const std::string &name) +{ + SetupItem *const item = mItems[name + "Event"]; + if (item) + item->rereadValue(); +} diff --git a/src/gui/widgets/tabs/setuptabscroll.h b/src/gui/widgets/tabs/setuptabscroll.h new file mode 100644 index 000000000..e7be18709 --- /dev/null +++ b/src/gui/widgets/tabs/setuptabscroll.h @@ -0,0 +1,75 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_SETUPTABSCROLL_H +#define GUI_WIDGETS_SETUPTABSCROLL_H + +#include "gui/widgets/tabs/setuptab.h" + +#include <map> +#include <set> + +#include "localconsts.h" + +class SetupItem; +class ScrollArea; +class VertContainer; + +class SetupTabScroll : public SetupTab +{ + public: + explicit SetupTabScroll(const Widget2 *const widget); + + A_DELETE_COPY(SetupTabScroll) + + virtual ~SetupTabScroll(); + + void addControl(SetupItem *const widget); + + void addControl(SetupItem *const widget, const std::string &event); + + VertContainer *getContainer() const A_WARN_UNUSED + { return mContainer; } + + virtual void apply() override; + + virtual void cancel() override; + + virtual void externalUpdated() override; + + virtual void action(const gcn::ActionEvent &event A_UNUSED) override + { } + + int getPreferredFirstItemSize() A_WARN_UNUSED + { return mPreferredFirstItemSize; } + + void widgetResized(const gcn::Event &event) override; + + void reread(const std::string &name); + + protected: + VertContainer *mContainer; + ScrollArea *mScroll; + std::map<std::string, SetupItem*> mItems; + std::set<SetupItem*> mAllItems; + int mPreferredFirstItemSize; +}; + +#endif // GUI_WIDGETS_SETUPTABSCROLL_H diff --git a/src/gui/widgets/tabs/tab.cpp b/src/gui/widgets/tabs/tab.cpp new file mode 100644 index 000000000..8c25e7b1d --- /dev/null +++ b/src/gui/widgets/tabs/tab.cpp @@ -0,0 +1,346 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/tab.h" + +#include "client.h" +#include "graphicsvertexes.h" + +#include "gui/widgets/label.h" +#include "gui/widgets/tabbedarea.h" + +#include "debug.h" + +int Tab::mInstances = 0; +float Tab::mAlpha = 1.0; + +enum +{ + TAB_STANDARD = 0, // 0 + TAB_HIGHLIGHTED, // 1 + TAB_SELECTED, // 2 + TAB_UNUSED, // 3 + TAB_COUNT // 4 - Must be last. +}; + +static std::string const data[TAB_COUNT] = +{ + "tab.xml", + "tab_highlighted.xml", + "tab_selected.xml", + "tab_unused.xml" +}; + +Skin *Tab::tabImg[TAB_COUNT]; + +Tab::Tab(const Widget2 *const widget) : + gcn::BasicContainer(), + Widget2(widget), + gcn::MouseListener(), + gcn::WidgetListener(), + mLabel(new Label(this)), + mTabbedArea(nullptr), + mTabColor(&getThemeColor(Theme::TAB)), + mTabOutlineColor(&getThemeColor(Theme::TAB_OUTLINE)), + mTabHighlightedColor(&getThemeColor(Theme::TAB_HIGHLIGHTED)), + mTabHighlightedOutlineColor(&getThemeColor( + Theme::TAB_HIGHLIGHTED_OUTLINE)), + mTabSelectedColor(&getThemeColor(Theme::TAB_SELECTED)), + mTabSelectedOutlineColor(&getThemeColor(Theme::TAB_SELECTED_OUTLINE)), + mFlashColor(&getThemeColor(Theme::TAB_FLASH)), + mFlashOutlineColor(&getThemeColor(Theme::TAB_FLASH_OUTLINE)), + mPlayerFlashColor(&getThemeColor(Theme::TAB_PLAYER_FLASH)), + mPlayerFlashOutlineColor(&getThemeColor(Theme::TAB_PLAYER_FLASH_OUTLINE)), + mFlash(0), + mVertexes(new ImageCollection), + mImage(nullptr), + mMode(0), + mRedraw(true), + mHasMouse(false) +{ + init(); +} + +Tab::~Tab() +{ + if (gui) + gui->removeDragged(this); + + mInstances--; + if (mInstances == 0 && Theme::instance()) + { + Theme *const theme = Theme::instance(); + for (int mode = 0; mode < TAB_COUNT; mode ++) + theme->unload(tabImg[mode]); + } + + delete mLabel; + mLabel = nullptr; + + if (mImage) + { + mImage->decRef(); + mImage = nullptr; + } + delete mVertexes; + mVertexes = nullptr; +} + +void Tab::init() +{ + addMouseListener(this); + setFocusable(false); + setFrameSize(0); + mFlash = 0; + + addWidgetListener(this); + + if (mInstances == 0) + { + // Load the skin + Theme *const theme = Theme::instance(); + if (theme) + { + for (int mode = 0; mode < TAB_COUNT; mode ++) + tabImg[mode] = theme->load(data[mode], "tab.xml"); + } + updateAlpha(); + } + mInstances++; + + add(mLabel); + + const Skin *const skin = tabImg[TAB_STANDARD]; + if (!skin) + return; + const int padding = skin->getPadding(); + + mLabel->setPosition(padding, padding); +} + +void Tab::updateAlpha() +{ + const float alpha = std::max(client->getGuiAlpha(), + Theme::instance()->getMinimumOpacity()); + + if (alpha != mAlpha) + { + mAlpha = alpha; + for (int a = 0; a < 9; a++) + { + for (int t = 0; t < TAB_COUNT; t++) + { + Skin *const skin = tabImg[t]; + if (skin) + { + const ImageRect &rect = skin->getBorder(); + Image *const image = rect.grid[a]; + if (image) + image->setAlpha(mAlpha); + } + } + } + } +} + +void Tab::draw(gcn::Graphics *graphics) +{ + BLOCK_START("Tab::draw") + int mode = TAB_STANDARD; + + // check which type of tab to draw + if (mTabbedArea) + { + if (mTabbedArea->isTabSelected(this)) + { + mLabel->setForegroundColorAll(*mTabSelectedColor, + *mTabSelectedOutlineColor); + mode = TAB_SELECTED; + // if tab is selected, it doesnt need to highlight activity + mFlash = 0; + } + else if (mHasMouse) + { + mLabel->setForegroundColorAll(*mTabHighlightedColor, + *mTabHighlightedOutlineColor); + mode = TAB_HIGHLIGHTED; + } + else + { + mLabel->setForegroundColorAll(*mTabColor, *mTabOutlineColor); + } + + switch (mFlash) + { + case 1: + mLabel->setForegroundColorAll(*mFlashColor, + *mFlashOutlineColor); + break; + case 2: + mLabel->setForegroundColorAll(*mPlayerFlashColor, + *mPlayerFlashOutlineColor); + break; + default: + break; + } + } + + const Skin *const skin = tabImg[mode]; + if (!skin) + { + BLOCK_END("Tab::draw") + return; + } + + updateAlpha(); + + Graphics *const g = static_cast<Graphics*>(graphics); + + if (skin) + { + // draw tab + if (openGLMode != RENDER_SAFE_OPENGL) + { + const ImageRect &rect = skin->getBorder(); + if (mRedraw || mode != mMode || g->getRedraw()) + { + mMode = mode; + mRedraw = false; + mVertexes->clear(); + g->calcWindow(mVertexes, 0, 0, + mDimension.width, mDimension.height, rect); + + if (mImage) + { + const Skin *const skin1 = tabImg[TAB_STANDARD]; + if (skin1) + { + const int padding = skin1->getPadding(); + g->calcTile(mVertexes, mImage, padding, padding); + } + } + } + + g->drawTile(mVertexes); + } + else + { + g->drawImageRect(0, 0, + mDimension.width, mDimension.height, skin->getBorder()); + if (mImage) + { + const Skin *const skin1 = tabImg[TAB_STANDARD]; + if (skin1) + { + const int padding = skin1->getPadding(); + g->drawImage(mImage, padding, padding); + } + } + } + } + + drawChildren(graphics); + BLOCK_END("Tab::draw") +} + +void Tab::widgetResized(const gcn::Event &event A_UNUSED) +{ + mRedraw = true; +} + +void Tab::widgetMoved(const gcn::Event &event A_UNUSED) +{ + mRedraw = true; +} + +void Tab::setLabelFont(gcn::Font *const font) +{ + if (!mLabel) + return; + + mLabel->setFont(font); + mLabel->adjustSize(); + adjustSize(); +} + + +void Tab::adjustSize() +{ + const Skin *const skin = tabImg[TAB_STANDARD]; + if (!skin) + return; + const int pad2 = skin->getPadding() * 2; + + if (mImage) + { + const SDL_Rect &rect = mImage->mBounds; + setSize(rect.w + pad2, rect.h + pad2); + } + else + { + setSize(mLabel->getWidth() + pad2, + mLabel->getHeight() + pad2); + } + + if (mTabbedArea) + mTabbedArea->adjustTabPositions(); +} + +void Tab::setTabbedArea(TabbedArea* tabbedArea) +{ + mTabbedArea = tabbedArea; +} + +TabbedArea* Tab::getTabbedArea() const +{ + return mTabbedArea; +} + +void Tab::setCaption(const std::string &caption) +{ + mLabel->setCaption(caption); + mLabel->adjustSize(); + adjustSize(); +} + +void Tab::setImage(Image *const image) +{ + if (mImage) + mImage->decRef(); + mImage = image; + adjustSize(); +} + +const std::string &Tab::getCaption() const +{ + return mLabel->getCaption(); +} + +void Tab::mouseEntered(gcn::MouseEvent& mouseEvent A_UNUSED) +{ + mHasMouse = true; +} + +void Tab::mouseExited(gcn::MouseEvent& mouseEvent A_UNUSED) +{ + mHasMouse = false; +} diff --git a/src/gui/widgets/tabs/tab.h b/src/gui/widgets/tabs/tab.h new file mode 100644 index 000000000..ecd0ae494 --- /dev/null +++ b/src/gui/widgets/tabs/tab.h @@ -0,0 +1,187 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_TAB_H +#define GUI_WIDGETS_TAB_H + +#include "gui/widgets/widget2.h" + +#include <guichan/basiccontainer.hpp> +#include <guichan/mouselistener.hpp> +#include <guichan/widgetlistener.hpp> + +#include "localconsts.h" + +class ImageCollection; +class Label; +class Skin; +class TabbedArea; + +/** + * A tab, the same as the Guichan tab in 0.8, but extended + */ +class Tab : public gcn::BasicContainer, + public Widget2, + public gcn::MouseListener, + public gcn::WidgetListener +{ + public: + explicit Tab(const Widget2 *const widget); + + A_DELETE_COPY(Tab) + + virtual ~Tab(); + + /** + * Update the alpha value to the graphic components. + */ + void updateAlpha(); + + /** + * Draw the tabbed area. + */ + void draw(gcn::Graphics *graphics) override; + + /** + * Set the normal color for the tab's text. + */ + void setTabColor(const gcn::Color *const color1, + const gcn::Color *const color2) + { + mTabColor = color1; + mTabOutlineColor = color2; + } + + /** + * Set the highlighted color for the tab's text. + */ + void setHighlightedTabColor(const gcn::Color *const color1, + const gcn::Color *const color2) + { + mTabHighlightedColor = color1; + mTabHighlightedOutlineColor = color2; + } + + /** + * Set the selected color for the tab's text. + */ + void setSelectedTabColor(const gcn::Color *const color1, + const gcn::Color *const color2) + { + mTabSelectedColor = color1; + mTabSelectedOutlineColor = color2; + } + + /** + * Set the flash color for the tab's text. + */ + void setFlashTabColor(const gcn::Color *const color1, + const gcn::Color *const color2) + { + mFlashColor = color1; + mFlashOutlineColor = color2; + } + + /** + * Set the player flash color for the tab's text. + */ + void setPlayerFlashTabColor(const gcn::Color *const color1, + const gcn::Color *const color2) + { + mPlayerFlashColor = color1; + mPlayerFlashOutlineColor = color2; + } + + /** + * Set tab flashing state + */ + void setFlash(const int flash) + { mFlash = flash; } + + int getFlash() const A_WARN_UNUSED + { return mFlash; } + + void widgetResized(const gcn::Event &event) override; + + void widgetMoved(const gcn::Event &event) override; + + void setLabelFont(gcn::Font *const font); + + Label *getLabel() const A_WARN_UNUSED + { return mLabel; } + + void adjustSize(); + + void setTabbedArea(TabbedArea* tabbedArea); + + TabbedArea* getTabbedArea() const A_WARN_UNUSED; + + void setCaption(const std::string& caption); + + const std::string &getCaption() const A_WARN_UNUSED; + + void mouseEntered(gcn::MouseEvent &mouseEvent) override; + + void mouseExited(gcn::MouseEvent &mouseEvent) override; + + void setImage(Image *const image); + + protected: + friend class TabbedArea; + + virtual void setCurrent() + { } + + Label* mLabel; + + + TabbedArea* mTabbedArea; + + private: + /** Load images if no other instances exist yet */ + void init(); + + static Skin *tabImg[4]; /**< Tab state graphics */ + static int mInstances; /**< Number of tab instances */ + static float mAlpha; + + const gcn::Color *mTabColor; + const gcn::Color *mTabOutlineColor; + const gcn::Color *mTabHighlightedColor; + const gcn::Color *mTabHighlightedOutlineColor; + const gcn::Color *mTabSelectedColor; + const gcn::Color *mTabSelectedOutlineColor; + const gcn::Color *mFlashColor; + const gcn::Color *mFlashOutlineColor; + const gcn::Color *mPlayerFlashColor; + const gcn::Color *mPlayerFlashOutlineColor; + int mFlash; + ImageCollection *mVertexes; + Image *mImage; + int mMode; + bool mRedraw; + + protected: + bool mHasMouse; +}; + +#endif // GUI_WIDGETS_TAB_H diff --git a/src/gui/widgets/tabs/tradetab.cpp b/src/gui/widgets/tabs/tradetab.cpp new file mode 100644 index 000000000..f9e1dc9e0 --- /dev/null +++ b/src/gui/widgets/tabs/tradetab.cpp @@ -0,0 +1,51 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/tradetab.h" + +#include "chatlogger.h" + +#include "utils/gettext.h" + +#include "debug.h" + +TradeTab::TradeTab(const Widget2 *const widget) : + // TRANSLATORS: trade chat tab name + ChatTab(widget, _("Trade"), TRADE_CHANNEL) +{ +} + +TradeTab::~TradeTab() +{ +} + +void TradeTab::handleInput(const std::string &msg) +{ + std::string str("\302\202" + msg); + ChatTab::handleInput(str); +} + +void TradeTab::saveToLogFile(const std::string &msg) const +{ + if (chatLogger) + chatLogger->log(std::string("#Trade"), std::string(msg)); +} diff --git a/src/gui/widgets/tabs/tradetab.h b/src/gui/widgets/tabs/tradetab.h new file mode 100644 index 000000000..8c28704a4 --- /dev/null +++ b/src/gui/widgets/tabs/tradetab.h @@ -0,0 +1,51 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_TRADETAB_H +#define GUI_WIDGETS_TRADETAB_H + +#include "gui/widgets/tabs/chattab.h" + +/** + * A tab for a party chat channel. + */ +class TradeTab final : public ChatTab +{ + public: + explicit TradeTab(const Widget2 *const widget); + + A_DELETE_COPY(TradeTab) + + ~TradeTab(); + + int getType() const override A_WARN_UNUSED + { return ChatTab::TAB_TRADE; } + + void saveToLogFile(const std::string &msg) const override; + + protected: + void handleInput(const std::string &msg) override; +}; + +extern TradeTab *tradeChatTab; + +#endif // GUI_WIDGETS_TRADETAB_H diff --git a/src/gui/widgets/tabs/whispertab.cpp b/src/gui/widgets/tabs/whispertab.cpp new file mode 100644 index 000000000..7ad14ac65 --- /dev/null +++ b/src/gui/widgets/tabs/whispertab.cpp @@ -0,0 +1,196 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "gui/widgets/tabs/whispertab.h" + +#include "chatlogger.h" +#include "commands.h" + +#include "being/localplayer.h" + +#include "net/chathandler.h" +#include "net/net.h" + +#include "gui/widgets/windowcontainer.h" + +#include "utils/gettext.h" + +#include "debug.h" + +WhisperTab::WhisperTab(const Widget2 *const widget, const std::string &nick) : + ChatTab(widget, nick, ""), + mNick(nick) +{ + setWhisperTabColors(); +} + +WhisperTab::~WhisperTab() +{ + if (chatWindow) + chatWindow->removeWhisper(mNick); +} + +void WhisperTab::handleInput(const std::string &msg) +{ + if (chatWindow) + { + Net::getChatHandler()->privateMessage(mNick, + chatWindow->doReplace(msg)); + } + else + { + Net::getChatHandler()->privateMessage(mNick, msg); + } + + if (player_node) + chatLog(player_node->getName(), msg); + else + chatLog("?", msg); +} + +void WhisperTab::handleCommand(const std::string &msg) +{ + if (msg == "close") + { + delete this; + return; + } + + const size_t pos = msg.find(' '); + const std::string type(msg, 0, pos); + const std::string args(msg, pos == std::string::npos + ? msg.size() : pos + 1); + + if (type == "me") + { + std::string str = strprintf("*%s*", args.c_str()); + Net::getChatHandler()->privateMessage(mNick, str); + if (player_node) + chatLog(player_node->getName(), str); + else + chatLog("?", str); + } + else + { + ChatTab::handleCommand(msg); + } +} + +void WhisperTab::showHelp() +{ + // TRANSLATORS: whisper tab help + chatLog(_("/ignore > Ignore the other player")); + // TRANSLATORS: whisper tab help + chatLog(_("/unignore > Stop ignoring the other player")); + // TRANSLATORS: whisper tab help + chatLog(_("/close > Close the whisper tab")); +} + +bool WhisperTab::handleCommand(const std::string &type, + const std::string &args) +{ + if (type == "help") + { + if (args == "close") + { + // TRANSLATORS: whisper tab help + chatLog(_("Command: /close")); + // TRANSLATORS: whisper tab help + chatLog(_("This command closes the current whisper tab.")); + } + else if (args == "ignore") + { + // TRANSLATORS: whisper tab help + chatLog(_("Command: /ignore")); + // TRANSLATORS: whisper tab help + chatLog(_("This command ignores the other player regardless of " + "current relations.")); + } + else if (args == "unignore") + { + // TRANSLATORS: whisper tab help + chatLog(_("Command: /unignore <player>")); + // TRANSLATORS: whisper tab help + chatLog(_("This command stops ignoring the other player if they " + "are being ignored.")); + } + else + { + return false; + } + } + else if (type == "close") + { + if (windowContainer) + windowContainer->scheduleDelete(this); + else + delete this; + if (chatWindow) + chatWindow->defaultTab(); + } + else if (type == "ignore") + { + Commands::ignore(mNick, this); + } + else if (type == "unignore") + { + Commands::unignore(mNick, this); + } + else + { + return false; + } + + return true; +} + +void WhisperTab::saveToLogFile(const std::string &msg) const +{ + if (chatLogger) + chatLogger->log(getNick(), msg); +} + +void WhisperTab::getAutoCompleteList(StringVect &names) const +{ + names.push_back(mNick); +} + +void WhisperTab::setWhisperTabColors() +{ + setTabColor(&getThemeColor(Theme::WHISPER_TAB), + &getThemeColor(Theme::WHISPER_TAB_OUTLINE)); + setHighlightedTabColor(&getThemeColor(Theme::WHISPER_TAB_HIGHLIGHTED), + &getThemeColor(Theme::WHISPER_TAB_HIGHLIGHTED_OUTLINE)); + setSelectedTabColor(&getThemeColor(Theme::WHISPER_TAB_SELECTED), + &getThemeColor(Theme::WHISPER_TAB_SELECTED_OUTLINE)); +} + +void WhisperTab::setWhisperTabOfflineColors() +{ + setTabColor(&getThemeColor(Theme::WHISPER_TAB_OFFLINE), + &getThemeColor(Theme::WHISPER_TAB_OFFLINE_OUTLINE)); + setHighlightedTabColor(&getThemeColor( + Theme::WHISPER_TAB_OFFLINE_HIGHLIGHTED), &getThemeColor( + Theme::WHISPER_TAB_OFFLINE_HIGHLIGHTED_OUTLINE)); + setSelectedTabColor(&getThemeColor(Theme::WHISPER_TAB_OFFLINE_SELECTED), + &getThemeColor(Theme::WHISPER_TAB_OFFLINE_SELECTED_OUTLINE)); +} diff --git a/src/gui/widgets/tabs/whispertab.h b/src/gui/widgets/tabs/whispertab.h new file mode 100644 index 000000000..97e6427c2 --- /dev/null +++ b/src/gui/widgets/tabs/whispertab.h @@ -0,0 +1,74 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUI_WIDGETS_WHISPERTAB_H +#define GUI_WIDGETS_WHISPERTAB_H + +#include "gui/widgets/tabs/chattab.h" + +/** + * A tab for whispers from a single player. + */ +class WhisperTab final : public ChatTab +{ + public: + A_DELETE_COPY(WhisperTab) + + const std::string &getNick() const A_WARN_UNUSED + { return mNick; } + + void showHelp() override; + + bool handleCommand(const std::string &type, + const std::string &args) override; + + int getType() const override A_WARN_UNUSED + { return ChatTab::TAB_WHISPER; } + + void saveToLogFile(const std::string &msg) const override; + + void setWhisperTabColors(); + + void setWhisperTabOfflineColors(); + + protected: + friend class ChatWindow; + + void getAutoCompleteList(StringVect &names) const override; + /** + * Constructor. + * + * @param nick the name of the player this tab is whispering to + */ + WhisperTab(const Widget2 *const widget, const std::string &nick); + + ~WhisperTab(); + + void handleInput(const std::string &msg) override; + + void handleCommand(const std::string &msg) override; + + private: + std::string mNick; +}; + +#endif // GUI_WIDGETS_WHISPERTAB_H |