From 362a539125dff292614618d5ebf61e0c71dfae9f Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Wed, 18 Aug 2010 23:32:46 +0200 Subject: Fixing overlapping icons in item popups The bug could not be reproduced by everyone. Many thanks to Jaxad0127 for testing it on an affected system. This patch resolves http://bugs.manasource.org/view.php?id=191 Signed-off-by: Jared Adams --- src/gui/itempopup.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'src/gui') diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index 0cde9395..b71ca529 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -50,22 +50,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(), 2 * fontHeight + 2 * getPadding()); // Item Weight mItemWeight = new TextBox; mItemWeight->setEditable(false); - mItemWeight->setPosition(getPadding(), 3 * fontHeight + 4 * getPadding()); mIcon = new Icon(0); @@ -147,28 +142,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) -- cgit v1.2.3-70-g09d2 From af7bbb7b4404439580666b31388dd8dbef481011 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Wed, 18 Aug 2010 15:55:40 -0600 Subject: Fix Theme loading Reviewed-by: Freeyorp --- src/gui/theme.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gui') diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index 12de1f91..f80fa272 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -326,6 +326,7 @@ bool Theme::tryThemePath(std::string themePath) if (!themePath.empty()) { themePath = defaultThemePath + themePath; + if (PHYSFS_exists(themePath.c_str())) { mThemePath = themePath; @@ -338,6 +339,9 @@ bool Theme::tryThemePath(std::string themePath) void Theme::prepareThemePath() { + // Ensure the Theme object has been created + instance(); + // Try theme from settings if (!tryThemePath(config.getValue("theme", ""))) // Try theme from branding -- cgit v1.2.3-70-g09d2 From db0f5e2a332f82c006729146727d37315de7dfda Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Thu, 19 Aug 2010 16:22:40 +0200 Subject: Fixing some bugs in NPC-shop gui * Price and total money is now shown from the beginning in sell dialog. * Item popup is set invisible when mouse has moved away from items. * Item popup gets deleted when shop closes. Signed-off-by: Jared Adams --- src/gui/sell.cpp | 2 ++ src/gui/widgets/shoplistbox.cpp | 11 +++++++++++ src/gui/widgets/shoplistbox.h | 13 +++++++++++++ 3 files changed, 26 insertions(+) (limited to 'src/gui') diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 69ff7ed2..13e0ba99 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -242,6 +242,8 @@ void SellDialog::setMoney(int amount) { mPlayerMoney = amount; mShopItemList->setPlayersMoney(amount); + + updateButtonsAndLabels(); } void SellDialog::updateButtonsAndLabels() diff --git a/src/gui/widgets/shoplistbox.cpp b/src/gui/widgets/shoplistbox.cpp index 2f5fab34..a5033570 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..9232a5a4 100644 --- a/src/gui/widgets/shoplistbox.h +++ b/src/gui/widgets/shoplistbox.h @@ -47,6 +47,11 @@ class ShopListBox : public ListBox */ ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel); + /** + * Deconstructor + */ + ~ShopListBox(); + /** * Draws the list box. */ @@ -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; -- cgit v1.2.3-70-g09d2 From df91c40fa79629adb2652ed1b5141d943113a936 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Fri, 20 Aug 2010 18:09:37 +0200 Subject: Show info popups for all players Until now popups were only shown for players who are member of a party. This resolves http://bugs.manasource.org/view.php?id=197 Signed-off-by: Jared Adams --- src/gui/beingpopup.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src/gui') diff --git a/src/gui/beingpopup.cpp b/src/gui/beingpopup.cpp index 687b20c2..2150f7e5 100644 --- a/src/gui/beingpopup.cpp +++ b/src/gui/beingpopup.cpp @@ -65,25 +65,28 @@ void BeingPopup::show(int x, int y, Player *p) return; } + mBeingName->setCaption(p->getName()); + mBeingName->adjustSize(); + + int minWidth = mBeingName->getWidth(); + const int height = getFont()->getHeight(); + if (!(p->getPartyName().empty())) { - mBeingName->setCaption(p->getName()); - mBeingName->adjustSize(); - mBeingParty->setCaption(strprintf(_("Party: %s"), p->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); } -- cgit v1.2.3-70-g09d2 From 0009672b80c666b8a7ddc0b7c36951eba1fa2c35 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Sat, 21 Aug 2010 22:56:44 +0200 Subject: Fixing segmentation fault and improving gui for party MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Segmentation fault happened if a player left a party while other party members are offline. * While creating a party the key input is not anymore reused for game play. * The vertical scrollbar is only shown when needed. * The default height was raised, because before much of the functionality was hidden. Signed-off-by: Thorbjørn Lindeijer --- src/game.cpp | 2 +- src/gui/socialwindow.cpp | 4 ++-- src/party.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gui') diff --git a/src/game.cpp b/src/game.cpp index ec5e6b13..d34dc049 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -754,7 +754,7 @@ void Game::handleInput() // Moving player around if (player_node->isAlive() && !NPC::isTalking() && - !chatWindow->isInputFocused() && !quitDialog) + !chatWindow->isInputFocused() && !quitDialog && !TextDialog::isActive()) { // Get the state of the keyboard keys keyboard.refreshActiveKeys(); diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 098ecbc5..f6e1d0aa 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -186,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() @@ -321,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(); diff --git a/src/party.cpp b/src/party.cpp index 75283916..155de2ba 100644 --- a/src/party.cpp +++ b/src/party.cpp @@ -145,7 +145,7 @@ void Party::removeFromMembers() while(itr != itr_end) { Being *b = beingManager->findBeing((*itr)->getID()); - if (b->getType() == Being::PLAYER) + if (b && b->getType() == Being::PLAYER) static_cast(b)->setParty(NULL); ++itr; } -- cgit v1.2.3-70-g09d2 From 371c36f8817780a913bc2c600c2204e61267972d Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Sun, 22 Aug 2010 20:16:15 +0200 Subject: Fixing segmentation fault when tab gets removed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit How to reproduce the bug: Leave a party, while the party tab in the chat window is not selected. Then click with the mouse on the chat window. Signed-off-by: Thorbjørn Lindeijer --- src/gui/widgets/tabbedarea.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'src/gui') 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(); } -- cgit v1.2.3-70-g09d2 From 38474d0c3c14cf595aed61ee1e4a69d48abbcf92 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Tue, 24 Aug 2010 17:24:14 +0200 Subject: Giving functionality to invite in socialwindow and allow enter key in textdialog Signed-off-by: Jared Adams --- src/gui/socialwindow.cpp | 3 --- src/gui/textdialog.cpp | 2 ++ src/net/tmwa/partyhandler.cpp | 16 +++++++++++----- 3 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/gui') diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index f6e1d0aa..7a13f96b 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -203,9 +203,6 @@ public: { std::string name = mInviteDialog->getText(); Net::getPartyHandler()->invite(name); - - localChatTab->chatLog(strprintf(_("Invited user %s to party."), - name.c_str()), BY_SERVER); mInviteDialog = NULL; } else if (event.getId() == "~do invite") diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp index 3e3aafe2..6faa1162 100644 --- a/src/gui/textdialog.cpp +++ b/src/gui/textdialog.cpp @@ -38,6 +38,8 @@ TextDialog::TextDialog(const std::string &title, const std::string &msg, mOkButton = new Button(_("OK"), "OK", this); gcn::Button *cancelButton = new Button(_("Cancel"), "CANCEL", this); + mTextField->addActionListener(this); + place(0, 0, textLabel, 4); place(0, 1, mTextField, 4); place(2, 2, mOkButton); diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp index a92a27df..76108e9c 100644 --- a/src/net/tmwa/partyhandler.cpp +++ b/src/net/tmwa/partyhandler.cpp @@ -327,18 +327,24 @@ void PartyHandler::invite(Player *player) void PartyHandler::invite(const std::string &name) { - if (partyTab) + Being *invitee = beingManager->findBeingByName(name, Being::PLAYER); + + if (invitee) { - partyTab->chatLog(_("Inviting like this isn't supported at the moment."), - BY_SERVER); + invite((Player *)invitee); + partyTab->chatLog(strprintf(_("Invited user %s to party."), + name.c_str()), BY_SERVER); + } + else if (partyTab) + { + partyTab->chatLog(strprintf(_("Inviting failed, because you can't see " + "a player called %s."), name.c_str()), BY_SERVER); } else { localChatTab->chatLog(_("You can only inivte when you are in a party!"), BY_SERVER); } - - // TODO? } void PartyHandler::inviteResponse(const std::string &inviter, bool accept) -- cgit v1.2.3-70-g09d2 From 627e1271f0ac2e7bd95a83f521ecbcf1b554ba80 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Wed, 25 Aug 2010 20:38:06 +0200 Subject: Adding autoComplete for invite Signed-off-by: Jared Adams --- src/gui/chat.h | 1 + src/gui/socialwindow.cpp | 17 ++++++++++++----- src/gui/textdialog.cpp | 10 +++++++--- src/gui/textdialog.h | 2 +- src/gui/widgets/shoplistbox.h | 2 +- src/gui/widgets/textfield.cpp | 16 +++++++++++++++- src/gui/widgets/textfield.h | 11 +++++++++++ 7 files changed, 48 insertions(+), 11 deletions(-) (limited to 'src/gui') diff --git a/src/gui/chat.h b/src/gui/chat.h index e49d02c9..b0d91556 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -177,6 +177,7 @@ class ChatWindow : public Window, protected: friend class ChatTab; friend class WhisperTab; + friend class TextField; /** Remove the given tab from the window */ void removeTab(ChatTab *tab); diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 7a13f96b..3d8afa44 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -121,12 +121,16 @@ public: if (event.getId() == "do invite") { std::string name = mInviteDialog->getText(); - Net::getGuildHandler()->invite(mGuild->getId(), name); - localChatTab->chatLog(strprintf(_("Invited user %s to guild %s."), + if (!name.empty()) + { + Net::getGuildHandler()->invite(mGuild->getId(), name); + localChatTab->chatLog(strprintf(_("Invited user %s to guild %s."), name.c_str(), mGuild->getName().c_str()), BY_SERVER); + } + mInviteDialog = NULL; } else if (event.getId() == "~do invite") @@ -153,7 +157,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); } @@ -202,7 +206,10 @@ public: if (event.getId() == "do invite") { std::string name = mInviteDialog->getText(); - Net::getPartyHandler()->invite(name); + + if (!name.empty()) + Net::getPartyHandler()->invite(name); + mInviteDialog = NULL; } else if (event.getId() == "~do invite") @@ -229,7 +236,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); } diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp index 6faa1162..28792a0b 100644 --- a/src/gui/textdialog.cpp +++ b/src/gui/textdialog.cpp @@ -30,14 +30,18 @@ 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(true); + mTextField->addActionListener(this); place(0, 0, textLabel, 4); 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/shoplistbox.h b/src/gui/widgets/shoplistbox.h index 9232a5a4..087bdd53 100644 --- a/src/gui/widgets/shoplistbox.h +++ b/src/gui/widgets/shoplistbox.h @@ -48,7 +48,7 @@ class ShopListBox : public ListBox ShopListBox(gcn::ListModel *listModel, ShopItems *shopListModel); /** - * Deconstructor + * Destructor */ ~ShopListBox(); diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 4453f522..60a1f57f 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -21,9 +21,11 @@ #include "gui/widgets/textfield.h" +#include "beingmanager.h" #include "configuration.h" #include "graphics.h" +#include "gui/chat.h" #include "gui/palette.h" #include "gui/sdlinput.h" #include "gui/theme.h" @@ -43,7 +45,8 @@ ImageRect TextField::skin; TextField::TextField(const std::string &text, bool loseFocusOnTab): gcn::TextField(text), - mNumeric(false) + mNumeric(false), + mAutoComplete(false) { setFrameSize(2); @@ -246,6 +249,17 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) break; case Key::TAB: + if (mAutoComplete && mText.size() > 0) + { + std::vector names; + beingManager->getPlayerNames(names, false); + std::string newName = chatWindow->autoComplete(names, mText); + if (newName != "") + { + setText(newName); + setCaretPosition(mText.size()); + } + } if (mLoseFocusOnTab) return; break; diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h index 58e37f5c..1e6df9d6 100644 --- a/src/gui/widgets/textfield.h +++ b/src/gui/widgets/textfield.h @@ -90,6 +90,16 @@ class TextField : public gcn::TextField */ int getValue() const; + /** + * Set if the tabulator key causes auto complete + */ + void setAutoComplete(bool b ) {mAutoComplete = b;} + + /** + * Returns if the tabulator key causes auto complete + */ + bool getAutoComplete() {return mAutoComplete;} + private: void handlePaste(); @@ -100,6 +110,7 @@ class TextField : public gcn::TextField int mMinimum; int mMaximum; bool mLoseFocusOnTab; + bool mAutoComplete; }; #endif -- cgit v1.2.3-70-g09d2 From ef9eec73b3cc96ebecdc061e9e956a462fdcc19f Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Fri, 27 Aug 2010 19:03:18 +0200 Subject: Changing findBeingByName so that it searches case insensitive Adding error message when trying to create a party with to long name. Removing non-existing files from C::B project. Signed-off-by: Jared Adams --- mana.cbp | 2 -- src/beingmanager.cpp | 2 +- src/gui/socialwindow.cpp | 6 ++++-- src/net/tmwa/partyhandler.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gui') diff --git a/mana.cbp b/mana.cbp index 459a660c..c855a9a9 100644 --- a/mana.cbp +++ b/mana.cbp @@ -137,7 +137,6 @@ - @@ -369,7 +368,6 @@ - diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index 656b297e..931e4579 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -165,7 +165,7 @@ Being *BeingManager::findBeingByName(const std::string &name, i != i_end; ++i) { Being *being = (*i); - if (being->getName() == name && + if (!compareStrI(being->getName(),name) && (type == Being::UNKNOWN || type == being->getType())) return being; } diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 3d8afa44..290fd557 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -498,7 +498,8 @@ void SocialWindow::action(const gcn::ActionEvent &event) if (name.size() > 16) { - // TODO : State too many characters in input. + localChatTab->chatLog(_("Creating guild failed, please choose a " + "shorter name."), BY_SERVER); return; } @@ -518,7 +519,8 @@ void SocialWindow::action(const gcn::ActionEvent &event) if (name.size() > 16) { - // TODO : State too many characters in input. + localChatTab->chatLog(_("Creating party failed, please choose a " + "shorter name."), BY_SERVER); return; } diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp index 76108e9c..a88a27b6 100644 --- a/src/net/tmwa/partyhandler.cpp +++ b/src/net/tmwa/partyhandler.cpp @@ -333,7 +333,7 @@ void PartyHandler::invite(const std::string &name) { invite((Player *)invitee); partyTab->chatLog(strprintf(_("Invited user %s to party."), - name.c_str()), BY_SERVER); + invitee->getName().c_str()), BY_SERVER); } else if (partyTab) { -- cgit v1.2.3-70-g09d2 From d55c1345449a34adb3192c23fe3760bd0aae645b Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Sun, 29 Aug 2010 09:01:27 -0600 Subject: Move handling of autocomplete and input history into TextField Reviewed-by: Freeyorp --- src/beingmanager.cpp | 61 +++++++++++---- src/beingmanager.h | 12 ++- src/gui/chat.cpp | 178 ++++-------------------------------------- src/gui/chat.h | 25 ++---- src/gui/textdialog.cpp | 4 +- src/gui/widgets/chattab.cpp | 6 ++ src/gui/widgets/chattab.h | 7 +- src/gui/widgets/textfield.cpp | 137 +++++++++++++++++++++++++++++--- src/gui/widgets/textfield.h | 68 ++++++++++++++-- src/utils/stringutils.cpp | 37 ++++++++- src/utils/stringutils.h | 4 + 11 files changed, 318 insertions(+), 221 deletions(-) (limited to 'src/gui') diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp index 931e4579..d7045684 100644 --- a/src/beingmanager.cpp +++ b/src/beingmanager.cpp @@ -53,8 +53,48 @@ class FindBeingFunctor Being::Type type; } beingFinder; +class PlayerNamesLister : public AutoCompleteLister +{ + void getAutoCompleteList(std::vector& names) const + { + Beings::iterator i = beingManager->mBeings.begin(); + names.clear(); + + while (i != beingManager->mBeings.end()) + { + Being *being = (*i); + if (being->getType() == Being::PLAYER && being->getName() != "") + names.push_back(being->getName()); + + ++i; + } + } +}; + +class PlayerNPCNamesLister : public AutoCompleteLister +{ + void getAutoCompleteList(std::vector& names) const + { + Beings::iterator i = beingManager->mBeings.begin(); + names.clear(); + + while (i != beingManager->mBeings.end()) + { + Being *being = (*i); + if ((being->getType() == Being::PLAYER + || being->getType() == Being::NPC) + && being->getName() != "") + names.push_back(being->getName()); + + ++i; + } + } +}; + BeingManager::BeingManager() { + mPlayerNames = new PlayerNamesLister; + mPlayerNPCNames = new PlayerNPCNamesLister; } BeingManager::~BeingManager() @@ -263,23 +303,14 @@ bool BeingManager::hasBeing(Being *being) const return false; } -void BeingManager::getPlayerNames(std::vector &names, - bool npcNames) +AutoCompleteLister *BeingManager::getPlayerNameLister() { - Beings::iterator i = mBeings.begin(); - names.clear(); + return mPlayerNames; +} - while (i != mBeings.end()) - { - Being *being = (*i); - if ((being->getType() == Being::PLAYER - || (being->getType() == Being::NPC && npcNames)) - && being->getName() != "") - { - names.push_back(being->getName()); - } - ++i; - } +AutoCompleteLister *BeingManager::getPlayerNPCNameLister() +{ + return mPlayerNPCNames; } void BeingManager::updatePlayerNames() diff --git a/src/beingmanager.h b/src/beingmanager.h index 7fd63afe..f2f8eb6d 100644 --- a/src/beingmanager.h +++ b/src/beingmanager.h @@ -24,6 +24,8 @@ #include "being.h" +#include "gui/widgets/textfield.h" + class LocalPlayer; class Map; @@ -122,12 +124,18 @@ class BeingManager */ void clear(); - void getPlayerNames(std::vector &names, - bool npcNames); + AutoCompleteLister *getPlayerNameLister(); + + AutoCompleteLister *getPlayerNPCNameLister(); void updatePlayerNames(); protected: + friend class PlayerNamesLister; + friend class PlayerNPCNamesLister; + + AutoCompleteLister *mPlayerNames; + AutoCompleteLister *mPlayerNPCNames; Beings mBeings; Map *mMap; }; diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index f87a8a3d..6d900e98 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -72,9 +72,21 @@ class ChatInput : public TextField, public gcn::FocusListener } }; +class ChatAutoComplete : public AutoCompleteLister +{ + void getAutoCompleteList(std::vector &list) const + { + ChatTab *tab = static_cast(chatWindow->mChatTabs + ->getSelectedTab()); + + return tab->getAutoCompleteList(list); + } +}; ChatWindow::ChatWindow(): Window(_("Chat")), + mHistory(new TextHistory()), + mAutoComplete(new ChatAutoComplete), mTmpVisible(false) { setWindowName("Chat"); @@ -104,9 +116,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.getValue("ReturnToggles", "0") == "1"; @@ -119,6 +130,8 @@ ChatWindow::~ChatWindow() delete mRecorder; removeAllWhispers(); delete mItemLinkHandler; + delete mHistory; + delete mAutoComplete; } void ChatWindow::resetToDefaultSize() @@ -173,14 +186,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); @@ -366,48 +371,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::addInputText(const std::string &text) { const int caretPos = mChatInput->getCaretPosition(); @@ -516,112 +479,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(mChatTabs->getSelectedTab()); - std::vector nameList; - cTab->getAutoCompleteList(nameList); - newName = autoComplete(nameList, name); - - if (newName == "") - { - beingManager->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 &names, - std::string partName) const -{ - std::vector::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 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 b0d91556..1c673556 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -23,6 +23,7 @@ #define CHAT_H #include "gui/widgets/window.h" +#include "gui/widgets/textfield.h" #include #include @@ -61,8 +62,7 @@ struct CHATLOG * \ingroup Interface */ class ChatWindow : public Window, - public gcn::ActionListener, - public gcn::KeyListener + public gcn::ActionListener { public: /** @@ -131,9 +131,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); @@ -143,11 +140,9 @@ class ChatWindow : public Window, /** Override to reset mTmpVisible */ void setVisible(bool visible); - void mousePressed(gcn::MouseEvent &event); void mouseDragged(gcn::MouseEvent &event); - /** * Scrolls the chat window * @@ -177,7 +172,7 @@ class ChatWindow : public Window, protected: friend class ChatTab; friend class WhisperTab; - friend class TextField; + friend class ChatAutoComplete; /** Remove the given tab from the window */ void removeTab(ChatTab *tab); @@ -189,13 +184,6 @@ class ChatWindow : public Window, void removeAllWhispers(); - void autoComplete(); - - std::string autoCompleteHistory(std::string partName); - - std::string autoComplete(std::vector &names, - std::string partName) const; - /** Used for showing item popup on clicking links **/ ItemLinkHandler *mItemLinkHandler; Recorder *mRecorder; @@ -203,6 +191,9 @@ class ChatWindow : public Window, /** Input box for typing chat messages. */ ChatInput *mChatInput; + TextHistory *mHistory; + AutoCompleteLister *mAutoComplete; + private: bool mTmpVisible; @@ -213,10 +204,6 @@ class ChatWindow : public Window, /** Manage whisper tabs */ TabMap mWhispers; - typedef std::list History; - typedef History::iterator HistoryIterator; - History mHistory; /**< Command history. */ - HistoryIterator mCurHist; /**< History iterator. */ bool mReturnToggles; /**< Marks whether toggles the chat log or not */ }; diff --git a/src/gui/textdialog.cpp b/src/gui/textdialog.cpp index 28792a0b..d9728357 100644 --- a/src/gui/textdialog.cpp +++ b/src/gui/textdialog.cpp @@ -21,6 +21,8 @@ #include "gui/textdialog.h" +#include "beingmanager.h" + #include "gui/widgets/button.h" #include "gui/widgets/label.h" #include "gui/widgets/textfield.h" @@ -40,7 +42,7 @@ TextDialog::TextDialog(const std::string &title, const std::string &msg, // In TextField the escape key will either cause autoComplete or lose focus mTextField = new TextField("", ! autoCompleteEnabled); if (autoCompleteEnabled) - mTextField->setAutoComplete(true); + mTextField->setAutoComplete(beingManager->getPlayerNameLister()); mTextField->addActionListener(this); diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp index 39ea6887..8bf57508 100644 --- a/src/gui/widgets/chattab.cpp +++ b/src/gui/widgets/chattab.cpp @@ -21,6 +21,7 @@ #include "gui/widgets/chattab.h" +#include "beingmanager.h" #include "commandhandler.h" #include "configuration.h" #include "localplayer.h" @@ -275,6 +276,11 @@ void ChatTab::handleCommand(const std::string &msg) commandHandler->handleCommand(msg, this); } +void ChatTab::getAutoCompleteList(std::vector &names) const +{ + beingManager->getPlayerNPCNameLister()->getAutoCompleteList(names); +} + void ChatTab::addRow(std::string &line) { std::string::size_type idx = 0; diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h index 7fd3931e..c2dfa1c1 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; @@ -45,7 +46,7 @@ enum /** * A tab for the chat window. This is special to ease chat handling. */ -class ChatTab : public Tab +class ChatTab : public Tab, public AutoCompleteLister { public: /** @@ -111,6 +112,8 @@ class ChatTab : public Tab const std::string &args) { return false; } + void getAutoCompleteList(std::vector &names) const; + protected: friend class ChatWindow; friend class WhisperWindow; @@ -121,8 +124,6 @@ class ChatTab : public Tab virtual void handleCommand(const std::string &msg); - virtual void getAutoCompleteList(std::vector&) const {} - void addRow(std::string &line); ScrollArea *mScrollArea; diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 60a1f57f..3e02be98 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -25,7 +25,6 @@ #include "configuration.h" #include "graphics.h" -#include "gui/chat.h" #include "gui/palette.h" #include "gui/sdlinput.h" #include "gui/theme.h" @@ -34,6 +33,7 @@ #include "utils/copynpaste.h" #include "utils/dtor.h" +#include "utils/stringutils.h" #include @@ -46,7 +46,8 @@ ImageRect TextField::skin; TextField::TextField(const std::string &text, bool loseFocusOnTab): gcn::TextField(text), mNumeric(false), - mAutoComplete(false) + mAutoComplete(NULL), + mHistory(NULL) { setFrameSize(2); @@ -212,6 +213,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(); @@ -237,6 +274,19 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) } break; case Key::ENTER: + if (mHistory) + { + mHistory->toEnd(); + + // If the input is different from previous, put it in the history + if (mHistory->empty() || !mHistory->matchesEntry(getText())) + { + mHistory->addEntry(getText()); + } + + mHistory->toEnd(); + } + distributeActionEvent(); break; @@ -249,17 +299,7 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) break; case Key::TAB: - if (mAutoComplete && mText.size() > 0) - { - std::vector names; - beingManager->getPlayerNames(names, false); - std::string newName = chatWindow->autoComplete(names, mText); - if (newName != "") - { - setText(newName); - setCaretPosition(mText.size()); - } - } + autoComplete(); if (mLoseFocusOnTab) return; break; @@ -273,6 +313,77 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) fixScroll(); } +void TextField::autoComplete() +{ + if (mAutoComplete && mText.size() > 0) + { + 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 - f); + break; + } + } + + if (caretPos - 1 + 1 != startName) + return; + + + std::vector nameList; + mAutoComplete->getAutoCompleteList(nameList); + newName = autocomplete(nameList, name); + + if (newName == "" && mHistory) + { + + TextHistoryIterator i = mHistory->history.begin(); + std::vector 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)); + + if (startName > 0) + setCaretPosition(caretPos - name.length() + newName.length() + + 1); + else + 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 1e6df9d6..6e50f1e9 100644 --- a/src/gui/widgets/textfield.h +++ b/src/gui/widgets/textfield.h @@ -24,9 +24,48 @@ #include +#include + class ImageRect; class TextField; +typedef std::list 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 matchesEntry(const std::string &text) + { return (*current) == text; } +}; + +class AutoCompleteLister { +public: + virtual void getAutoCompleteList(std::vector&) const {} +}; + /** * A text field. * @@ -91,16 +130,32 @@ class TextField : public gcn::TextField int getValue() const; /** - * Set if the tabulator key causes auto complete + * 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. */ - void setAutoComplete(bool b ) {mAutoComplete = b;} + AutoCompleteLister *getAutoComplete() const + { return mAutoComplete; } /** - * Returns if the tabulator key causes auto complete + * Sets the TextField's source of input history. */ - bool getAutoComplete() {return mAutoComplete;} + 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; @@ -110,7 +165,10 @@ class TextField : public gcn::TextField int mMinimum; int mMaximum; bool mLoseFocusOnTab; - bool mAutoComplete; + + AutoCompleteLister *mAutoComplete; + + TextHistory *mHistory; /**< Text history. */ }; #endif diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp index 9fe3de14..445427fe 100644 --- a/src/utils/stringutils.cpp +++ b/src/utils/stringutils.cpp @@ -174,4 +174,39 @@ const char* getSafeUtf8String(std::string text) memcpy(buf, text.c_str(), text.size()); memset(buf + text.size(), 0, UTF8_MAX_SIZE); return buf; -} \ No newline at end of file +} + +std::string autocomplete(std::vector &candidates, + std::string base) +{ + std::vector::iterator i = candidates.begin(); + toLower(base); + std::string newName(""); + + while (i != candidates.end()) + { + if (!i->empty()) + { + std::string name = *i; + toLower(name); + + std::string::size_type pos = name.find(base, 0); + if (pos == 0) + { + if (newName != "") + { + toLower(newName); + newName = findSameSubstring(name, newName); + } + else + { + newName = *i; + } + } + } + + ++i; + } + + return newName; +} diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h index ec82e240..5f1f05f0 100644 --- a/src/utils/stringutils.h +++ b/src/utils/stringutils.h @@ -24,6 +24,7 @@ #include #include +#include /** * Trims spaces off the end and the beginning of the given string. @@ -125,4 +126,7 @@ const std::string findSameSubstring(const std::string &str1, const std::string & const char* getSafeUtf8String(std::string text); +std::string autocomplete(std::vector &candidates, + std::string base); + #endif // UTILS_STRINGUTILS_H -- cgit v1.2.3-70-g09d2 From f63a221850062da5b676c7dce258405f59486530 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Mon, 30 Aug 2010 19:26:33 +0200 Subject: Fixing segmentation fault and making invite to guild in pop-up conditional How to reproduce the segmentation fault: Open the emote pop-up. Then press the escape key and switch the character. The emote pop-up is still open and clicking on it makes the game crash. Signed-off-by: Jared Adams --- src/gui/popupmenu.cpp | 3 ++- src/gui/windowmenu.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 520b4005..01870e62 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/windowmenu.cpp b/src/gui/windowmenu.cpp index 5af5a202..4b18de89 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) -- cgit v1.2.3-70-g09d2 From fe08ffb9047bed67474aa8519051a0d4dcab98c5 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Tue, 31 Aug 2010 23:15:04 +0200 Subject: Fixing auto complete and chat history Reviewed-by: Jaxad0127 --- src/gui/widgets/textfield.cpp | 18 ++++++------------ src/gui/widgets/textfield.h | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) (limited to 'src/gui') diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 3e02be98..cffda1e3 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -276,10 +276,8 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) case Key::ENTER: if (mHistory) { - mHistory->toEnd(); - // If the input is different from previous, put it in the history - if (mHistory->empty() || !mHistory->matchesEntry(getText())) + if (mHistory->empty() || !mHistory->matchesLastEntry(getText())) { mHistory->addEntry(getText()); } @@ -317,23 +315,23 @@ void TextField::autoComplete() { if (mAutoComplete && mText.size() > 0) { - int caretPos = getCaretPosition(); + 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 --) + for (int f = caretPos - 1; f > -1; f--) { if (isWordSeparator(inputText[f])) { startName = f + 1; - name = inputText.substr(f + 1, caretPos - f); + name = inputText.substr(f + 1, caretPos - startName); break; } } - if (caretPos - 1 + 1 != startName) + if (caretPos == startName) return; @@ -375,11 +373,7 @@ void TextField::autoComplete() + inputText.substr(caretPos, inputText.length() - caretPos)); - if (startName > 0) - setCaretPosition(caretPos - name.length() + newName.length() - + 1); - else - setCaretPosition(caretPos - name.length() + newName.length()); + setCaretPosition(caretPos - name.length() + newName.length()); } } } diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h index 6e50f1e9..1963f9fa 100644 --- a/src/gui/widgets/textfield.h +++ b/src/gui/widgets/textfield.h @@ -57,8 +57,8 @@ struct TextHistory { void addEntry(const std::string &text) { history.push_back(text); } - bool matchesEntry(const std::string &text) - { return (*current) == text; } + bool matchesLastEntry(const std::string &text) + { return history.back() == text; } }; class AutoCompleteLister { -- cgit v1.2.3-70-g09d2 From 76ec7d66c0bb691f3409beb2448718a0bcefcc50 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Thu, 2 Sep 2010 21:17:08 +0200 Subject: Fixing escape key in charselectdialog * In charselectdialog the requestFocus is now called later, because before it had no effect, since it was called before the characters were present. Having no char with focus has the side effect that the escape key gets ignored. * Removing the code for variable width of CharacterDisplay, because with recent changes it is executed before the characters are present, therefore it had no effect. --- src/gui/charselectdialog.cpp | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'src/gui') diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp index e22c4daf..f8c28c6a 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()); } -- cgit v1.2.3-70-g09d2 From e806e70958f68a3b0dc9c841cacabacf011ac973 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Thu, 2 Sep 2010 21:26:39 +0200 Subject: Avoiding empty lines in history --- src/gui/widgets/textfield.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gui') diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index cffda1e3..4989ae83 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -277,7 +277,8 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) if (mHistory) { // If the input is different from previous, put it in the history - if (mHistory->empty() || !mHistory->matchesLastEntry(getText())) + if (!getText().empty() && (mHistory->empty() || + !mHistory->matchesLastEntry(getText()))) { mHistory->addEntry(getText()); } -- cgit v1.2.3-70-g09d2 From 49452a005f4273b3ec91470883f308690e2269ac Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Thu, 2 Sep 2010 19:14:08 -0600 Subject: Fix crash with missing skill icon Reviewed-by: Bertram --- src/gui/skilldialog.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 53528cee..207e3ded 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -73,9 +73,14 @@ struct SkillInfo float progress; gcn::Color color; + SkillInfo() : + icon(NULL) + {} + ~SkillInfo() { - icon->decRef(); + if (icon) + icon->decRef(); } void setIcon(const std::string &iconPath) @@ -85,7 +90,8 @@ struct SkillInfo { icon = res->getImage(iconPath); } - else + + if (!icon) { icon = Theme::getImageFromTheme("unknown-item.png"); } -- cgit v1.2.3-70-g09d2 From db2f9e4c7af87074f75af14a183db41e5ccdcc21 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Wed, 8 Sep 2010 16:22:28 +0200 Subject: Adding missing update for attributes in StatusWindow Reviewed-by: Thorbjorn --- src/gui/statuswindow.cpp | 13 +++++++++---- src/gui/statuswindow.h | 2 ++ src/net/tmwa/playerhandler.cpp | 4 ++++ 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src/gui') diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index ede85133..91f832f5 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -246,10 +246,7 @@ std::string StatusWindow::update(int id) mCorrectionPointsLabel->adjustSize(); } - for (Attrs::iterator it = mAttrs.begin(); it != mAttrs.end(); it++) - { - it->second->update(); - } + updateAttrs(); } else if (id == LEVEL) { @@ -272,6 +269,14 @@ std::string StatusWindow::update(int id) return ""; } +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 a1fc4b4b..d99368b8 100644 --- a/src/gui/statuswindow.h +++ b/src/gui/statuswindow.h @@ -59,6 +59,8 @@ class StatusWindow : public Window std::string update(int id); + void updateAttrs(); + void setPointsNeeded(int id, int needed); void addAttribute(int id, const std::string &name, bool modifiable, diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index 5aab94b8..16f1ee53 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -318,6 +318,10 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) player_node->setAction(Being::DEAD); } } + + if (statusWindow) + statusWindow->updateAttrs(); + break; case SMSG_PLAYER_STAT_UPDATE_2: -- cgit v1.2.3-70-g09d2 From 173cbf107b35fb191724e5386cf3bcf0106c80ae Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Wed, 8 Sep 2010 21:56:44 +0200 Subject: Adding missing updates for buttons in InventoryWindow Reviewed-by: Thorbjorn --- src/gui/inventorywindow.cpp | 9 ++++++++- src/gui/inventorywindow.h | 7 ++++++- src/net/tmwa/inventoryhandler.cpp | 10 ++++++++++ src/net/tmwa/inventoryhandler.h | 2 ++ 4 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 591ebd2f..16ac5409 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -288,10 +288,18 @@ 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); mDropButton->setEnabled(false); + mSplitButton->setEnabled(false); return; } @@ -322,7 +330,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 f611e934..0dce0611 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -100,7 +100,12 @@ class InventoryWindow : public Window, * window has been closed. */ void close(); - + + /** + * Updates the buttons. + */ + void updateButtons(); + /** * Updates the weight bar. */ diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp index 7363c738..f5b379b9 100644 --- a/src/net/tmwa/inventoryhandler.cpp +++ b/src/net/tmwa/inventoryhandler.cpp @@ -245,6 +245,8 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) inventory->setItem(index, itemId, amount, equipType != 0); } + + inventoryWindow->updateButtons(); } break; case SMSG_PLAYER_INVENTORY_REMOVE: @@ -255,6 +257,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) item->increaseQuantity(-amount); if (item->getQuantity() == 0) inventory->removeItemAt(index); + inventoryWindow->updateButtons(); } break; @@ -266,7 +269,11 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) msg.readInt8(); // type if (Item *item = inventory->getItem(index)) + { item->setQuantity(amount); + inventoryWindow->updateButtons(); + } + break; case SMSG_ITEM_USE_RESPONSE: @@ -280,7 +287,10 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) else { if (Item *item = inventory->getItem(index)) + { item->setQuantity(amount); + inventoryWindow->updateButtons(); + } } break; diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h index 82738afe..0c4ad092 100644 --- a/src/net/tmwa/inventoryhandler.h +++ b/src/net/tmwa/inventoryhandler.h @@ -87,6 +87,8 @@ class EquipBackend : public Equipment::Backend { { item->setEquipped(true); } + + inventoryWindow->updateButtons(); } private: -- cgit v1.2.3-70-g09d2 From 81dd53a536f3f76636b058250750a661911a94ea Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Sat, 11 Sep 2010 20:25:24 +0200 Subject: Fixing misspelling in Setup_Video and removing empty lines from log Reviewed-by: Jaxad0127 --- src/client.cpp | 2 +- src/gui/serverdialog.cpp | 2 +- src/gui/setup_video.cpp | 6 +++--- src/net/tmwa/guildhandler.cpp | 2 +- src/net/tmwa/network.cpp | 2 +- src/net/tmwa/partyhandler.cpp | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/gui') diff --git a/src/client.cpp b/src/client.cpp index 5488d8ad..482bb9dc 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -961,7 +961,7 @@ int Client::exec() case STATE_ERROR: logger->log("State: ERROR"); - logger->log("Error: %s\n", errorMessage.c_str()); + logger->log("Error: %s", errorMessage.c_str()); mCurrentDialog = new OkDialog(_("Error"), errorMessage); mCurrentDialog->addActionListener(&errorListener); mCurrentDialog = NULL; // OkDialog deletes itself diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 0762b00f..09ba7cd1 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -676,7 +676,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 81ce8107..b576f302 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -224,11 +224,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)), diff --git a/src/net/tmwa/guildhandler.cpp b/src/net/tmwa/guildhandler.cpp index 8a106841..dac57b64 100644 --- a/src/net/tmwa/guildhandler.cpp +++ b/src/net/tmwa/guildhandler.cpp @@ -118,7 +118,7 @@ void GuildHandler::handleMessage(Net::MessageIn &msg) msg.readInt8(); // Unused std::string guildName = msg.readString(24); - logger->log("Guild position info: %d %d %d %s\n", guildId, + logger->log("Guild position info: %d %d %d %s", guildId, emblem, posMode, guildName.c_str()); } break; diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp index ddfbbc5d..aff19b11 100644 --- a/src/net/tmwa/network.cpp +++ b/src/net/tmwa/network.cpp @@ -326,7 +326,7 @@ MessageIn Network::getNextMessage() len = readWord(2); #ifdef DEBUG - logger->log("Received packet 0x%x of length %d\n", msgId, len); + logger->log("Received packet 0x%x of length %d", msgId, len); #endif MessageIn msg(mInBuffer, len); diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp index a88a27b6..611fe3e6 100644 --- a/src/net/tmwa/partyhandler.cpp +++ b/src/net/tmwa/partyhandler.cpp @@ -189,7 +189,7 @@ void PartyHandler::handleMessage(Net::MessageIn &msg) partyTab->chatLog(_("Experience sharing not possible."), BY_SERVER); break; default: - logger->log("Unknown party exp option: %d\n", exp); + logger->log("Unknown party exp option: %d", exp); } switch (item) @@ -213,7 +213,7 @@ void PartyHandler::handleMessage(Net::MessageIn &msg) partyTab->chatLog(_("Item sharing not possible."), BY_SERVER); break; default: - logger->log("Unknown party item option: %d\n", exp); + logger->log("Unknown party item option: %d", exp); } break; } -- cgit v1.2.3-70-g09d2 From 60f16fea6c08f419bfd3d852ec3696bedfe09196 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Sun, 12 Sep 2010 00:07:55 +0200 Subject: Deactivating OpenGL by default on Windows For Linux OpenGL was already deactivated. For OSX it is still by default switched on. Reviewed-by: Jaxad0127 --- src/client.cpp | 2 +- src/gui/setup_video.cpp | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/gui') diff --git a/src/client.cpp b/src/client.cpp index 482bb9dc..8def205b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1090,7 +1090,7 @@ void Client::initConfiguration() { // Fill configuration with defaults config.setValue("hwaccel", false); -#if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL +#if defined __APPLE__ && defined USE_OPENGL config.setValue("opengl", true); #else config.setValue("opengl", false); diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index b576f302..b14a8654 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -440,8 +440,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; -- cgit v1.2.3-70-g09d2 From af176c1f344a78a352ecaa6f252054f5ac38ec73 Mon Sep 17 00:00:00 2001 From: Stefan Dombrowski Date: Mon, 13 Sep 2010 14:19:11 +0200 Subject: Avoid loading non-existing music and minimaps Reviewed-by: Thorbjorn --- src/game.cpp | 7 ++++++- src/gui/minimap.cpp | 3 ++- src/sound.cpp | 7 +------ 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/gui') diff --git a/src/game.cpp b/src/game.cpp index 026b0017..8e856dc0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -958,7 +958,12 @@ void Game::changeMap(const std::string &mapPath) std::string oldMusic = mCurrentMap ? mCurrentMap->getMusicFile() : ""; std::string newMusic = newMap ? newMap->getMusicFile() : ""; if (newMusic != oldMusic) - sound.playMusic(newMusic); + { + if (newMusic.empty()) + sound.stopMusic(); + else + sound.playMusic(newMusic); + } delete mCurrentMap; mCurrentMap = newMap; diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index 35844f64..8713d3f9 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -106,7 +106,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/sound.cpp b/src/sound.cpp index d3542a48..fa39e49b 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -195,12 +195,7 @@ void Sound::stopMusic() logger->log("Sound::stopMusic()"); - if (mMusic) - { - Mix_HaltMusic(); - Mix_FreeMusic(mMusic); - mMusic = NULL; - } + haltMusic(); } void Sound::fadeInMusic(const std::string &path, int ms) -- cgit v1.2.3-70-g09d2