diff options
author | Thorbjørn Lindeijer <thorbjorn.lindeijer@nokia.com> | 2010-09-25 03:15:26 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <thorbjorn.lindeijer@nokia.com> | 2010-09-25 03:15:26 +0200 |
commit | 661d16e98c62dfff40f481177bf3f1a0c58c2124 (patch) | |
tree | a415866c4c94a0a0c53045a47220ca413ae9c5c9 /src/gui | |
parent | 758d80263b1647c712c0e0cdd3dfca9945a1bb7e (diff) | |
parent | 7d0738df0d139af3175fcc1fec5b9be4a467f4f4 (diff) | |
download | mana-661d16e98c62dfff40f481177bf3f1a0c58c2124.tar.gz mana-661d16e98c62dfff40f481177bf3f1a0c58c2124.tar.bz2 mana-661d16e98c62dfff40f481177bf3f1a0c58c2124.tar.xz mana-661d16e98c62dfff40f481177bf3f1a0c58c2124.zip |
Merge branch '1.0'
Conflicts:
src/actorspritemanager.h
src/beingmanager.cpp
src/game.cpp
src/gui/beingpopup.cpp
src/gui/chat.cpp
src/gui/chat.h
src/gui/inventorywindow.h
src/gui/itempopup.cpp
src/gui/socialwindow.cpp
src/gui/statuswindow.cpp
src/gui/widgets/chattab.cpp
src/gui/widgets/chattab.h
src/net/tmwa/inventoryhandler.cpp
src/net/tmwa/partyhandler.cpp
src/party.cpp
src/sound.cpp
src/utils/stringutils.cpp
src/utils/stringutils.h
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/beingpopup.cpp | 25 | ||||
-rw-r--r-- | src/gui/charselectdialog.cpp | 20 | ||||
-rw-r--r-- | src/gui/chat.cpp | 178 | ||||
-rw-r--r-- | src/gui/chat.h | 21 | ||||
-rw-r--r-- | src/gui/inventorywindow.cpp | 9 | ||||
-rw-r--r-- | src/gui/inventorywindow.h | 5 | ||||
-rw-r--r-- | src/gui/itempopup.cpp | 35 | ||||
-rw-r--r-- | src/gui/minimap.cpp | 3 | ||||
-rw-r--r-- | src/gui/popupmenu.cpp | 3 | ||||
-rw-r--r-- | src/gui/sell.cpp | 2 | ||||
-rw-r--r-- | src/gui/serverdialog.cpp | 2 | ||||
-rw-r--r-- | src/gui/setup_video.cpp | 20 | ||||
-rw-r--r-- | src/gui/skilldialog.cpp | 10 | ||||
-rw-r--r-- | src/gui/socialwindow.cpp | 30 | ||||
-rw-r--r-- | src/gui/statuswindow.cpp | 18 | ||||
-rw-r--r-- | src/gui/statuswindow.h | 2 | ||||
-rw-r--r-- | src/gui/textdialog.cpp | 14 | ||||
-rw-r--r-- | src/gui/textdialog.h | 2 | ||||
-rw-r--r-- | src/gui/widgets/chattab.cpp | 6 | ||||
-rw-r--r-- | src/gui/widgets/chattab.h | 8 | ||||
-rw-r--r-- | src/gui/widgets/shoplistbox.cpp | 11 | ||||
-rw-r--r-- | src/gui/widgets/shoplistbox.h | 13 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.cpp | 20 | ||||
-rw-r--r-- | src/gui/widgets/textfield.cpp | 121 | ||||
-rw-r--r-- | src/gui/widgets/textfield.h | 69 | ||||
-rw-r--r-- | src/gui/windowmenu.cpp | 1 |
26 files changed, 371 insertions, 277 deletions
diff --git a/src/gui/beingpopup.cpp b/src/gui/beingpopup.cpp index ee9fd66d..ae0b43fd 100644 --- a/src/gui/beingpopup.cpp +++ b/src/gui/beingpopup.cpp @@ -65,25 +65,28 @@ void BeingPopup::show(int x, int y, Being *b) return; } + mBeingName->setCaption(b->getName()); + mBeingName->adjustSize(); + + int minWidth = mBeingName->getWidth(); + const int height = getFont()->getHeight(); + if (!(b->getPartyName().empty())) { - mBeingName->setCaption(b->getName()); - mBeingName->adjustSize(); - mBeingParty->setCaption(strprintf(_("Party: %s"), b->getPartyName().c_str())); mBeingParty->adjustSize(); - int minWidth = std::max(mBeingName->getWidth(), - mBeingParty->getWidth()); - - const int height = getFont()->getHeight(); + if (minWidth < mBeingParty->getWidth()) + minWidth = mBeingParty->getWidth(); setContentSize(minWidth + 10, (height * 2) + 10); - - position(x, y); - return; + } + else + { + mBeingParty->setCaption(""); + setContentSize(minWidth + 10, height + 10); } - setVisible(false); + position(x, y); } diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp index 9d6050f8..1c292759 100644 --- a/src/gui/charselectdialog.cpp +++ b/src/gui/charselectdialog.cpp @@ -164,10 +164,10 @@ CharSelectDialog::CharSelectDialog(LoginData *loginData): addKeyListener(this); center(); - mCharacterEntries[0]->requestFocus(); setVisible(true); Net::getCharHandler()->setCharSelectDialog(this); + mCharacterEntries[0]->requestFocus(); } CharSelectDialog::~CharSelectDialog() @@ -328,10 +328,10 @@ CharacterDisplay::CharacterDisplay(CharSelectDialog *charSelectDialog): mCharacter(0), mPlayerBox(new PlayerBox) { - mButton = new Button("wwwwwwwww", "go", charSelectDialog); - mName = new Label("wwwwwwwwwwwwwwwwwwwwwwww"); - mLevel = new Label("(888)"); - mMoney = new Label("wwwwwwwww"); + mButton = new Button("", "go", charSelectDialog); + mName = new Label(""); + mLevel = new Label(""); + mMoney = new Label(""); mDelete = new Button(_("Delete"), "delete", charSelectDialog); @@ -347,15 +347,7 @@ CharacterDisplay::CharacterDisplay(CharSelectDialog *charSelectDialog): update(); - // Setting the width so that the largest label fits. - mName->adjustSize(); - mMoney->adjustSize(); - int width = 74; - if (width < 20 + mName->getWidth()) - width = 20 + mName->getWidth(); - if (width < 20 + mMoney->getWidth()) - width = 20 + mMoney->getWidth(); - h.reflowLayout(width, 112 + mName->getHeight() + mLevel->getHeight() + + h.reflowLayout(80, 112 + mName->getHeight() + mLevel->getHeight() + mMoney->getHeight() + mButton->getHeight() + mDelete->getHeight()); } diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index b1d4b131..8e0f5941 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -73,9 +73,21 @@ class ChatInput : public TextField, public gcn::FocusListener } }; +class ChatAutoComplete : public AutoCompleteLister +{ + void getAutoCompleteList(std::vector<std::string> &list) const + { + ChatTab *tab = static_cast<ChatTab*>(chatWindow->mChatTabs + ->getSelectedTab()); + + return tab->getAutoCompleteList(list); + } +}; ChatWindow::ChatWindow(): Window(_("Chat")), + mHistory(new TextHistory()), + mAutoComplete(new ChatAutoComplete), mTmpVisible(false) { listen("Chat"); @@ -108,9 +120,8 @@ ChatWindow::ChatWindow(): loadWindowState(); - // Add key listener to chat input to be able to respond to up/down - mChatInput->addKeyListener(this); - mCurHist = mHistory.end(); + mChatInput->setHistory(mHistory); + mChatInput->setAutoComplete(mAutoComplete); mReturnToggles = config.getBoolValue("ReturnToggles"); @@ -123,6 +134,8 @@ ChatWindow::~ChatWindow() delete mRecorder; removeAllWhispers(); delete mItemLinkHandler; + delete mHistory; + delete mAutoComplete; } void ChatWindow::resetToDefaultSize() @@ -177,14 +190,6 @@ void ChatWindow::action(const gcn::ActionEvent &event) if (!message.empty()) { - // If message different from previous, put it in the history - if (mHistory.empty() || message != mHistory.back()) - { - mHistory.push_back(message); - } - // Reset history iterator - mCurHist = mHistory.end(); - // Send the message to the server chatInput(message); @@ -370,48 +375,6 @@ void ChatWindow::mouseDragged(gcn::MouseEvent &event) } } - -void ChatWindow::keyPressed(gcn::KeyEvent &event) -{ - if (event.getKey().getValue() == Key::DOWN) - { - if (mCurHist != mHistory.end()) - { - // Move forward through the history - HistoryIterator prevHist = mCurHist++; - - if (mCurHist != mHistory.end()) - { - mChatInput->setText(*mCurHist); - mChatInput->setCaretPosition(mChatInput->getText().length()); - } - else - { - mChatInput->setText(""); - mCurHist = prevHist; - } - } - else if (mChatInput->getText() != "") - { - mChatInput->setText(""); - } - } - else if (event.getKey().getValue() == Key::UP && - mCurHist != mHistory.begin() && mHistory.size() > 0) - { - // Move backward through the history - mCurHist--; - mChatInput->setText(*mCurHist); - mChatInput->setCaretPosition(mChatInput->getText().length()); - } - else if (event.getKey().getValue() == Key::TAB && - mChatInput->getText() != "") - { - autoComplete(); - return; - } -} - void ChatWindow::event(const std::string &channel, const Mana::Event &event) { if (channel == "Notices") @@ -558,112 +521,3 @@ ChatTab *ChatWindow::addWhisperTab(const std::string &nick, bool switchTo) return ret; } - -void ChatWindow::autoComplete() -{ - int caretPos = mChatInput->getCaretPosition(); - int startName = 0; - const std::string inputText = mChatInput->getText(); - std::string name = inputText.substr(0, caretPos); - std::string newName(""); - - for (int f = caretPos - 1; f > -1; f --) - { - if (isWordSeparator(inputText[f])) - { - startName = f + 1; - name = inputText.substr(f + 1, caretPos - f); - break; - } - } - - if (caretPos - 1 + 1 == startName) - return; - - - ChatTab *cTab = static_cast<ChatTab*>(mChatTabs->getSelectedTab()); - std::vector<std::string> nameList; - cTab->getAutoCompleteList(nameList); - newName = autoComplete(nameList, name); - - if (newName == "") - { - actorSpriteManager->getPlayerNames(nameList, true); - newName = autoComplete(nameList, name); - } - if (newName == "") - { - newName = autoCompleteHistory(name); - } - - if (newName != "") - { - if(inputText[0] == '@' || inputText[0] == '/') - newName = "\"" + newName + "\""; - - mChatInput->setText(inputText.substr(0, startName) + newName - + inputText.substr(caretPos, inputText.length() - caretPos)); - - if (startName > 0) - mChatInput->setCaretPosition(caretPos - name.length() + newName.length() + 1); - else - mChatInput->setCaretPosition(caretPos - name.length() + newName.length()); - } -} - -std::string ChatWindow::autoComplete(std::vector<std::string> &names, - std::string partName) const -{ - std::vector<std::string>::iterator i = names.begin(); - toLower(partName); - std::string newName(""); - - while (i != names.end()) - { - if (!i->empty()) - { - std::string name = *i; - toLower(name); - - std::string::size_type pos = name.find(partName, 0); - if (pos == 0) - { - if (newName != "") - { - toLower(newName); - newName = findSameSubstring(name, newName); - } - else - { - newName = *i; - } - } - } - ++i; - } - - return newName; -} - -std::string ChatWindow::autoCompleteHistory(std::string partName) -{ - History::iterator i = mHistory.begin(); - std::vector<std::string> nameList; - - while (i != mHistory.end()) - { - std::string line = *i; - unsigned int f = 0; - while (f < line.length() && !isWordSeparator(line.at(f))) - { - f++; - } - line = line.substr(0, f); - if (line != "") - { - nameList.push_back(line); - } - ++i; - } - return autoComplete(nameList, partName); -} diff --git a/src/gui/chat.h b/src/gui/chat.h index db5fe293..3a001432 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -25,6 +25,7 @@ #include "listener.h" #include "gui/widgets/window.h" +#include "gui/widgets/textfield.h" #include <guichan/actionlistener.hpp> #include <guichan/keylistener.hpp> @@ -76,7 +77,6 @@ struct CHATLOG */ class ChatWindow : public Window, public gcn::ActionListener, - public gcn::KeyListener, public Mana::Listener { public: @@ -146,9 +146,6 @@ class ChatWindow : public Window, */ void chatInput(const std::string &msg); - /** Called when key is pressed */ - void keyPressed(gcn::KeyEvent &event); - /** Add the given text to the chat input. */ void addInputText(const std::string &text); @@ -158,7 +155,6 @@ class ChatWindow : public Window, /** Override to reset mTmpVisible */ void setVisible(bool visible); - void mousePressed(gcn::MouseEvent &event); void mouseDragged(gcn::MouseEvent &event); @@ -193,6 +189,7 @@ class ChatWindow : public Window, protected: friend class ChatTab; friend class WhisperTab; + friend class ChatAutoComplete; /** Remove the given tab from the window */ void removeTab(ChatTab *tab); @@ -204,13 +201,6 @@ class ChatWindow : public Window, void removeAllWhispers(); - void autoComplete(); - - std::string autoCompleteHistory(std::string partName); - - std::string autoComplete(std::vector<std::string> &names, - std::string partName) const; - /** Used for showing item popup on clicking links **/ ItemLinkHandler *mItemLinkHandler; Recorder *mRecorder; @@ -218,6 +208,9 @@ class ChatWindow : public Window, /** Input box for typing chat messages. */ ChatInput *mChatInput; + TextHistory *mHistory; + AutoCompleteLister *mAutoComplete; + private: bool mTmpVisible; @@ -228,10 +221,6 @@ class ChatWindow : public Window, /** Manage whisper tabs */ TabMap mWhispers; - typedef std::list<std::string> History; - typedef History::iterator HistoryIterator; - History mHistory; /**< Command history. */ - HistoryIterator mCurHist; /**< History iterator. */ bool mReturnToggles; /**< Marks whether <Return> toggles the chat log or not */ }; diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 6ad1b05f..62b63f24 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -312,11 +312,19 @@ void InventoryWindow::valueChanged(const gcn::SelectionEvent &event) (item->getQuantity() - 1)); } + updateButtons(); +} + +void InventoryWindow::updateButtons() +{ + Item *item = mItems->getSelectedItem(); + if (!item || item->getQuantity() == 0) { mUseButton->setEnabled(false); mEquipButton->setEnabled(false); mDropButton->setEnabled(false); + mSplitButton->setEnabled(false); return; } @@ -347,7 +355,6 @@ void InventoryWindow::valueChanged(const gcn::SelectionEvent &event) mSplitButton->setEnabled(false); } - void InventoryWindow::setSplitAllowed(bool allowed) { mSplitButton->setVisible(allowed); diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index 1b68b897..99fc1c03 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -103,6 +103,11 @@ class InventoryWindow : public Window, */ void close(); + /** + * Updates the buttons. + */ + void updateButtons(); + void slotsChanged(Inventory* inventory); bool isMainInventory() { return mInventory->isMainInventory(); } diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index ea33fda3..9b2df34d 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -51,22 +51,17 @@ ItemPopup::ItemPopup(): mItemName->setFont(boldFont); mItemName->setPosition(getPadding(), getPadding()); - const int fontHeight = getFont()->getHeight(); - // Item Description mItemDesc = new TextBox; mItemDesc->setEditable(false); - mItemDesc->setPosition(getPadding(), fontHeight); // Item Effect mItemEffect = new TextBox; mItemEffect->setEditable(false); - mItemEffect->setPosition(getPadding(), (fontHeight << 1) + (getPadding() << 1)); // Item Weight mItemWeight = new TextBox; mItemWeight->setEditable(false); - mItemWeight->setPosition(getPadding(), fontHeight * 3 + (getPadding() << 2)); mIcon = new Icon(0); @@ -158,28 +153,34 @@ void ItemPopup::setItem(const ItemInfo &item, bool showImage) const int numRowsDesc = mItemDesc->getNumberOfRows(); const int numRowsEffect = mItemEffect->getNumberOfRows(); const int numRowsWeight = mItemWeight->getNumberOfRows(); - const int height = getFont()->getHeight(); + const int fontHeight = getFont()->getHeight(); + + int nameHeight; + if (mIcon->getHeight() > 2 * fontHeight) + nameHeight = mIcon->getHeight(); + else + nameHeight = 2 * fontHeight; if (item.getEffect().empty()) { - setContentSize(minWidth, (numRowsDesc + numRowsWeight + getPadding()) * - height); + setContentSize(minWidth, nameHeight + + (numRowsDesc + numRowsWeight + 1) * fontHeight); - mItemWeight->setPosition(getPadding(), (numRowsDesc + getPadding()) * - height); + mItemWeight->setPosition(getPadding(), + nameHeight + (numRowsDesc + 1) * fontHeight); } else { - setContentSize(minWidth, (numRowsDesc + numRowsEffect + numRowsWeight + - getPadding()) * height); + setContentSize(minWidth, nameHeight + (numRowsDesc + numRowsEffect + + numRowsWeight + 1) * fontHeight); - mItemWeight->setPosition(getPadding(), (numRowsDesc + numRowsEffect + - getPadding()) * height); + mItemWeight->setPosition(getPadding(), nameHeight + (numRowsDesc + + numRowsEffect + 1) * fontHeight); } - mItemDesc->setPosition(getPadding(), 2 * height); - mItemEffect->setPosition(getPadding(), (numRowsDesc + getPadding()) * height); - + mItemDesc->setPosition(getPadding(), nameHeight); + mItemEffect->setPosition(getPadding(), nameHeight + + (numRowsDesc + 1) * fontHeight); } gcn::Color ItemPopup::getColor(ItemType type) diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index dd447f95..993814ea 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -105,7 +105,8 @@ void Minimap::setMap(Map *map) if (minimapName.empty() && resman->exists(tempname)) minimapName = tempname; - mMapImage = resman->getImage(minimapName); + if (!minimapName.empty()) + mMapImage = resman->getImage(minimapName); } if (mMapImage) diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 7a702cc2..e2257388 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -128,7 +128,8 @@ void PopupMenu::showPopup(int x, int y, Being *being) mBrowserBox->addRow(strprintf("@@follow|%s@@", strprintf(_("Follow %s"), name.c_str()).c_str())); - mBrowserBox->addRow(strprintf("@@guild|%s@@", + if (player_node->getNumberOfGuilds()) + mBrowserBox->addRow(strprintf("@@guild|%s@@", strprintf(_("Invite %s to join your guild"), name.c_str()).c_str())); if (player_node->isInParty()) diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 83f01d7f..f33111d7 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -252,6 +252,8 @@ void SellDialog::setMoney(int amount) { mPlayerMoney = amount; mShopItemList->setPlayersMoney(amount); + + updateButtonsAndLabels(); } void SellDialog::updateButtonsAndLabels() diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 115b582c..1657c8d3 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -679,7 +679,7 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status, } else if (status < 0) { - logger->log("Error retreiving server list: %s\n", + logger->log("Error retreiving server list: %s", sd->mDownload->getError()); sd->mDownloadStatus = DOWNLOADING_ERROR; } diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index bbfae738..ae921d2f 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -222,11 +222,11 @@ Setup_Video::Setup_Video(): mParticleEffectsCheckBox(new CheckBox(_("Particle effects"), mParticleEffectsEnabled)), mNameCheckBox(new CheckBox(_("Show own name"), mNameEnabled)), - mNPCLogCheckBox(new CheckBox(_("Log NPC interations"), mNPCLogEnabled)), + mNPCLogCheckBox(new CheckBox(_("Log NPC interactions"), mNPCLogEnabled)), mPickupNotifyLabel(new Label(_("Show pickup notification"))), - // TRANSLATORS: Refers to "Show own name" + // TRANSLATORS: Refers to "Show pickup notification" mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)), - // TRANSLATORS: Refers to "Show own name" + // TRANSLATORS: Refers to "Show pickup notification" mPickupParticleCheckBox(new CheckBox(_("as particle"), mPickupParticleEnabled)), mSpeechSlider(new Slider(0, 3)), @@ -438,8 +438,18 @@ void Setup_Video::apply() config.setValue("opengl", mOpenGLCheckBox->isSelected()); // OpenGL can currently only be changed by restarting, notify user. - new OkDialog(_("Changing to OpenGL"), - _("Applying change to OpenGL requires restart.")); + if (mOpenGLCheckBox->isSelected()) + { + new OkDialog(_("Changing to OpenGL"), + _("Applying change to OpenGL requires restart. " + "In case OpenGL messes up your game graphics, restart " + "the game with the command line option \"--no-opengl\".")); + } + else + { + new OkDialog(_("Deactivating OpenGL"), + _("Applying change to OpenGL requires restart.")); + } } mFps = mFpsCheckBox->isSelected() ? (int) mFpsSlider->getValue() : 0; diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 168553f6..be46132e 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -74,9 +74,14 @@ struct SkillInfo float progress; gcn::Color color; + SkillInfo() : + icon(NULL) + {} + ~SkillInfo() { - icon->decRef(); + if (icon) + icon->decRef(); } void setIcon(const std::string &iconPath) @@ -86,7 +91,8 @@ struct SkillInfo { icon = res->getImage(iconPath); } - else + + if (!icon) { icon = Theme::getImageFromTheme( paths.getStringValue("unknownItemFile")); diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 88cd5732..588ce5e7 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -120,11 +120,13 @@ public: if (event.getId() == "do invite") { std::string name = mInviteDialog->getText(); - Net::getGuildHandler()->invite(mGuild->getId(), name); - SERVER_NOTICE(strprintf(_("Invited user %s to guild %s."), - name.c_str(), - mGuild->getName().c_str())) + if (!name.empty()) + { + SERVER_NOTICE(strprintf(_("Invited user %s to guild %s."), + name.c_str(), + mGuild->getName().c_str())) + } mInviteDialog = NULL; } else if (event.getId() == "~do invite") @@ -151,7 +153,7 @@ protected: mInviteDialog = new TextDialog(_("Member Invite to Guild"), strprintf(_("Who would you like to invite to guild %s?"), mGuild->getName().c_str()), - socialWindow); + socialWindow, true); mInviteDialog->setActionEventId("do invite"); mInviteDialog->addActionListener(this); } @@ -184,7 +186,7 @@ public: mScroll = new ScrollArea(mList); mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_AUTO); - mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_ALWAYS); + mScroll->setVerticalScrollPolicy(gcn::ScrollArea::SHOW_AUTO); } ~PartyTab() @@ -200,10 +202,10 @@ public: if (event.getId() == "do invite") { std::string name = mInviteDialog->getText(); - Net::getPartyHandler()->invite(name); - SERVER_NOTICE(strprintf(_("Invited user %s to party."), - name.c_str())) + if (!name.empty()) + SERVER_NOTICE(strprintf(_("Invited user %s to party."), + name.c_str())) mInviteDialog = NULL; } else if (event.getId() == "~do invite") @@ -230,7 +232,7 @@ protected: mInviteDialog = new TextDialog(_("Member Invite to Party"), strprintf(_("Who would you like to invite to party %s?"), mParty->getName().c_str()), - socialWindow); + socialWindow, true); mInviteDialog->setActionEventId("do invite"); mInviteDialog->addActionListener(this); } @@ -319,7 +321,7 @@ SocialWindow::SocialWindow() : setCloseButton(true); setMinWidth(120); setMinHeight(55); - setDefaultSize(590, 200, 150, 60); + setDefaultSize(590, 200, 150, 124); setupWindow->registerWindowForReset(this); loadWindowState(); @@ -492,7 +494,8 @@ void SocialWindow::action(const gcn::ActionEvent &event) if (name.size() > 16) { - // TODO : State too many characters in input. + SERVER_NOTICE(_("Creating guild failed, please choose a " + "shorter name.")); return; } @@ -512,7 +515,8 @@ void SocialWindow::action(const gcn::ActionEvent &event) if (name.size() > 16) { - // TODO : State too many characters in input. + SERVER_NOTICE(_("Creating party failed, please choose a " + "shorter name.")); return; } diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index 493f5ee6..6535edf7 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -238,10 +238,7 @@ void StatusWindow::event(const std::string &channel, const Mana::Event &event) _("Character points: %d"), event.getInt("newValue"))); mCharacterPointsLabel->adjustSize(); - // Update all attributes - for (Attrs::iterator it = mAttrs.begin(); - it != mAttrs.end(); it++) - it->second->update(); + updateAttrs(); break; case CORR_POINTS: @@ -249,10 +246,7 @@ void StatusWindow::event(const std::string &channel, const Mana::Event &event) _("Correction points: %d"), event.getInt("newValue"))); mCorrectionPointsLabel->adjustSize(); - // Update all attributes - for (Attrs::iterator it = mAttrs.begin(); - it != mAttrs.end(); it++) - it->second->update(); + updateAttrs(); break; case LEVEL: @@ -286,6 +280,14 @@ void StatusWindow::event(const std::string &channel, const Mana::Event &event) } } +void StatusWindow::updateAttrs() +{ + for (Attrs::iterator it = mAttrs.begin(); it != mAttrs.end(); it++) + { + it->second->update(); + } +} + void StatusWindow::setPointsNeeded(int id, int needed) { Attrs::iterator it = mAttrs.find(id); diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h index 5be09b6a..fd8c6319 100644 --- a/src/gui/statuswindow.h +++ b/src/gui/statuswindow.h @@ -51,6 +51,8 @@ class StatusWindow : public Window, public Mana::Listener void event(const std::string &channel, const Mana::Event &event); + void updateAttrs(); + void setPointsNeeded(int id, int needed); void addAttribute(int id, const std::string &name, bool modifiable, diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp index 3e3aafe2..f88a6afa 100644 --- a/src/gui/textdialog.cpp +++ b/src/gui/textdialog.cpp @@ -21,6 +21,8 @@ #include "gui/textdialog.h" +#include "actorspritemanager.h" + #include "gui/widgets/button.h" #include "gui/widgets/label.h" #include "gui/widgets/textfield.h" @@ -30,14 +32,20 @@ int TextDialog::instances = 0; TextDialog::TextDialog(const std::string &title, const std::string &msg, - Window *parent): - Window(title, true, parent), - mTextField(new TextField) + Window *parent, bool autoCompleteEnabled): + Window(title, true, parent) { gcn::Label *textLabel = new Label(msg); mOkButton = new Button(_("OK"), "OK", this); gcn::Button *cancelButton = new Button(_("Cancel"), "CANCEL", this); + // In TextField the escape key will either cause autoComplete or lose focus + mTextField = new TextField("", ! autoCompleteEnabled); + if (autoCompleteEnabled) + mTextField->setAutoComplete(actorSpriteManager->getPlayerNameLister()); + + mTextField->addActionListener(this); + place(0, 0, textLabel, 4); place(0, 1, mTextField, 4); place(2, 2, mOkButton); diff --git a/src/gui/textdialog.h b/src/gui/textdialog.h index d4c611cc..aa8fcf8f 100644 --- a/src/gui/textdialog.h +++ b/src/gui/textdialog.h @@ -42,7 +42,7 @@ public: * @see Window::Window */ TextDialog(const std::string &title, const std::string &msg, - Window *parent = NULL); + Window *parent = NULL, bool autoCompleteEnabled = false); ~TextDialog(); diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp index 05f34760..e9162ab6 100644 --- a/src/gui/widgets/chattab.cpp +++ b/src/gui/widgets/chattab.cpp @@ -21,6 +21,7 @@ #include "gui/widgets/chattab.h" +#include "actorspritemanager.h" #include "chatlog.h" #include "commandhandler.h" #include "configuration.h" @@ -279,6 +280,11 @@ void ChatTab::handleCommand(const std::string &msg) commandHandler->handleCommand(msg, this); } +void ChatTab::getAutoCompleteList(std::vector<std::string> &names) const +{ + actorSpriteManager->getPlayerNPCNameLister()->getAutoCompleteList(names); +} + void ChatTab::saveToLogFile(std::string &msg) { if (chatLogger) diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h index f5682668..1e187f23 100644 --- a/src/gui/widgets/chattab.h +++ b/src/gui/widgets/chattab.h @@ -25,6 +25,7 @@ #include "gui/chat.h" #include "gui/widgets/tab.h" +#include "gui/widgets/textfield.h" class BrowserBox; class Recorder; @@ -33,7 +34,7 @@ class ScrollArea; /** * A tab for the chat window. This is special to ease chat handling. */ -class ChatTab : public Tab +class ChatTab : public Tab, public AutoCompleteLister { public: /** @@ -100,6 +101,9 @@ class ChatTab : public Tab const std::string &args) { return false; } + + void getAutoCompleteList(std::vector<std::string> &names) const; + virtual void saveToLogFile(std::string &msg); protected: @@ -112,8 +116,6 @@ class ChatTab : public Tab virtual void handleCommand(const std::string &msg); - virtual void getAutoCompleteList(std::vector<std::string>&) const {} - void addRow(std::string &line); ScrollArea *mScrollArea; diff --git a/src/gui/widgets/shoplistbox.cpp b/src/gui/widgets/shoplistbox.cpp index c0a79500..ae7d4d9b 100644 --- a/src/gui/widgets/shoplistbox.cpp +++ b/src/gui/widgets/shoplistbox.cpp @@ -61,6 +61,11 @@ ShopListBox::ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel): mItemPopup = new ItemPopup; } +ShopListBox::~ShopListBox() +{ + delete mItemPopup; +} + void ShopListBox::setPlayersMoney(int money) { mPlayerMoney = money; @@ -167,3 +172,9 @@ void ShopListBox::mouseMoved(gcn::MouseEvent &event) } } } + +void ShopListBox::mouseExited(gcn::MouseEvent &event) +{ + mItemPopup->setVisible(false); +} + diff --git a/src/gui/widgets/shoplistbox.h b/src/gui/widgets/shoplistbox.h index 062ad93a..087bdd53 100644 --- a/src/gui/widgets/shoplistbox.h +++ b/src/gui/widgets/shoplistbox.h @@ -48,6 +48,11 @@ class ShopListBox : public ListBox ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel); /** + * Destructor + */ + ~ShopListBox(); + + /** * Draws the list box. */ void draw(gcn::Graphics *graphics); @@ -73,8 +78,16 @@ class ShopListBox : public ListBox */ void setPriceCheck(bool check); + /** + ** Show ItemTooltip + */ void mouseMoved(gcn::MouseEvent &event); + /** + ** Hide ItemTooltip + */ + void mouseExited(gcn::MouseEvent &event); + private: int mPlayerMoney; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index a774ab22..101c9546 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -103,16 +103,12 @@ void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) void TabbedArea::removeTab(Tab *tab) { - int tabIndexToBeSelected = -1; - if (tab == mSelectedTab) { - int index = getSelectedTabIndex(); - - if (index == (int)mTabs.size() - 1 && mTabs.size() == 1) - tabIndexToBeSelected = -1; + if (getNumberOfTabs() > 1) + setSelectedTab(std::max(0, getSelectedTabIndex() - 1)); else - tabIndexToBeSelected = index - 1; + mSelectedTab = 0; } TabContainer::iterator iter; @@ -137,16 +133,6 @@ void TabbedArea::removeTab(Tab *tab) } } - if (tabIndexToBeSelected == -1) - { - mSelectedTab = NULL; - mWidgetContainer->clear(); - } - else - { - setSelectedTab(tabIndexToBeSelected); - } - adjustSize(); adjustTabPositions(); } diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 9696cd59..d06df376 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -32,6 +32,7 @@ #include "utils/copynpaste.h" #include "utils/dtor.h" +#include "utils/stringutils.h" #include <guichan/font.hpp> @@ -43,7 +44,9 @@ ImageRect TextField::skin; TextField::TextField(const std::string &text, bool loseFocusOnTab): gcn::TextField(text), - mNumeric(false) + mNumeric(false), + mAutoComplete(NULL), + mHistory(NULL) { setFrameSize(2); @@ -209,6 +212,42 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) } } break; + case Key::UP: + { + if (mHistory && !mHistory->atBegining() && !mHistory->empty()) + { + // Move backward through the history + mHistory->current--; + setText(*mHistory->current); + setCaretPosition(getText().length()); + } + } break; + + case Key::DOWN: + { + if (mHistory && !mHistory->atEnd()) + { + // Move forward through the history + TextHistoryIterator prevHist = mHistory->current++; + + if (!mHistory->atEnd()) + { + setText(*mHistory->current); + setCaretPosition(getText().length()); + } + else + { + setText(""); + mHistory->current = prevHist; + } + } + else if (getText() != "") + { + // Always clear (easy access to useful function) + setText(""); + } + } break; + case Key::DELETE: { unsigned sz = mText.size(); @@ -234,6 +273,18 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) } break; case Key::ENTER: + if (mHistory) + { + // If the input is different from previous, put it in the history + if (!getText().empty() && (mHistory->empty() || + !mHistory->matchesLastEntry(getText()))) + { + mHistory->addEntry(getText()); + } + + mHistory->toEnd(); + } + distributeActionEvent(); break; @@ -246,6 +297,7 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) break; case Key::TAB: + autoComplete(); if (mLoseFocusOnTab) return; break; @@ -259,6 +311,73 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) fixScroll(); } +void TextField::autoComplete() +{ + if (mAutoComplete && mText.size() > 0) + { + const int caretPos = getCaretPosition(); + int startName = 0; + const std::string inputText = getText(); + std::string name = inputText.substr(0, caretPos); + std::string newName(""); + + for (int f = caretPos - 1; f > -1; f--) + { + if (isWordSeparator(inputText[f])) + { + startName = f + 1; + name = inputText.substr(f + 1, caretPos - startName); + break; + } + } + + if (caretPos == startName) + return; + + + std::vector<std::string> nameList; + mAutoComplete->getAutoCompleteList(nameList); + newName = autocomplete(nameList, name); + + if (newName == "" && mHistory) + { + + TextHistoryIterator i = mHistory->history.begin(); + std::vector<std::string> nameList; + + while (i != mHistory->history.end()) + { + std::string line = *i; + unsigned int f = 0; + while (f < line.length() && !isWordSeparator(line.at(f))) + { + f++; + } + line = line.substr(0, f); + if (line != "") + { + nameList.push_back(line); + } + ++i; + } + + newName = autocomplete(nameList, name); + } + + if (newName != "") + { + if(inputText[0] == '@' || inputText[0] == '/') + newName = "\"" + newName + "\""; + + setText(inputText.substr(0, startName) + newName + + inputText.substr(caretPos, inputText.length() + - caretPos)); + + setCaretPosition(caretPos - name.length() + newName.length()); + } + } +} + void TextField::handlePaste() { std::string text = getText(); diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h index 58e37f5c..1963f9fa 100644 --- a/src/gui/widgets/textfield.h +++ b/src/gui/widgets/textfield.h @@ -24,9 +24,48 @@ #include <guichan/widgets/textfield.hpp> +#include <vector> + class ImageRect; class TextField; +typedef std::list<std::string> TextHistoryList; +typedef TextHistoryList::iterator TextHistoryIterator; + +struct TextHistory { + TextHistoryList history; /**< Command history. */ + TextHistoryIterator current; /**< History iterator. */ + + TextHistory() + { current = history.end(); } + + bool empty() const + { return history.empty(); } + + bool atBegining() const + { return current == history.begin(); } + + bool atEnd() const + { return current == history.end(); } + + void toBegining() + { current = history.begin(); } + + void toEnd() + { current = history.end(); } + + void addEntry(const std::string &text) + { history.push_back(text); } + + bool matchesLastEntry(const std::string &text) + { return history.back() == text; } +}; + +class AutoCompleteLister { +public: + virtual void getAutoCompleteList(std::vector<std::string>&) const {} +}; + /** * A text field. * @@ -90,7 +129,33 @@ class TextField : public gcn::TextField */ int getValue() const; + /** + * Sets the TextField's source of autocomplete. Passing null will + * disable autocomplete. + */ + void setAutoComplete(AutoCompleteLister *lister) + { mAutoComplete = lister; } + + /** + * Returns the TextField's source of autocomplete. + */ + AutoCompleteLister *getAutoComplete() const + { return mAutoComplete; } + + /** + * Sets the TextField's source of input history. + */ + void setHistory(TextHistory *history) + { mHistory = history; } + + /** + * Returns the TextField's source of input history. + */ + TextHistory *getHistory() const + { return mHistory; } + private: + void autoComplete(); void handlePaste(); static int instances; @@ -100,6 +165,10 @@ class TextField : public gcn::TextField int mMinimum; int mMaximum; bool mLoseFocusOnTab; + + AutoCompleteLister *mAutoComplete; + + TextHistory *mHistory; /**< Text history. */ }; #endif diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp index 76e6bc1f..542ab4a0 100644 --- a/src/gui/windowmenu.cpp +++ b/src/gui/windowmenu.cpp @@ -72,6 +72,7 @@ WindowMenu::WindowMenu(): WindowMenu::~WindowMenu() { + delete mEmotePopup; } void WindowMenu::action(const gcn::ActionEvent &event) |