1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-09 03:39:14 +00:00
OpenMW/apps/openmw/mwgui/dialogue.cpp

208 lines
6.0 KiB
C++

#include "dialogue.hpp"
#include "dialogue_history.hpp"
#include "window_manager.hpp"
#include "widgets.hpp"
#include "components/esm_store/store.hpp"
#include "../mwworld/environment.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
#include <assert.h>
#include <iostream>
#include <iterator>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
using namespace MWGui;
using namespace Widgets;
/**
*Copied from the internet.
*/
std::string lower_string(const std::string& str)
{
std::string lowerCase;
std::transform (str.begin(), str.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
return lower_string(str).find(lower_string(substr),pos);
}
DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment)
: WindowBase("openmw_dialogue_window_layout.xml", parWindowManager),
mEnvironment(environment)
{
// Centre dialog
center();
//WindowManager *wm = environment.mWindowManager;
setText("NpcName", "Name of character");
//History view
getWidget(history, "History");
history->setOverflowToTheLeft(true);
history->setMaxTextLength(1000000);
Widget* eventbox;
//An EditBox cannot receive mouse click events, so we use an
//invisible widget on top of the editbox to receive them
/// \todo scrolling the dialogue history with the mouse wheel doesn't work using this solution
getWidget(eventbox, "EventBox");
eventbox->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);
getWidget(pDispositionBar, "Disposition");
getWidget(pDispositionText,"DispositionText");
}
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
{
ISubWidgetText* t = history->getClient()->getSubWidgetText();
if(t == nullptr)
return;
const IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
size_t cursorPosition = t->getCursorPosition(lastPressed);
MyGUI::UString color = history->getColorAtPos(cursorPosition);
if(color != "#B29154")
{
UString key = history->getColorTextAt(cursorPosition);
if(color == "#686EBA") mEnvironment.mDialogueManager->keywordSelected(lower_string(key));
if(color == "#572D21") mEnvironment.mDialogueManager->questionAnswered(key);
}
}
void DialogueWindow::open()
{
topicsList->removeAllItems();
pTopicsText.clear();
history->eraseText(0,history->getTextLength());
updateOptions();
setVisible(true);
}
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
{
mEnvironment.mDialogueManager->goodbyeSelected();
}
void DialogueWindow::onSelectTopic(MyGUI::List* _sender, size_t _index)
{
if (_index == MyGUI::ITEM_NONE)
return;
std::string topic = _sender->getItemNameAt(_index);
mEnvironment.mDialogueManager->keywordSelected(lower_string(topic));
}
void DialogueWindow::startDialogue(std::string npcName)
{
setText("NpcName", npcName);
}
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
topicsList->removeAllItems();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); it++)
{
topicsList->addItem(*it);
}
}
void DialogueWindow::removeKeyword(std::string keyWord)
{
if(topicsList->findItemIndexWith(keyWord) != MyGUI::ITEM_NONE)
{
topicsList->removeItemAt(topicsList->findItemIndexWith(keyWord));
pTopicsText.erase(keyWord);
}
}
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
{
size_t pos = 0;
while((pos = find_str_ci(str,keyword, pos)) != std::string::npos)
{
if(pos==0)
{
str.insert(pos,color1);
pos += color1.length();
pos += keyword.length();
str.insert(pos,color2);
pos+= color2.length();
}
else
{
if(str.substr(pos -1,1) == " ")
{
str.insert(pos,color1);
pos += color1.length();
pos += keyword.length();
str.insert(pos,color2);
pos+= color2.length();
}
else
{
pos += keyword.length();
}
}
}
}
std::string DialogueWindow::parseText(std::string text)
{
for(unsigned int i = 0;i<topicsList->getItemCount();i++)
{
std::string keyWord = topicsList->getItemNameAt(i);
addColorInString(text,keyWord,"#686EBA","#B29154");
}
return text;
}
void DialogueWindow::addText(std::string text)
{
history->addDialogText("#B29154"+parseText(text)+"#B29154");
}
void DialogueWindow::addTitle(std::string text)
{
history->addDialogHeading(text);
}
void DialogueWindow::askQuestion(std::string question)
{
history->addDialogText("#572D21"+question+"#B29154"+" ");
}
void DialogueWindow::updateOptions()
{
//Clear the list of topics
topicsList->removeAllItems();
pTopicsText.clear();
history->eraseText(0,history->getTextLength());
pDispositionBar->setProgressRange(100);
pDispositionBar->setProgressPosition(40);
pDispositionText->eraseText(0,pDispositionText->getTextLength());
pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154");
}