diff options
Diffstat (limited to 'src/gui/widgets')
-rw-r--r-- | src/gui/widgets/chattab.cpp | 6 | ||||
-rw-r--r-- | src/gui/widgets/chattab.h | 8 | ||||
-rw-r--r-- | src/gui/widgets/shoplistbox.cpp | 11 | ||||
-rw-r--r-- | src/gui/widgets/shoplistbox.h | 13 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.cpp | 20 | ||||
-rw-r--r-- | src/gui/widgets/textfield.cpp | 121 | ||||
-rw-r--r-- | src/gui/widgets/textfield.h | 69 |
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 |