From be5562cb2cea5cec5e9464219712828df845b3b3 Mon Sep 17 00:00:00 2001 From: Jan-Peter Nilsson Date: Wed, 3 Nov 2010 21:21:08 +0100 Subject: [PATCH] Added dialouge window --- apps/openmw/CMakeLists.txt | 4 + apps/openmw/mwgui/dialogue.cpp | 127 ++++++++++++++++++ apps/openmw/mwgui/dialogue.hpp | 55 ++++++++ apps/openmw/mwgui/dialogue_history.cpp | 77 +++++++++++ apps/openmw/mwgui/dialogue_history.hpp | 20 +++ apps/openmw/mwgui/window_manager.cpp | 29 ++++ apps/openmw/mwgui/window_manager.hpp | 5 + extern/mygui_3.0.1/CMakeLists.txt | 1 + .../openmw_dialogue_window_layout.xml | 29 ++++ 9 files changed, 347 insertions(+) create mode 100644 apps/openmw/mwgui/dialogue.cpp create mode 100644 apps/openmw/mwgui/dialogue.hpp create mode 100644 apps/openmw/mwgui/dialogue_history.cpp create mode 100644 apps/openmw/mwgui/dialogue_history.hpp create mode 100644 extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2f003f6aa..78477aae4 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -43,6 +43,8 @@ set(GAMEGUI_HEADER mwgui/review.hpp mwgui/window_manager.hpp mwgui/console.hpp + mwgui/dialogue.hpp + mwgui/dialogue_history.hpp ) set(GAMEGUI mwgui/window_manager.cpp @@ -54,6 +56,8 @@ set(GAMEGUI mwgui/birth.cpp mwgui/class.cpp mwgui/review.cpp + mwgui/dialogue.cpp + mwgui/dialogue_history.cpp ) source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI}) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp new file mode 100644 index 000000000..6f2ca8e96 --- /dev/null +++ b/apps/openmw/mwgui/dialogue.cpp @@ -0,0 +1,127 @@ +#include "dialogue.hpp" +#include "dialogue_history.hpp" +#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" +#include "window_manager.hpp" +#include "widgets.hpp" +#include "components/esm_store/store.hpp" + +#include +#include +#include + +#include +#include + +using namespace MWGui; +using namespace Widgets; + +DialogueWindow::DialogueWindow(MWWorld::Environment& environment) + : Layout("openmw_dialogue_window_layout.xml") + , environment(environment) +{ + // Centre dialog + MyGUI::IntSize gameWindowSize = environment.mWindowManager->getGui()->getViewSize(); + MyGUI::IntCoord coord = mMainWidget->getCoord(); + coord.left = (gameWindowSize.width - coord.width)/2; + coord.top = (gameWindowSize.height - coord.height)/2; + mMainWidget->setCoord(coord); + + //WindowManager *wm = environment.mWindowManager; + setText("NpcName", "Name of character"); + + //History view + getWidget(history, "History"); + history->setOverflowToTheLeft(true); + history->getClient()->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked); + + //Topics list + getWidget(topicsList, "TopicsList"); + topicsList->setScrollVisible(true); + topicsList->eventListSelectAccept = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + topicsList->eventListMouseItemActivate = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + topicsList->eventListChangePosition = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + + MyGUI::ButtonPtr byeButton; + getWidget(byeButton, "ByeButton"); + byeButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); + + updateOptions(); +} + +void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) +{ + ISubWidgetText* t = history->getSubWidgetText(); + if(t == nullptr) + return; + + const IntPoint& lastPressed = InputManager::getInstance().getLastLeftPressed(); + + size_t cursorPosition = t->getCursorPosition(lastPressed); + if(history->getColorAtPos(cursorPosition) != "#FFFFFF") + { + UString key = history->getColorTextAt(cursorPosition); + std::cout << "Clicked on key: " << key << std::endl; + //eventTopicSelected(key); + } +} + +void DialogueWindow::open() +{ + updateOptions(); + setVisible(true); +} + +void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) +{ + eventBye(); +} + +void DialogueWindow::onSelectTopic(MyGUI::List* _sender, size_t _index) +{ + if (_index == MyGUI::ITEM_NONE) + return; + + //const std::string* theTopic = topicsList->getItemDataAt(_index); + //std::cout << "Selected: "<< theTopic << std::endl; + //eventTopicSelected(key); +} + + +void DialogueWindow::updateOptions() +{ + //FIXME Add this properly + history->addDialogText("Through the translucent surface of the orb, you see shifting images of distant locations..."); + for(int z = 0; z < 10; z++) + { + history->addDialogHeading("Fort Frostmoth"); + history->addDialogText("The image in the orb flickers, and you see.... The cold courtyard of #FF0000Fort Frostmoth#FFFFFF, battered bu werewolf attack, but still standing, still projecting Imperial might even to this distant and cold corner of the world."); + } + + //Clear the list of topics + topicsList->removeAllItems(); + int i = 0; + topicsList->addItem("Ald'ruhn", i++); + topicsList->addItem("Balmora", i++); + topicsList->addItem("Sadrith Mora", i++); + topicsList->addItem("Vivec", i++); + topicsList->addItem("Ald Velothi", i++); + topicsList->addItem("Caldera", i++); + topicsList->addItem("Dagon Fel ", i++); + topicsList->addItem("Gnaar Mok", i++); + topicsList->addItem("Gnisis", i++); + topicsList->addItem("Hla Oad", i++); + topicsList->addItem("Khuul", i++); + topicsList->addItem("Maar Gan", i++); + topicsList->addItem("Molag Mar", i++); + topicsList->addItem("Pelagiad", i++); + topicsList->addItem("Seyda Neen", i++); + topicsList->addItem("Suran", i++); + topicsList->addItem("Tel Aruhn", i++); + topicsList->addItem("Tel Branora", i++); + topicsList->addItem("Tel Fyr", i++); + topicsList->addItem("Tel Mora", i++); + topicsList->addItem("Tel Vos", i++); + topicsList->addItem("Vos", i++); +} + diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp new file mode 100644 index 000000000..625ca225d --- /dev/null +++ b/apps/openmw/mwgui/dialogue.hpp @@ -0,0 +1,55 @@ +#ifndef MWGUI_DIALOGE_H +#define MWGUI_DIALOGE_H + +#include + +#include + +#include + +namespace MWWorld +{ + class Environment; +} + +/* + This file contains the dialouge window + Layout is defined by resources/mygui/openmw_dialogue_window_layout.xml. + */ + +namespace MWGui +{ + class DialogeHistory; + + using namespace MyGUI; + + class DialogueWindow: public OEngine::GUI::Layout + { + public: + DialogueWindow(MWWorld::Environment& environment); + + void open(); + + // Events + typedef delegates::CDelegate0 EventHandle_Void; + + /** Event : Dialog finished, OK button clicked.\n + signature : void method()\n + */ + EventHandle_Void eventBye; + + protected: + void onSelectTopic(MyGUI::List* _sender, size_t _index); + void onByeClicked(MyGUI::Widget* _sender); + void onHistoryClicked(MyGUI::Widget* _sender); + + private: + void updateOptions(); + + MWWorld::Environment& environment; + + DialogeHistory* history; + MyGUI::ListPtr topicsList; + }; +} +#endif diff --git a/apps/openmw/mwgui/dialogue_history.cpp b/apps/openmw/mwgui/dialogue_history.cpp new file mode 100644 index 000000000..d7a274f7a --- /dev/null +++ b/apps/openmw/mwgui/dialogue_history.cpp @@ -0,0 +1,77 @@ +#include "dialogue_history.hpp" +#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" +#include "window_manager.hpp" +#include "widgets.hpp" +#include "components/esm_store/store.hpp" + +#include +#include +#include + +#include +#include + +using namespace MWGui; +using namespace Widgets; + +UString DialogeHistory::getColorAtPos(size_t _pos) +{ + UString colour = TextIterator::convertTagColour(mText->getTextColour()); + TextIterator iterator(mText->getCaption()); + while(iterator.moveNext()) + { + size_t pos = iterator.getPosition(); + iterator.getTagColour(colour); + if (pos < _pos) + continue; + else if (pos == _pos) + break; + } + return colour; +} + +UString DialogeHistory::getColorTextAt(size_t _pos) +{ + bool breakOnNext = false; + UString colour = TextIterator::convertTagColour(mText->getTextColour()); + UString colour2 = colour; + TextIterator iterator(mText->getCaption()); + TextIterator col_start = iterator; + while(iterator.moveNext()) + { + size_t pos = iterator.getPosition(); + iterator.getTagColour(colour); + if(colour != colour2) + { + if(breakOnNext) + { + return getOnlyText().substr(col_start.getPosition(), iterator.getPosition()-col_start.getPosition()); + } + col_start = iterator; + colour2 = colour; + } + if (pos < _pos) + continue; + else if (pos == _pos) + { + breakOnNext = true; + } + } + return ""; +} + +void DialogeHistory::addDialogHeading(const UString& parText) +{ + UString head("\n#00FF00"); + head.append(parText); + head.append("#FFFFFF\n"); + addText(head); +} + +void DialogeHistory::addDialogText(const UString& parText) +{ + addText(parText); + addText("\n"); +} + diff --git a/apps/openmw/mwgui/dialogue_history.hpp b/apps/openmw/mwgui/dialogue_history.hpp new file mode 100644 index 000000000..ec41678e6 --- /dev/null +++ b/apps/openmw/mwgui/dialogue_history.hpp @@ -0,0 +1,20 @@ +#ifndef MWGUI_DIALOGE_HISTORY_H +#define MWGUI_DIALOGE_HISTORY_H +#include + +namespace MWGui +{ + using namespace MyGUI; + class DialogeHistory : public MyGUI::Edit + { + MYGUI_RTTI_DERIVED( DialogeHistory ) + public: + Widget* getClient() { return mClient; } + UString getColorAtPos(size_t _pos); + UString getColorTextAt(size_t _pos); + void addDialogHeading(const UString& parText); + void addDialogText(const UString& parText); + }; +} +#endif + diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index ce13ff977..6a06865fa 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -5,6 +5,8 @@ #include "class.hpp" #include "birth.hpp" #include "review.hpp" +#include "dialogue.hpp" +#include "dialogue_history.hpp" #include "../mwmechanics/mechanicsmanager.hpp" #include "../mwinput/inputmanager.hpp" @@ -22,6 +24,7 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment : environment(environment) , nameDialog(nullptr) , raceDialog(nullptr) + , dialogueWindow(nullptr) , classChoiceDialog(nullptr) , generateClassQuestionDialog(nullptr) , generateClassResultDialog(nullptr) @@ -41,6 +44,10 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment , shown(GW_ALL) , allowed(newGame ? GW_None : GW_ALL) { + + //Register own widgets with MyGUI + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + // Get size info from the Gui object assert(gui); int w = gui->getViewSize().width; @@ -86,6 +93,7 @@ WindowManager::~WindowManager() delete nameDialog; delete raceDialog; + delete dialogueWindow; delete classChoiceDialog; delete generateClassQuestionDialog; delete generateClassResultDialog; @@ -307,6 +315,17 @@ void WindowManager::updateVisible() return; } + if (mode == GM_Dialogue) + { + if (dialogueWindow) + removeDialog(dialogueWindow); + dialogueWindow = new DialogueWindow(environment); + dialogueWindow->eventBye = MyGUI::newDelegate(this, &WindowManager::onDialogueWindowBye); + dialogueWindow->open(); + return; + } + + // Unsupported mode, switch back to game // Note: The call will eventually end up this method again but // will stop at the check if(mode == GM_Game) above. @@ -522,6 +541,16 @@ void WindowManager::onRaceDialogDone() setGuiMode(GM_Game); } +void WindowManager::onDialogueWindowBye() +{ + if (dialogueWindow) + { + //FIXME set some state and stuff? + removeDialog(dialogueWindow); + } + setGuiMode(GM_Game); +} + void WindowManager::onRaceDialogBack() { if (raceDialog) diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index f9dd4f55d..5c6c4fd50 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -54,6 +54,7 @@ namespace MWGui class TextInputDialog; class InfoBoxDialog; class RaceDialog; + class DialogueWindow; class ClassChoiceDialog; class GenerateClassResultDialog; class PickClassDialog; @@ -82,6 +83,7 @@ namespace MWGui // Character creation TextInputDialog *nameDialog; RaceDialog *raceDialog; + DialogueWindow *dialogueWindow; ClassChoiceDialog *classChoiceDialog; InfoBoxDialog *generateClassQuestionDialog; GenerateClassResultDialog *generateClassResultDialog; @@ -248,6 +250,9 @@ namespace MWGui const std::string &getGameSettingString(const std::string &id, const std::string &default_); private: + + void onDialogueWindowBye(); + // Character generation: Name dialog void onNameDialogDone(); diff --git a/extern/mygui_3.0.1/CMakeLists.txt b/extern/mygui_3.0.1/CMakeLists.txt index 9da8c59e4..d7e0bd483 100644 --- a/extern/mygui_3.0.1/CMakeLists.txt +++ b/extern/mygui_3.0.1/CMakeLists.txt @@ -53,6 +53,7 @@ configure_file("${SDIR}/openmw_chargen_select_skill_layout.xml" "${DDIR}/openmw_ configure_file("${SDIR}/openmw_chargen_class_description_layout.xml" "${DDIR}/openmw_chargen_class_description_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_chargen_birth_layout.xml" "${DDIR}/openmw_chargen_birth_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_chargen_review_layout.xml" "${DDIR}/openmw_chargen_review_layout.xml" COPYONLY) +configure_file("${SDIR}/openmw_dialogue_window_layout.xml" "${DDIR}/openmw_dialogue_window_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_inventory_window_layout.xml" "${DDIR}/openmw_inventory_window_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY) configure_file("${SDIR}/openmw_mainmenu_layout.xml" "${DDIR}/openmw_mainmenu_layout.xml" COPYONLY) diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml b/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml new file mode 100644 index 000000000..2987e82be --- /dev/null +++ b/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +