diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index b112c3f38..29bc86fe3 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwinput add_openmw_dir (mwgui layouts text_input widgets race class birth review window_manager console dialogue dialogue_history window_base stats_window messagebox journalwindow charactercreation - map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow + map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 0238446eb..3d47aa7dc 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -2,6 +2,7 @@ #include "dialogue_history.hpp" #include "window_manager.hpp" #include "widgets.hpp" +#include "list.hpp" #include "components/esm_store/store.hpp" #include "../mwbase/environment.hpp" #include "../mwdialogue/dialoguemanager.hpp" @@ -56,9 +57,8 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager) //Topics list getWidget(topicsList, "TopicsList"); - topicsList->setScrollVisible(true); //topicsList->eventListSelectAccept += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); - topicsList->eventListMouseItemActivate += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + topicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); //topicsList->eventListChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); MyGUI::ButtonPtr byeButton; @@ -98,7 +98,7 @@ void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) void DialogueWindow::open() { - topicsList->removeAllItems(); + topicsList->clear(); pTopicsText.clear(); history->eraseText(0,history->getTextLength()); updateOptions(); @@ -110,11 +110,8 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); } -void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index) +void DialogueWindow::onSelectTopic(std::string topic) { - if (_index == MyGUI::ITEM_NONE) - return; - std::string topic = _sender->getItemNameAt(_index); MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic)); } @@ -126,7 +123,7 @@ void DialogueWindow::startDialogue(std::string npcName) void DialogueWindow::setKeywords(std::list keyWords) { - topicsList->removeAllItems(); + topicsList->clear(); for(std::list::iterator it = keyWords.begin(); it != keyWords.end(); it++) { topicsList->addItem(*it); @@ -135,9 +132,9 @@ void DialogueWindow::setKeywords(std::list keyWords) void DialogueWindow::removeKeyword(std::string keyWord) { - if(topicsList->findItemIndexWith(keyWord) != MyGUI::ITEM_NONE) + if(topicsList->hasItem(keyWord)) { - topicsList->removeItemAt(topicsList->findItemIndexWith(keyWord)); + topicsList->removeItem(keyWord); pTopicsText.erase(keyWord); } } @@ -211,7 +208,7 @@ void DialogueWindow::askQuestion(std::string question) void DialogueWindow::updateOptions() { //Clear the list of topics - topicsList->removeAllItems(); + topicsList->clear(); pTopicsText.clear(); history->eraseText(0,history->getTextLength()); diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index 5921ca57a..ac29e9ec8 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -7,6 +7,11 @@ namespace MWGui { class WindowManager; + + namespace Widgets + { + class MWList; + } } /* @@ -42,7 +47,7 @@ namespace MWGui void askQuestion(std::string question); protected: - void onSelectTopic(MyGUI::ListBox* _sender, size_t _index); + void onSelectTopic(std::string topic); void onByeClicked(MyGUI::Widget* _sender); void onHistoryClicked(MyGUI::Widget* _sender); void onMouseWheel(MyGUI::Widget* _sender, int _rel); @@ -55,7 +60,7 @@ namespace MWGui std::string parseText(std::string text); DialogueHistory* history; - MyGUI::ListBox* topicsList; + Widgets::MWList* topicsList; MyGUI::ProgressPtr pDispositionBar; MyGUI::EditPtr pDispositionText; std::map pTopicsText;// this map links keyword and "real" text. diff --git a/apps/openmw/mwgui/list.cpp b/apps/openmw/mwgui/list.cpp new file mode 100644 index 000000000..733654b8c --- /dev/null +++ b/apps/openmw/mwgui/list.cpp @@ -0,0 +1,116 @@ +#include "list.hpp" + +#include + +using namespace MWGui; +using namespace MWGui::Widgets; + +MWList::MWList() : + mClient(0) + , mScrollView(0) + , mItemHeight(0) +{ +} + +void MWList::initialiseOverride() +{ + Base::initialiseOverride(); + + assignWidget(mClient, "Client"); + if (mClient == 0) + mClient = this; + + mScrollView = mClient->createWidgetReal( + "MW_ScrollView", MyGUI::FloatCoord(0.0, 0.0, 1.0, 1.0), + MyGUI::Align::Top | MyGUI::Align::Left | MyGUI::Align::Stretch, getName() + "_ScrollView"); +} + +void MWList::addItem(const std::string& name) +{ + mItems.push_back(name); + + redraw(); +} + +void MWList::redraw(bool scrollbarShown) +{ + const int _scrollBarWidth = 24; // fetch this from skin? + const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0; + const int spacing = 3; + + while (mScrollView->getChildCount()) + { + MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0)); + } + + mItemHeight = 0; + for (std::vector::const_iterator it=mItems.begin(); + it!=mItems.end(); ++it) + { + MyGUI::Button* button = mScrollView->createWidget( + "MW_ListLine", MyGUI::IntCoord(0, mItemHeight, mScrollView->getSize().width - scrollBarWidth - 2, 24), + MyGUI::Align::Left | MyGUI::Align::Top, getName() + "_item_" + (*it)); + button->setCaption((*it)); + button->getSubWidgetText()->setWordWrap(true); + button->getSubWidgetText()->setTextAlign(MyGUI::Align::Left); + button->eventMouseWheel += MyGUI::newDelegate(this, &MWList::onMouseWheel); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWList::onItemSelected); + + int height = button->getTextSize().height; + button->setSize(MyGUI::IntSize(button->getSize().width, height)); + + mItemHeight += height + spacing; + } + mScrollView->setCanvasSize(mClient->getSize().width + (_scrollBarWidth-scrollBarWidth), std::max(mItemHeight, mClient->getSize().height)); + mScrollView->setViewOffset(MyGUI::IntPoint(0,0)); + + if (!scrollbarShown && mItemHeight > mClient->getSize().height) + redraw(true); +} + +bool MWList::hasItem(const std::string& name) +{ + return (std::find(mItems.begin(), mItems.end(), name) != mItems.end()); +} + +unsigned int MWList::getItemCount() +{ + return mItems.size(); +} + +std::string MWList::getItemNameAt(unsigned int at) +{ + assert(at < mItems.size() && "List item out of bounds"); + return mItems[at]; +} + +void MWList::removeItem(const std::string& name) +{ + assert( std::find(mItems.begin(), mItems.end(), name) != mItems.end() ); + mItems.erase( std::find(mItems.begin(), mItems.end(), name) ); + + redraw(); +} + +void MWList::clear() +{ + mItems.clear(); + + redraw(); +} + +void MWList::onMouseWheel(MyGUI::Widget* _sender, int _rel) +{ + //NB view offset is negative + if (mScrollView->getViewOffset().top + _rel*0.3 > 0) + mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); + else + mScrollView->setViewOffset(MyGUI::IntPoint(0, mScrollView->getViewOffset().top + _rel*0.3)); +} + +void MWList::onItemSelected(MyGUI::Widget* _sender) +{ + std::string name = static_cast(_sender)->getCaption(); + + eventItemSelected(name); +} diff --git a/apps/openmw/mwgui/list.hpp b/apps/openmw/mwgui/list.hpp new file mode 100644 index 000000000..eedcae066 --- /dev/null +++ b/apps/openmw/mwgui/list.hpp @@ -0,0 +1,54 @@ +#ifndef MWGUI_LIST_HPP +#define MWGUI_LIST_HPP + +#include + +namespace MWGui +{ + namespace Widgets + { + /** + * \brief a very simple list widget that supports word-wrapping entries + * \note does not handle changing the width of the list at runtime + */ + class MWList : public MyGUI::Widget + { + MYGUI_RTTI_DERIVED(MWList) + public: + MWList(); + + typedef MyGUI::delegates::CMultiDelegate1 EventHandle_String; + + /** + * Event: Item selected with the mouse. + * signature: void method(std::string itemName) + */ + EventHandle_String eventItemSelected; + + void addItem(const std::string& name); + void removeItem(const std::string& name); + bool hasItem(const std::string& name); + unsigned int getItemCount(); + std::string getItemNameAt(unsigned int at); + void clear(); + + protected: + void initialiseOverride(); + + void redraw(bool scrollbarShown = false); + + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void onItemSelected(MyGUI::Widget* _sender); + + private: + MyGUI::ScrollView* mScrollView; + MyGUI::Widget* mClient; + + std::vector mItems; + + int mItemHeight; // height of all items + }; + } +} + +#endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index d082efe0c..dfac55beb 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -10,6 +10,7 @@ #include "tooltips.hpp" #include "scrollwindow.hpp" #include "bookwindow.hpp" +#include "list.hpp" #include "../mwmechanics/mechanicsmanager.hpp" #include "../mwinput/inputmanager.hpp" @@ -73,6 +74,13 @@ WindowManager::WindowManager( //Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); // Get size info from the Gui object assert(gui); @@ -107,13 +115,6 @@ WindowManager::WindowManager( playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat())); } - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - // Set up visibility updateVisible(); } diff --git a/files/mygui/openmw_dialogue_window_layout.xml b/files/mygui/openmw_dialogue_window_layout.xml index b0e437074..d45de4bd4 100644 --- a/files/mygui/openmw_dialogue_window_layout.xml +++ b/files/mygui/openmw_dialogue_window_layout.xml @@ -19,7 +19,7 @@ - + diff --git a/files/mygui/openmw_list.skin.xml b/files/mygui/openmw_list.skin.xml index 02075ad1a..89cc73123 100644 --- a/files/mygui/openmw_list.skin.xml +++ b/files/mygui/openmw_list.skin.xml @@ -212,6 +212,20 @@ + + + + + + + + + + + + + + diff --git a/files/mygui/openmw_scroll_layout.xml b/files/mygui/openmw_scroll_layout.xml index 4c9ab10e2..8641a0511 100644 --- a/files/mygui/openmw_scroll_layout.xml +++ b/files/mygui/openmw_scroll_layout.xml @@ -15,6 +15,19 @@ + + + + + + + + + + + + + diff --git a/files/mygui/openmw_scroll_skin.xml b/files/mygui/openmw_scroll_skin.xml index 20b952d58..39437d54e 100644 --- a/files/mygui/openmw_scroll_skin.xml +++ b/files/mygui/openmw_scroll_skin.xml @@ -2,4 +2,10 @@ + + + + + +