summaryrefslogtreecommitdiff
path: root/src/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets')
-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
7 files changed, 227 insertions, 21 deletions
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