summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/beingpopup.cpp25
-rw-r--r--src/gui/charselectdialog.cpp20
-rw-r--r--src/gui/chat.cpp178
-rw-r--r--src/gui/chat.h21
-rw-r--r--src/gui/inventorywindow.cpp9
-rw-r--r--src/gui/inventorywindow.h5
-rw-r--r--src/gui/itempopup.cpp35
-rw-r--r--src/gui/minimap.cpp3
-rw-r--r--src/gui/popupmenu.cpp3
-rw-r--r--src/gui/sell.cpp2
-rw-r--r--src/gui/serverdialog.cpp2
-rw-r--r--src/gui/setup_video.cpp20
-rw-r--r--src/gui/skilldialog.cpp10
-rw-r--r--src/gui/socialwindow.cpp30
-rw-r--r--src/gui/statuswindow.cpp18
-rw-r--r--src/gui/statuswindow.h2
-rw-r--r--src/gui/textdialog.cpp14
-rw-r--r--src/gui/textdialog.h2
-rw-r--r--src/gui/widgets/chattab.cpp6
-rw-r--r--src/gui/widgets/chattab.h8
-rw-r--r--src/gui/widgets/shoplistbox.cpp11
-rw-r--r--src/gui/widgets/shoplistbox.h13
-rw-r--r--src/gui/widgets/tabbedarea.cpp20
-rw-r--r--src/gui/widgets/textfield.cpp121
-rw-r--r--src/gui/widgets/textfield.h69
-rw-r--r--src/gui/windowmenu.cpp1
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)