mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 02:53:51 +00:00
No more using namespace
This commit is contained in:
parent
60fadaeaf0
commit
7eee86ab66
22 changed files with 8609 additions and 8557 deletions
|
@ -9,237 +9,239 @@
|
||||||
|
|
||||||
#include "widgets.hpp"
|
#include "widgets.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
|
||||||
using namespace Widgets;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
bool sortBirthSigns(const std::pair<std::string, const ESM::BirthSign*>& left, const std::pair<std::string, const ESM::BirthSign*>& right)
|
bool sortBirthSigns(const std::pair<std::string, const ESM::BirthSign*>& left, const std::pair<std::string, const ESM::BirthSign*>& right)
|
||||||
{
|
{
|
||||||
return left.second->mName.compare (right.second->mName) < 0;
|
return left.second->mName.compare (right.second->mName) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BirthDialog::BirthDialog()
|
namespace MWGui
|
||||||
: WindowModal("openmw_chargen_birth.layout")
|
|
||||||
{
|
{
|
||||||
// Centre dialog
|
|
||||||
center();
|
|
||||||
|
|
||||||
getWidget(mSpellArea, "SpellArea");
|
BirthDialog::BirthDialog()
|
||||||
|
: WindowModal("openmw_chargen_birth.layout")
|
||||||
|
{
|
||||||
|
// Centre dialog
|
||||||
|
center();
|
||||||
|
|
||||||
getWidget(mBirthImage, "BirthsignImage");
|
getWidget(mSpellArea, "SpellArea");
|
||||||
|
|
||||||
getWidget(mBirthList, "BirthsignList");
|
getWidget(mBirthImage, "BirthsignImage");
|
||||||
mBirthList->setScrollVisible(true);
|
|
||||||
mBirthList->eventListSelectAccept += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
|
||||||
mBirthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
|
||||||
mBirthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
|
||||||
|
|
||||||
MyGUI::Button* backButton;
|
getWidget(mBirthList, "BirthsignList");
|
||||||
getWidget(backButton, "BackButton");
|
mBirthList->setScrollVisible(true);
|
||||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
|
mBirthList->eventListSelectAccept += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
||||||
|
mBirthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
||||||
|
mBirthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
|
||||||
|
|
||||||
MyGUI::Button* okButton;
|
MyGUI::Button* backButton;
|
||||||
getWidget(okButton, "OKButton");
|
getWidget(backButton, "BackButton");
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
|
||||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked);
|
|
||||||
|
|
||||||
updateBirths();
|
MyGUI::Button* okButton;
|
||||||
updateSpells();
|
getWidget(okButton, "OKButton");
|
||||||
}
|
|
||||||
|
|
||||||
void BirthDialog::setNextButtonShow(bool shown)
|
|
||||||
{
|
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
|
|
||||||
if (shown)
|
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
|
|
||||||
else
|
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
||||||
}
|
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked);
|
||||||
|
|
||||||
void BirthDialog::open()
|
updateBirths();
|
||||||
{
|
updateSpells();
|
||||||
WindowModal::open();
|
}
|
||||||
updateBirths();
|
|
||||||
updateSpells();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void BirthDialog::setNextButtonShow(bool shown)
|
||||||
void BirthDialog::setBirthId(const std::string &birthId)
|
|
||||||
{
|
|
||||||
mCurrentBirthId = birthId;
|
|
||||||
mBirthList->setIndexSelected(MyGUI::ITEM_NONE);
|
|
||||||
size_t count = mBirthList->getItemCount();
|
|
||||||
for (size_t i = 0; i < count; ++i)
|
|
||||||
{
|
{
|
||||||
if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId))
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
|
||||||
|
if (shown)
|
||||||
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
|
||||||
|
else
|
||||||
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BirthDialog::open()
|
||||||
|
{
|
||||||
|
WindowModal::open();
|
||||||
|
updateBirths();
|
||||||
|
updateSpells();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BirthDialog::setBirthId(const std::string &birthId)
|
||||||
|
{
|
||||||
|
mCurrentBirthId = birthId;
|
||||||
|
mBirthList->setIndexSelected(MyGUI::ITEM_NONE);
|
||||||
|
size_t count = mBirthList->getItemCount();
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
mBirthList->setIndexSelected(i);
|
if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId))
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSpells();
|
|
||||||
}
|
|
||||||
|
|
||||||
// widget controls
|
|
||||||
|
|
||||||
void BirthDialog::onOkClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE)
|
|
||||||
return;
|
|
||||||
eventDone(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BirthDialog::onBackClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
|
|
||||||
{
|
|
||||||
if (_index == MyGUI::ITEM_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
|
|
||||||
const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
|
|
||||||
if (boost::iequals(mCurrentBirthId, *birthId))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mCurrentBirthId = *birthId;
|
|
||||||
updateSpells();
|
|
||||||
}
|
|
||||||
|
|
||||||
// update widget content
|
|
||||||
|
|
||||||
void BirthDialog::updateBirths()
|
|
||||||
{
|
|
||||||
mBirthList->removeAllItems();
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::BirthSign> &signs =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>();
|
|
||||||
|
|
||||||
// sort by name
|
|
||||||
std::vector < std::pair<std::string, const ESM::BirthSign*> > birthSigns;
|
|
||||||
|
|
||||||
MWWorld::Store<ESM::BirthSign>::iterator it = signs.begin();
|
|
||||||
for (; it != signs.end(); ++it)
|
|
||||||
{
|
|
||||||
birthSigns.push_back(std::make_pair(it->mId, &(*it)));
|
|
||||||
}
|
|
||||||
std::sort(birthSigns.begin(), birthSigns.end(), sortBirthSigns);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (std::vector<std::pair<std::string, const ESM::BirthSign*> >::const_iterator it2 = birthSigns.begin();
|
|
||||||
it2 != birthSigns.end(); ++it2, ++index)
|
|
||||||
{
|
|
||||||
mBirthList->addItem(it2->second->mName, it2->first);
|
|
||||||
if (mCurrentBirthId.empty())
|
|
||||||
{
|
|
||||||
mBirthList->setIndexSelected(index);
|
|
||||||
mCurrentBirthId = it2->first;
|
|
||||||
}
|
|
||||||
else if (boost::iequals(it2->first, mCurrentBirthId))
|
|
||||||
{
|
|
||||||
mBirthList->setIndexSelected(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BirthDialog::updateSpells()
|
|
||||||
{
|
|
||||||
for (std::vector<MyGUI::Widget*>::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it)
|
|
||||||
{
|
|
||||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
|
||||||
}
|
|
||||||
mSpellItems.clear();
|
|
||||||
|
|
||||||
if (mCurrentBirthId.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
MWSpellPtr spellWidget;
|
|
||||||
const int lineHeight = 18;
|
|
||||||
MyGUI::IntCoord coord(0, 0, mSpellArea->getWidth(), 18);
|
|
||||||
|
|
||||||
const MWWorld::ESMStore &store =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore();
|
|
||||||
|
|
||||||
const ESM::BirthSign *birth =
|
|
||||||
store.get<ESM::BirthSign>().find(mCurrentBirthId);
|
|
||||||
|
|
||||||
std::string texturePath = std::string("textures\\") + birth->mTexture;
|
|
||||||
fixTexturePath(texturePath);
|
|
||||||
mBirthImage->setImageTexture(texturePath);
|
|
||||||
|
|
||||||
std::vector<std::string> abilities, powers, spells;
|
|
||||||
|
|
||||||
std::vector<std::string>::const_iterator it = birth->mPowers.mList.begin();
|
|
||||||
std::vector<std::string>::const_iterator end = birth->mPowers.mList.end();
|
|
||||||
for (; it != end; ++it)
|
|
||||||
{
|
|
||||||
const std::string &spellId = *it;
|
|
||||||
const ESM::Spell *spell = store.get<ESM::Spell>().search(spellId);
|
|
||||||
if (!spell)
|
|
||||||
continue; // Skip spells which cannot be found
|
|
||||||
ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->mData.mType);
|
|
||||||
if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Ability && type != ESM::Spell::ST_Power)
|
|
||||||
continue; // We only want spell, ability and powers.
|
|
||||||
|
|
||||||
if (type == ESM::Spell::ST_Ability)
|
|
||||||
abilities.push_back(spellId);
|
|
||||||
else if (type == ESM::Spell::ST_Power)
|
|
||||||
powers.push_back(spellId);
|
|
||||||
else if (type == ESM::Spell::ST_Spell)
|
|
||||||
spells.push_back(spellId);
|
|
||||||
}
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
const std::vector<std::string> &spells;
|
|
||||||
const char *label;
|
|
||||||
}
|
|
||||||
categories[3] = {
|
|
||||||
{abilities, "sBirthsignmenu1"},
|
|
||||||
{powers, "sPowers"},
|
|
||||||
{spells, "sBirthsignmenu2"}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int category = 0; category < 3; ++category)
|
|
||||||
{
|
|
||||||
if (!categories[category].spells.empty())
|
|
||||||
{
|
|
||||||
MyGUI::TextBox* label = mSpellArea->createWidget<MyGUI::TextBox>("SandBrightText", coord, MyGUI::Align::Default, std::string("Label"));
|
|
||||||
label->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString(categories[category].label, ""));
|
|
||||||
mSpellItems.push_back(label);
|
|
||||||
coord.top += lineHeight;
|
|
||||||
|
|
||||||
std::vector<std::string>::const_iterator end = categories[category].spells.end();
|
|
||||||
for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != end; ++it)
|
|
||||||
{
|
{
|
||||||
const std::string &spellId = *it;
|
mBirthList->setIndexSelected(i);
|
||||||
spellWidget = mSpellArea->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i));
|
MyGUI::Button* okButton;
|
||||||
spellWidget->setSpellId(spellId);
|
getWidget(okButton, "OKButton");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mSpellItems.push_back(spellWidget);
|
updateSpells();
|
||||||
coord.top += lineHeight;
|
}
|
||||||
|
|
||||||
MyGUI::IntCoord spellCoord = coord;
|
// widget controls
|
||||||
spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template?
|
|
||||||
spellWidget->createEffectWidgets(mSpellItems, mSpellArea, spellCoord, (category == 0) ? MWEffectList::EF_Constant : 0);
|
|
||||||
coord.top = spellCoord.top;
|
|
||||||
|
|
||||||
++i;
|
void BirthDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE)
|
||||||
|
return;
|
||||||
|
eventDone(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BirthDialog::onBackClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index)
|
||||||
|
{
|
||||||
|
if (_index == MyGUI::ITEM_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
|
||||||
|
const std::string *birthId = mBirthList->getItemDataAt<std::string>(_index);
|
||||||
|
if (boost::iequals(mCurrentBirthId, *birthId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mCurrentBirthId = *birthId;
|
||||||
|
updateSpells();
|
||||||
|
}
|
||||||
|
|
||||||
|
// update widget content
|
||||||
|
|
||||||
|
void BirthDialog::updateBirths()
|
||||||
|
{
|
||||||
|
mBirthList->removeAllItems();
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::BirthSign> &signs =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>();
|
||||||
|
|
||||||
|
// sort by name
|
||||||
|
std::vector < std::pair<std::string, const ESM::BirthSign*> > birthSigns;
|
||||||
|
|
||||||
|
MWWorld::Store<ESM::BirthSign>::iterator it = signs.begin();
|
||||||
|
for (; it != signs.end(); ++it)
|
||||||
|
{
|
||||||
|
birthSigns.push_back(std::make_pair(it->mId, &(*it)));
|
||||||
|
}
|
||||||
|
std::sort(birthSigns.begin(), birthSigns.end(), sortBirthSigns);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (std::vector<std::pair<std::string, const ESM::BirthSign*> >::const_iterator it2 = birthSigns.begin();
|
||||||
|
it2 != birthSigns.end(); ++it2, ++index)
|
||||||
|
{
|
||||||
|
mBirthList->addItem(it2->second->mName, it2->first);
|
||||||
|
if (mCurrentBirthId.empty())
|
||||||
|
{
|
||||||
|
mBirthList->setIndexSelected(index);
|
||||||
|
mCurrentBirthId = it2->first;
|
||||||
|
}
|
||||||
|
else if (boost::iequals(it2->first, mCurrentBirthId))
|
||||||
|
{
|
||||||
|
mBirthList->setIndexSelected(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BirthDialog::updateSpells()
|
||||||
|
{
|
||||||
|
for (std::vector<MyGUI::Widget*>::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||||
|
}
|
||||||
|
mSpellItems.clear();
|
||||||
|
|
||||||
|
if (mCurrentBirthId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Widgets::MWSpellPtr spellWidget;
|
||||||
|
const int lineHeight = 18;
|
||||||
|
MyGUI::IntCoord coord(0, 0, mSpellArea->getWidth(), 18);
|
||||||
|
|
||||||
|
const MWWorld::ESMStore &store =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
|
const ESM::BirthSign *birth =
|
||||||
|
store.get<ESM::BirthSign>().find(mCurrentBirthId);
|
||||||
|
|
||||||
|
std::string texturePath = std::string("textures\\") + birth->mTexture;
|
||||||
|
Widgets::fixTexturePath(texturePath);
|
||||||
|
mBirthImage->setImageTexture(texturePath);
|
||||||
|
|
||||||
|
std::vector<std::string> abilities, powers, spells;
|
||||||
|
|
||||||
|
std::vector<std::string>::const_iterator it = birth->mPowers.mList.begin();
|
||||||
|
std::vector<std::string>::const_iterator end = birth->mPowers.mList.end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
const std::string &spellId = *it;
|
||||||
|
const ESM::Spell *spell = store.get<ESM::Spell>().search(spellId);
|
||||||
|
if (!spell)
|
||||||
|
continue; // Skip spells which cannot be found
|
||||||
|
ESM::Spell::SpellType type = static_cast<ESM::Spell::SpellType>(spell->mData.mType);
|
||||||
|
if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Ability && type != ESM::Spell::ST_Power)
|
||||||
|
continue; // We only want spell, ability and powers.
|
||||||
|
|
||||||
|
if (type == ESM::Spell::ST_Ability)
|
||||||
|
abilities.push_back(spellId);
|
||||||
|
else if (type == ESM::Spell::ST_Power)
|
||||||
|
powers.push_back(spellId);
|
||||||
|
else if (type == ESM::Spell::ST_Spell)
|
||||||
|
spells.push_back(spellId);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const std::vector<std::string> &spells;
|
||||||
|
const char *label;
|
||||||
|
}
|
||||||
|
categories[3] = {
|
||||||
|
{abilities, "sBirthsignmenu1"},
|
||||||
|
{powers, "sPowers"},
|
||||||
|
{spells, "sBirthsignmenu2"}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int category = 0; category < 3; ++category)
|
||||||
|
{
|
||||||
|
if (!categories[category].spells.empty())
|
||||||
|
{
|
||||||
|
MyGUI::TextBox* label = mSpellArea->createWidget<MyGUI::TextBox>("SandBrightText", coord, MyGUI::Align::Default, std::string("Label"));
|
||||||
|
label->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString(categories[category].label, ""));
|
||||||
|
mSpellItems.push_back(label);
|
||||||
|
coord.top += lineHeight;
|
||||||
|
|
||||||
|
std::vector<std::string>::const_iterator end = categories[category].spells.end();
|
||||||
|
for (std::vector<std::string>::const_iterator it = categories[category].spells.begin(); it != end; ++it)
|
||||||
|
{
|
||||||
|
const std::string &spellId = *it;
|
||||||
|
spellWidget = mSpellArea->createWidget<Widgets::MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i));
|
||||||
|
spellWidget->setSpellId(spellId);
|
||||||
|
|
||||||
|
mSpellItems.push_back(spellWidget);
|
||||||
|
coord.top += lineHeight;
|
||||||
|
|
||||||
|
MyGUI::IntCoord spellCoord = coord;
|
||||||
|
spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template?
|
||||||
|
spellWidget->createEffectWidgets(mSpellItems, mSpellArea, spellCoord, (category == 0) ? Widgets::MWEffectList::EF_Constant : 0);
|
||||||
|
coord.top = spellCoord.top;
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,148 +12,151 @@
|
||||||
|
|
||||||
#include "formatting.hpp"
|
#include "formatting.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
|
|
||||||
BookWindow::BookWindow ()
|
|
||||||
: WindowBase("openmw_book.layout")
|
|
||||||
, mTakeButtonShow(true)
|
|
||||||
, mTakeButtonAllowed(true)
|
|
||||||
{
|
{
|
||||||
getWidget(mCloseButton, "CloseButton");
|
|
||||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);
|
|
||||||
|
|
||||||
getWidget(mTakeButton, "TakeButton");
|
BookWindow::BookWindow ()
|
||||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onTakeButtonClicked);
|
: WindowBase("openmw_book.layout")
|
||||||
|
, mTakeButtonShow(true)
|
||||||
getWidget(mNextPageButton, "NextPageBTN");
|
, mTakeButtonAllowed(true)
|
||||||
mNextPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onNextPageButtonClicked);
|
|
||||||
|
|
||||||
getWidget(mPrevPageButton, "PrevPageBTN");
|
|
||||||
mPrevPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onPrevPageButtonClicked);
|
|
||||||
|
|
||||||
getWidget(mLeftPageNumber, "LeftPageNumber");
|
|
||||||
getWidget(mRightPageNumber, "RightPageNumber");
|
|
||||||
|
|
||||||
getWidget(mLeftPage, "LeftPage");
|
|
||||||
getWidget(mRightPage, "RightPage");
|
|
||||||
|
|
||||||
center();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::clearPages()
|
|
||||||
{
|
|
||||||
for (std::vector<MyGUI::Widget*>::iterator it=mPages.begin();
|
|
||||||
it!=mPages.end(); ++it)
|
|
||||||
{
|
{
|
||||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
getWidget(mCloseButton, "CloseButton");
|
||||||
}
|
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);
|
||||||
mPages.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::open (MWWorld::Ptr book)
|
getWidget(mTakeButton, "TakeButton");
|
||||||
{
|
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onTakeButtonClicked);
|
||||||
mBook = book;
|
|
||||||
|
|
||||||
clearPages();
|
getWidget(mNextPageButton, "NextPageBTN");
|
||||||
mCurrentPage = 0;
|
mNextPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onNextPageButtonClicked);
|
||||||
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
getWidget(mPrevPageButton, "PrevPageBTN");
|
||||||
|
mPrevPageButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onPrevPageButtonClicked);
|
||||||
|
|
||||||
MWWorld::LiveCellRef<ESM::Book> *ref = mBook.get<ESM::Book>();
|
getWidget(mLeftPageNumber, "LeftPageNumber");
|
||||||
|
getWidget(mRightPageNumber, "RightPageNumber");
|
||||||
|
|
||||||
BookTextParser parser;
|
getWidget(mLeftPage, "LeftPage");
|
||||||
std::vector<std::string> results = parser.split(ref->mBase->mText, mLeftPage->getSize().width, mLeftPage->getSize().height);
|
getWidget(mRightPage, "RightPage");
|
||||||
|
|
||||||
int i=0;
|
center();
|
||||||
for (std::vector<std::string>::iterator it=results.begin();
|
|
||||||
it!=results.end(); ++it)
|
|
||||||
{
|
|
||||||
MyGUI::Widget* parent;
|
|
||||||
if (i%2 == 0)
|
|
||||||
parent = mLeftPage;
|
|
||||||
else
|
|
||||||
parent = mRightPage;
|
|
||||||
|
|
||||||
MyGUI::Widget* pageWidget = parent->createWidgetReal<MyGUI::Widget>("", MyGUI::FloatCoord(0.0,0.0,1.0,1.0), MyGUI::Align::Default, "BookPage" + boost::lexical_cast<std::string>(i));
|
|
||||||
parser.parse(*it, pageWidget, mLeftPage->getSize().width);
|
|
||||||
mPages.push_back(pageWidget);
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePages();
|
void BookWindow::clearPages()
|
||||||
|
|
||||||
setTakeButtonShow(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::setTakeButtonShow(bool show)
|
|
||||||
{
|
|
||||||
mTakeButtonShow = show;
|
|
||||||
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::setInventoryAllowed(bool allowed)
|
|
||||||
{
|
|
||||||
mTakeButtonAllowed = allowed;
|
|
||||||
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender)
|
|
||||||
{
|
|
||||||
// no 3d sounds because the object could be in a container.
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender)
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
|
|
||||||
|
|
||||||
MWWorld::ActionTake take(mBook);
|
|
||||||
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
|
|
||||||
{
|
|
||||||
if ((mCurrentPage+1)*2 < mPages.size())
|
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
for (std::vector<MyGUI::Widget*>::iterator it=mPages.begin();
|
||||||
|
it!=mPages.end(); ++it)
|
||||||
++mCurrentPage;
|
|
||||||
|
|
||||||
updatePages();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
|
|
||||||
{
|
|
||||||
if (mCurrentPage > 0)
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
|
||||||
|
|
||||||
--mCurrentPage;
|
|
||||||
|
|
||||||
updatePages();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookWindow::updatePages()
|
|
||||||
{
|
|
||||||
mLeftPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 1) );
|
|
||||||
mRightPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 2) );
|
|
||||||
|
|
||||||
unsigned int i=0;
|
|
||||||
for (std::vector<MyGUI::Widget*>::iterator it = mPages.begin();
|
|
||||||
it != mPages.end(); ++it)
|
|
||||||
{
|
|
||||||
if (mCurrentPage*2 == i || mCurrentPage*2+1 == i)
|
|
||||||
(*it)->setVisible(true);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
(*it)->setVisible(false);
|
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||||
}
|
}
|
||||||
++i;
|
mPages.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BookWindow::open (MWWorld::Ptr book)
|
||||||
|
{
|
||||||
|
mBook = book;
|
||||||
|
|
||||||
|
clearPages();
|
||||||
|
mCurrentPage = 0;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
|
||||||
|
|
||||||
|
MWWorld::LiveCellRef<ESM::Book> *ref = mBook.get<ESM::Book>();
|
||||||
|
|
||||||
|
BookTextParser parser;
|
||||||
|
std::vector<std::string> results = parser.split(ref->mBase->mText, mLeftPage->getSize().width, mLeftPage->getSize().height);
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
for (std::vector<std::string>::iterator it=results.begin();
|
||||||
|
it!=results.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::Widget* parent;
|
||||||
|
if (i%2 == 0)
|
||||||
|
parent = mLeftPage;
|
||||||
|
else
|
||||||
|
parent = mRightPage;
|
||||||
|
|
||||||
|
MyGUI::Widget* pageWidget = parent->createWidgetReal<MyGUI::Widget>("", MyGUI::FloatCoord(0.0,0.0,1.0,1.0), MyGUI::Align::Default, "BookPage" + boost::lexical_cast<std::string>(i));
|
||||||
|
parser.parse(*it, pageWidget, mLeftPage->getSize().width);
|
||||||
|
mPages.push_back(pageWidget);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePages();
|
||||||
|
|
||||||
|
setTakeButtonShow(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::setTakeButtonShow(bool show)
|
||||||
|
{
|
||||||
|
mTakeButtonShow = show;
|
||||||
|
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::setInventoryAllowed(bool allowed)
|
||||||
|
{
|
||||||
|
mTakeButtonAllowed = allowed;
|
||||||
|
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
// no 3d sounds because the object could be in a container.
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
|
||||||
|
|
||||||
|
MWWorld::ActionTake take(mBook);
|
||||||
|
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
if ((mCurrentPage+1)*2 < mPages.size())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
||||||
|
|
||||||
|
++mCurrentPage;
|
||||||
|
|
||||||
|
updatePages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
|
||||||
|
{
|
||||||
|
if (mCurrentPage > 0)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
||||||
|
|
||||||
|
--mCurrentPage;
|
||||||
|
|
||||||
|
updatePages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookWindow::updatePages()
|
||||||
|
{
|
||||||
|
mLeftPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 1) );
|
||||||
|
mRightPageNumber->setCaption( boost::lexical_cast<std::string>(mCurrentPage*2 + 2) );
|
||||||
|
|
||||||
|
unsigned int i=0;
|
||||||
|
for (std::vector<MyGUI::Widget*>::iterator it = mPages.begin();
|
||||||
|
it != mPages.end(); ++it)
|
||||||
|
{
|
||||||
|
if (mCurrentPage*2 == i || mCurrentPage*2+1 == i)
|
||||||
|
(*it)->setVisible(true);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*it)->setVisible(false);
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -278,16 +278,15 @@ namespace MWGui
|
||||||
|
|
||||||
std::string Console::complete( std::string input, std::vector<std::string> &matches )
|
std::string Console::complete( std::string input, std::vector<std::string> &matches )
|
||||||
{
|
{
|
||||||
using namespace std;
|
std::string output = input;
|
||||||
string output=input;
|
std::string tmp = input;
|
||||||
string tmp=input;
|
|
||||||
bool has_front_quote = false;
|
bool has_front_quote = false;
|
||||||
|
|
||||||
/* Does the input string contain things that don't have to be completed? If yes erase them. */
|
/* Does the input string contain things that don't have to be completed? If yes erase them. */
|
||||||
/* Are there quotation marks? */
|
/* Are there quotation marks? */
|
||||||
if( tmp.find('"') != string::npos ) {
|
if( tmp.find('"') != std::string::npos ) {
|
||||||
int numquotes=0;
|
int numquotes=0;
|
||||||
for(string::iterator it=tmp.begin(); it < tmp.end(); ++it) {
|
for(std::string::iterator it=tmp.begin(); it < tmp.end(); ++it) {
|
||||||
if( *it == '"' )
|
if( *it == '"' )
|
||||||
numquotes++;
|
numquotes++;
|
||||||
}
|
}
|
||||||
|
@ -299,7 +298,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t pos;
|
size_t pos;
|
||||||
if( ( ((pos = tmp.rfind(' ')) != string::npos ) ) && ( pos > tmp.rfind('"') ) ) {
|
if( ( ((pos = tmp.rfind(' ')) != std::string::npos ) ) && ( pos > tmp.rfind('"') ) ) {
|
||||||
tmp.erase( 0, tmp.rfind(' ')+1);
|
tmp.erase( 0, tmp.rfind(' ')+1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -311,7 +310,7 @@ namespace MWGui
|
||||||
/* No quotation marks. Are there spaces?*/
|
/* No quotation marks. Are there spaces?*/
|
||||||
else {
|
else {
|
||||||
size_t rpos;
|
size_t rpos;
|
||||||
if( (rpos=tmp.rfind(' ')) != string::npos ) {
|
if( (rpos=tmp.rfind(' ')) != std::string::npos ) {
|
||||||
if( rpos == 0 ) {
|
if( rpos == 0 ) {
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
}
|
}
|
||||||
|
@ -330,7 +329,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate through the vector. */
|
/* Iterate through the vector. */
|
||||||
for(vector<string>::iterator it=mNames.begin(); it < mNames.end();++it) {
|
for(std::vector<std::string>::iterator it=mNames.begin(); it < mNames.end();++it) {
|
||||||
bool string_different=false;
|
bool string_different=false;
|
||||||
|
|
||||||
/* Is the string shorter than the input string? If yes skip it. */
|
/* Is the string shorter than the input string? If yes skip it. */
|
||||||
|
@ -338,7 +337,7 @@ namespace MWGui
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Is the beginning of the string different from the input string? If yes skip it. */
|
/* Is the beginning of the string different from the input string? If yes skip it. */
|
||||||
for( string::iterator iter=tmp.begin(), iter2=(*it).begin(); iter < tmp.end();iter++, iter2++) {
|
for( std::string::iterator iter=tmp.begin(), iter2=(*it).begin(); iter < tmp.end();iter++, iter2++) {
|
||||||
if( tolower(*iter) != tolower(*iter2) ) {
|
if( tolower(*iter) != tolower(*iter2) ) {
|
||||||
string_different=true;
|
string_different=true;
|
||||||
break;
|
break;
|
||||||
|
@ -361,24 +360,24 @@ namespace MWGui
|
||||||
/* Only one match. We're done. */
|
/* Only one match. We're done. */
|
||||||
if( matches.size() == 1 ) {
|
if( matches.size() == 1 ) {
|
||||||
/* Adding quotation marks when the input string started with a quotation mark or has spaces in it*/
|
/* Adding quotation marks when the input string started with a quotation mark or has spaces in it*/
|
||||||
if( ( matches.front().find(' ') != string::npos ) ) {
|
if( ( matches.front().find(' ') != std::string::npos ) ) {
|
||||||
if( !has_front_quote )
|
if( !has_front_quote )
|
||||||
output.append(string("\""));
|
output.append(std::string("\""));
|
||||||
return output.append(matches.front() + string("\" "));
|
return output.append(matches.front() + std::string("\" "));
|
||||||
}
|
}
|
||||||
else if( has_front_quote ) {
|
else if( has_front_quote ) {
|
||||||
return output.append(matches.front() + string("\" "));
|
return output.append(matches.front() + std::string("\" "));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return output.append(matches.front() + string(" "));
|
return output.append(matches.front() + std::string(" "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if all matching strings match further than input. If yes complete to this match. */
|
/* Check if all matching strings match further than input. If yes complete to this match. */
|
||||||
int i = tmp.length();
|
int i = tmp.length();
|
||||||
|
|
||||||
for(string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) {
|
for(std::string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) {
|
||||||
for(vector<string>::iterator it=matches.begin(); it < matches.end();++it) {
|
for(std::vector<std::string>::iterator it=matches.begin(); it < matches.end();++it) {
|
||||||
if( tolower((*it)[i]) != tolower(*iter) ) {
|
if( tolower((*it)[i]) != tolower(*iter) ) {
|
||||||
/* Append the longest match to the end of the output string*/
|
/* Append the longest match to the end of the output string*/
|
||||||
output.append(matches.front().substr( 0, i));
|
output.append(matches.front().substr( 0, i));
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,521 +19,521 @@
|
||||||
#include "inventorywindow.hpp"
|
#include "inventorywindow.hpp"
|
||||||
#include "travelwindow.hpp"
|
#include "travelwindow.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
|
||||||
using namespace Widgets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Copied from the internet.
|
*Copied from the internet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
|
||||||
std::string lower_string(const std::string& str)
|
|
||||||
{
|
{
|
||||||
std::string lowerCase = Misc::StringUtils::lowerCase (str);
|
|
||||||
|
|
||||||
return lowerCase;
|
std::string lower_string(const std::string& str)
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sortByLength (const std::string& left, const std::string& right)
|
|
||||||
{
|
|
||||||
return left.size() > right.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PersuasionDialog::PersuasionDialog()
|
|
||||||
: WindowModal("openmw_persuasion_dialog.layout")
|
|
||||||
{
|
|
||||||
getWidget(mCancelButton, "CancelButton");
|
|
||||||
getWidget(mAdmireButton, "AdmireButton");
|
|
||||||
getWidget(mIntimidateButton, "IntimidateButton");
|
|
||||||
getWidget(mTauntButton, "TauntButton");
|
|
||||||
getWidget(mBribe10Button, "Bribe10Button");
|
|
||||||
getWidget(mBribe100Button, "Bribe100Button");
|
|
||||||
getWidget(mBribe1000Button, "Bribe1000Button");
|
|
||||||
getWidget(mGoldLabel, "GoldLabel");
|
|
||||||
|
|
||||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onCancel);
|
|
||||||
mAdmireButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
|
||||||
mIntimidateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
|
||||||
mTauntButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
|
||||||
mBribe10Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
|
||||||
mBribe100Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
|
||||||
mBribe1000Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PersuasionDialog::onCancel(MyGUI::Widget *sender)
|
|
||||||
{
|
|
||||||
setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
|
|
||||||
{
|
|
||||||
MWBase::MechanicsManager::PersuasionType type;
|
|
||||||
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
|
|
||||||
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
|
|
||||||
else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
|
|
||||||
else if (sender == mBribe10Button)
|
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-10);
|
std::string lowerCase = Misc::StringUtils::lowerCase (str);
|
||||||
type = MWBase::MechanicsManager::PT_Bribe10;
|
|
||||||
}
|
return lowerCase;
|
||||||
else if (sender == mBribe100Button)
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-100);
|
|
||||||
type = MWBase::MechanicsManager::PT_Bribe100;
|
|
||||||
}
|
|
||||||
else /*if (sender == mBribe1000Button)*/
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-1000);
|
|
||||||
type = MWBase::MechanicsManager::PT_Bribe1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MWBase::Environment::get().getDialogueManager()->persuade(type);
|
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
|
||||||
|
|
||||||
setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PersuasionDialog::open()
|
|
||||||
{
|
|
||||||
WindowModal::open();
|
|
||||||
center();
|
|
||||||
|
|
||||||
int playerGold = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold();
|
|
||||||
|
|
||||||
mBribe10Button->setEnabled (playerGold >= 10);
|
|
||||||
mBribe100Button->setEnabled (playerGold >= 100);
|
|
||||||
mBribe1000Button->setEnabled (playerGold >= 1000);
|
|
||||||
|
|
||||||
mGoldLabel->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DialogueWindow::DialogueWindow()
|
|
||||||
: WindowBase("openmw_dialogue_window.layout")
|
|
||||||
, mPersuasionDialog()
|
|
||||||
, mEnabled(false)
|
|
||||||
, mServices(0)
|
|
||||||
{
|
|
||||||
// Centre dialog
|
|
||||||
center();
|
|
||||||
|
|
||||||
mPersuasionDialog.setVisible(false);
|
|
||||||
|
|
||||||
//History view
|
|
||||||
getWidget(mHistory, "History");
|
|
||||||
mHistory->setOverflowToTheLeft(true);
|
|
||||||
mHistory->setMaxTextLength(1000000);
|
|
||||||
MyGUI::Widget* eventbox;
|
|
||||||
|
|
||||||
//An EditBox cannot receive mouse click events, so we use an
|
|
||||||
//invisible widget on top of the editbox to receive them
|
|
||||||
getWidget(eventbox, "EventBox");
|
|
||||||
eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked);
|
|
||||||
eventbox->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel);
|
|
||||||
|
|
||||||
//Topics list
|
|
||||||
getWidget(mTopicsList, "TopicsList");
|
|
||||||
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
|
||||||
|
|
||||||
MyGUI::Button* byeButton;
|
|
||||||
getWidget(byeButton, "ByeButton");
|
|
||||||
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
|
|
||||||
|
|
||||||
getWidget(mDispositionBar, "Disposition");
|
|
||||||
getWidget(mDispositionText,"DispositionText");
|
|
||||||
|
|
||||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
MyGUI::ISubWidgetText* t = mHistory->getClient()->getSubWidgetText();
|
|
||||||
if(t == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const MyGUI::IntPoint& lastPressed = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
|
|
||||||
|
|
||||||
size_t cursorPosition = t->getCursorPosition(lastPressed);
|
|
||||||
MyGUI::UString color = mHistory->getColorAtPos(cursorPosition);
|
|
||||||
|
|
||||||
if (!mEnabled && color == "#572D21")
|
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
|
||||||
|
|
||||||
if (!mEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(color != "#B29154")
|
|
||||||
{
|
{
|
||||||
MyGUI::UString key = mHistory->getColorTextAt(cursorPosition);
|
return lower_string(str).find(lower_string(substr),pos);
|
||||||
|
}
|
||||||
|
|
||||||
if(color == "#686EBA")
|
bool sortByLength (const std::string& left, const std::string& right)
|
||||||
|
{
|
||||||
|
return left.size() > right.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
PersuasionDialog::PersuasionDialog()
|
||||||
|
: WindowModal("openmw_persuasion_dialog.layout")
|
||||||
|
{
|
||||||
|
getWidget(mCancelButton, "CancelButton");
|
||||||
|
getWidget(mAdmireButton, "AdmireButton");
|
||||||
|
getWidget(mIntimidateButton, "IntimidateButton");
|
||||||
|
getWidget(mTauntButton, "TauntButton");
|
||||||
|
getWidget(mBribe10Button, "Bribe10Button");
|
||||||
|
getWidget(mBribe100Button, "Bribe100Button");
|
||||||
|
getWidget(mBribe1000Button, "Bribe1000Button");
|
||||||
|
getWidget(mGoldLabel, "GoldLabel");
|
||||||
|
|
||||||
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onCancel);
|
||||||
|
mAdmireButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
||||||
|
mIntimidateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
||||||
|
mTauntButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
||||||
|
mBribe10Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
||||||
|
mBribe100Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
||||||
|
mBribe1000Button->eventMouseButtonClick += MyGUI::newDelegate(this, &PersuasionDialog::onPersuade);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PersuasionDialog::onCancel(MyGUI::Widget *sender)
|
||||||
|
{
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PersuasionDialog::onPersuade(MyGUI::Widget *sender)
|
||||||
|
{
|
||||||
|
MWBase::MechanicsManager::PersuasionType type;
|
||||||
|
if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire;
|
||||||
|
else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate;
|
||||||
|
else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt;
|
||||||
|
else if (sender == mBribe10Button)
|
||||||
{
|
{
|
||||||
std::map<size_t, HyperLink>::iterator i = mHyperLinks.upper_bound(cursorPosition);
|
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-10);
|
||||||
if( !mHyperLinks.empty() )
|
type = MWBase::MechanicsManager::PT_Bribe10;
|
||||||
{
|
}
|
||||||
--i;
|
else if (sender == mBribe100Button)
|
||||||
|
{
|
||||||
if( i->first + i->second.mLength > cursorPosition)
|
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-100);
|
||||||
{
|
type = MWBase::MechanicsManager::PT_Bribe100;
|
||||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(i->second.mTrueValue);
|
}
|
||||||
}
|
else /*if (sender == mBribe1000Button)*/
|
||||||
}
|
{
|
||||||
else
|
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-1000);
|
||||||
{
|
type = MWBase::MechanicsManager::PT_Bribe1000;
|
||||||
// the link was colored, but it is not in mHyperLinks.
|
|
||||||
// It means that those liunks are not marked with @# and found
|
|
||||||
// by topic name search
|
|
||||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(color == "#572D21")
|
MWBase::Environment::get().getDialogueManager()->persuade(type);
|
||||||
MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
|
setVisible(false);
|
||||||
{
|
|
||||||
mTopicsList->adjustSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
|
||||||
{
|
|
||||||
if (mHistory->getVScrollPosition() - _rel*0.3 < 0)
|
|
||||||
mHistory->setVScrollPosition(0);
|
|
||||||
else
|
|
||||||
mHistory->setVScrollPosition(mHistory->getVScrollPosition() - _rel*0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onSelectTopic(const std::string& topic, int id)
|
|
||||||
{
|
|
||||||
if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int separatorPos = 0;
|
|
||||||
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
|
|
||||||
{
|
|
||||||
if (mTopicsList->getItemNameAt(i) == "")
|
|
||||||
separatorPos = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id >= separatorPos)
|
void PersuasionDialog::open()
|
||||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
WindowModal::open();
|
||||||
|
center();
|
||||||
|
|
||||||
|
int playerGold = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getPlayerGold();
|
||||||
|
|
||||||
|
mBribe10Button->setEnabled (playerGold >= 10);
|
||||||
|
mBribe100Button->setEnabled (playerGold >= 100);
|
||||||
|
mBribe1000Button->setEnabled (playerGold >= 1000);
|
||||||
|
|
||||||
|
mGoldLabel->setCaptionWithReplacing("#{sGold}: " + boost::lexical_cast<std::string>(playerGold));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
DialogueWindow::DialogueWindow()
|
||||||
|
: WindowBase("openmw_dialogue_window.layout")
|
||||||
|
, mPersuasionDialog()
|
||||||
|
, mEnabled(false)
|
||||||
|
, mServices(0)
|
||||||
|
{
|
||||||
|
// Centre dialog
|
||||||
|
center();
|
||||||
|
|
||||||
|
mPersuasionDialog.setVisible(false);
|
||||||
|
|
||||||
|
//History view
|
||||||
|
getWidget(mHistory, "History");
|
||||||
|
mHistory->setOverflowToTheLeft(true);
|
||||||
|
mHistory->setMaxTextLength(1000000);
|
||||||
|
MyGUI::Widget* eventbox;
|
||||||
|
|
||||||
|
//An EditBox cannot receive mouse click events, so we use an
|
||||||
|
//invisible widget on top of the editbox to receive them
|
||||||
|
getWidget(eventbox, "EventBox");
|
||||||
|
eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked);
|
||||||
|
eventbox->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel);
|
||||||
|
|
||||||
|
//Topics list
|
||||||
|
getWidget(mTopicsList, "TopicsList");
|
||||||
|
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
||||||
|
|
||||||
|
MyGUI::Button* byeButton;
|
||||||
|
getWidget(byeButton, "ByeButton");
|
||||||
|
byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
|
||||||
|
|
||||||
|
getWidget(mDispositionBar, "Disposition");
|
||||||
|
getWidget(mDispositionText,"DispositionText");
|
||||||
|
|
||||||
|
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
MyGUI::ISubWidgetText* t = mHistory->getClient()->getSubWidgetText();
|
||||||
|
if(t == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const MyGUI::IntPoint& lastPressed = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left);
|
||||||
|
|
||||||
|
size_t cursorPosition = t->getCursorPosition(lastPressed);
|
||||||
|
MyGUI::UString color = mHistory->getColorAtPos(cursorPosition);
|
||||||
|
|
||||||
|
if (!mEnabled && color == "#572D21")
|
||||||
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
|
|
||||||
|
if (!mEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(color != "#B29154")
|
||||||
|
{
|
||||||
|
MyGUI::UString key = mHistory->getColorTextAt(cursorPosition);
|
||||||
|
|
||||||
|
if(color == "#686EBA")
|
||||||
|
{
|
||||||
|
std::map<size_t, HyperLink>::iterator i = mHyperLinks.upper_bound(cursorPosition);
|
||||||
|
if( !mHyperLinks.empty() )
|
||||||
|
{
|
||||||
|
--i;
|
||||||
|
|
||||||
|
if( i->first + i->second.mLength > cursorPosition)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getDialogueManager()->keywordSelected(i->second.mTrueValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the link was colored, but it is not in mHyperLinks.
|
||||||
|
// It means that those liunks are not marked with @# and found
|
||||||
|
// by topic name search
|
||||||
|
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(color == "#572D21")
|
||||||
|
MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onWindowResize(MyGUI::Window* _sender)
|
||||||
|
{
|
||||||
|
mTopicsList->adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||||
|
{
|
||||||
|
if (mHistory->getVScrollPosition() - _rel*0.3 < 0)
|
||||||
|
mHistory->setVScrollPosition(0);
|
||||||
|
else
|
||||||
|
mHistory->setVScrollPosition(mHistory->getVScrollPosition() - _rel*0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onSelectTopic(const std::string& topic, int id)
|
||||||
|
{
|
||||||
|
if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int separatorPos = 0;
|
||||||
|
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
|
||||||
|
{
|
||||||
|
if (mTopicsList->getItemNameAt(i) == "")
|
||||||
|
separatorPos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id >= separatorPos)
|
||||||
|
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
|
if (topic == gmst.find("sPersuasion")->getString())
|
||||||
|
{
|
||||||
|
mPersuasionDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
else if (topic == gmst.find("sCompanionShare")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion);
|
||||||
|
MWBase::Environment::get().getWindowManager()->showCompanionWindow(mPtr);
|
||||||
|
}
|
||||||
|
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
|
||||||
|
{
|
||||||
|
if (topic == gmst.find("sBarter")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter);
|
||||||
|
MWBase::Environment::get().getWindowManager()->getTradeWindow()->startTrade(mPtr);
|
||||||
|
}
|
||||||
|
else if (topic == gmst.find("sSpells")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellBuying);
|
||||||
|
MWBase::Environment::get().getWindowManager()->getSpellBuyingWindow()->startSpellBuying(mPtr);
|
||||||
|
}
|
||||||
|
else if (topic == gmst.find("sTravel")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Travel);
|
||||||
|
MWBase::Environment::get().getWindowManager()->getTravelWindow()->startTravel(mPtr);
|
||||||
|
}
|
||||||
|
else if (topic == gmst.find("sSpellMakingMenuTitle")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellCreation);
|
||||||
|
MWBase::Environment::get().getWindowManager()->startSpellMaking (mPtr);
|
||||||
|
}
|
||||||
|
else if (topic == gmst.find("sEnchanting")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting);
|
||||||
|
MWBase::Environment::get().getWindowManager()->startEnchanting (mPtr);
|
||||||
|
}
|
||||||
|
else if (topic == gmst.find("sServiceTrainingTitle")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Training);
|
||||||
|
MWBase::Environment::get().getWindowManager()->startTraining (mPtr);
|
||||||
|
}
|
||||||
|
else if (topic == gmst.find("sRepair")->getString())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair);
|
||||||
|
MWBase::Environment::get().getWindowManager()->startRepair (mPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
|
||||||
|
{
|
||||||
|
mEnabled = true;
|
||||||
|
mPtr = actor;
|
||||||
|
mTopicsList->setEnabled(true);
|
||||||
|
setTitle(npcName);
|
||||||
|
|
||||||
|
mTopicsList->clear();
|
||||||
|
mHyperLinks.clear();
|
||||||
|
mHistory->setCaption("");
|
||||||
|
updateOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
||||||
|
{
|
||||||
|
mTopicsList->clear();
|
||||||
|
|
||||||
|
bool isCompanion = !MWWorld::Class::get(mPtr).getScript(mPtr).empty()
|
||||||
|
&& mPtr.getRefData().getLocals().getIntVar(MWWorld::Class::get(mPtr).getScript(mPtr), "companion");
|
||||||
|
|
||||||
|
bool anyService = mServices > 0 || isCompanion || mPtr.getTypeName() == typeid(ESM::NPC).name();
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
if (topic == gmst.find("sPersuasion")->getString())
|
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||||
|
mTopicsList->addItem(gmst.find("sPersuasion")->getString());
|
||||||
|
|
||||||
|
if (mServices & Service_Trade)
|
||||||
|
mTopicsList->addItem(gmst.find("sBarter")->getString());
|
||||||
|
|
||||||
|
if (mServices & Service_BuySpells)
|
||||||
|
mTopicsList->addItem(gmst.find("sSpells")->getString());
|
||||||
|
|
||||||
|
if (mServices & Service_Travel)
|
||||||
|
mTopicsList->addItem(gmst.find("sTravel")->getString());
|
||||||
|
|
||||||
|
if (mServices & Service_CreateSpells)
|
||||||
|
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
|
||||||
|
|
||||||
|
if (mServices & Service_Enchant)
|
||||||
|
mTopicsList->addItem(gmst.find("sEnchanting")->getString());
|
||||||
|
|
||||||
|
if (mServices & Service_Training)
|
||||||
|
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
|
||||||
|
|
||||||
|
if (mServices & Service_Repair)
|
||||||
|
mTopicsList->addItem(gmst.find("sRepair")->getString());
|
||||||
|
|
||||||
|
if (isCompanion)
|
||||||
|
mTopicsList->addItem(gmst.find("sCompanionShare")->getString());
|
||||||
|
|
||||||
|
if (anyService)
|
||||||
|
mTopicsList->addSeparator();
|
||||||
|
|
||||||
|
|
||||||
|
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
|
||||||
{
|
{
|
||||||
mPersuasionDialog.setVisible(true);
|
mTopicsList->addItem(*it);
|
||||||
}
|
}
|
||||||
else if (topic == gmst.find("sCompanionShare")->getString())
|
mTopicsList->adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::removeKeyword(std::string keyWord)
|
||||||
|
{
|
||||||
|
if(mTopicsList->hasItem(keyWord))
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion);
|
mTopicsList->removeItem(keyWord);
|
||||||
MWBase::Environment::get().getWindowManager()->showCompanionWindow(mPtr);
|
|
||||||
}
|
}
|
||||||
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
|
mTopicsList->adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (topic == gmst.find("sBarter")->getString())
|
// do not add color if this portion of text is already colored.
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter);
|
MyGUI::TextIterator iterator (str);
|
||||||
MWBase::Environment::get().getWindowManager()->getTradeWindow()->startTrade(mPtr);
|
MyGUI::UString colour;
|
||||||
}
|
while(iterator.moveNext())
|
||||||
else if (topic == gmst.find("sSpells")->getString())
|
{
|
||||||
{
|
size_t iteratorPos = iterator.getPosition();
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellBuying);
|
iterator.getTagColour(colour);
|
||||||
MWBase::Environment::get().getWindowManager()->getSpellBuyingWindow()->startSpellBuying(mPtr);
|
if (iteratorPos == pos)
|
||||||
}
|
break;
|
||||||
else if (topic == gmst.find("sTravel")->getString())
|
}
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Travel);
|
if (colour == color1)
|
||||||
MWBase::Environment::get().getWindowManager()->getTravelWindow()->startTravel(mPtr);
|
return;
|
||||||
}
|
|
||||||
else if (topic == gmst.find("sSpellMakingMenuTitle")->getString())
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellCreation);
|
|
||||||
MWBase::Environment::get().getWindowManager()->startSpellMaking (mPtr);
|
|
||||||
}
|
|
||||||
else if (topic == gmst.find("sEnchanting")->getString())
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting);
|
|
||||||
MWBase::Environment::get().getWindowManager()->startEnchanting (mPtr);
|
|
||||||
}
|
|
||||||
else if (topic == gmst.find("sServiceTrainingTitle")->getString())
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Training);
|
|
||||||
MWBase::Environment::get().getWindowManager()->startTraining (mPtr);
|
|
||||||
}
|
|
||||||
else if (topic == gmst.find("sRepair")->getString())
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair);
|
|
||||||
MWBase::Environment::get().getWindowManager()->startRepair (mPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
str.insert(pos,color1);
|
||||||
|
pos += color1.length();
|
||||||
|
pos += keyword.length();
|
||||||
|
str.insert(pos,color2);
|
||||||
|
pos+= color2.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
|
std::string DialogueWindow::parseText(const std::string& text)
|
||||||
{
|
|
||||||
mEnabled = true;
|
|
||||||
mPtr = actor;
|
|
||||||
mTopicsList->setEnabled(true);
|
|
||||||
setTitle(npcName);
|
|
||||||
|
|
||||||
mTopicsList->clear();
|
|
||||||
mHyperLinks.clear();
|
|
||||||
mHistory->setCaption("");
|
|
||||||
updateOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
|
||||||
{
|
|
||||||
mTopicsList->clear();
|
|
||||||
|
|
||||||
bool isCompanion = !MWWorld::Class::get(mPtr).getScript(mPtr).empty()
|
|
||||||
&& mPtr.getRefData().getLocals().getIntVar(MWWorld::Class::get(mPtr).getScript(mPtr), "companion");
|
|
||||||
|
|
||||||
bool anyService = mServices > 0 || isCompanion || mPtr.getTypeName() == typeid(ESM::NPC).name();
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
|
||||||
|
|
||||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
|
||||||
mTopicsList->addItem(gmst.find("sPersuasion")->getString());
|
|
||||||
|
|
||||||
if (mServices & Service_Trade)
|
|
||||||
mTopicsList->addItem(gmst.find("sBarter")->getString());
|
|
||||||
|
|
||||||
if (mServices & Service_BuySpells)
|
|
||||||
mTopicsList->addItem(gmst.find("sSpells")->getString());
|
|
||||||
|
|
||||||
if (mServices & Service_Travel)
|
|
||||||
mTopicsList->addItem(gmst.find("sTravel")->getString());
|
|
||||||
|
|
||||||
if (mServices & Service_CreateSpells)
|
|
||||||
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
|
|
||||||
|
|
||||||
if (mServices & Service_Enchant)
|
|
||||||
mTopicsList->addItem(gmst.find("sEnchanting")->getString());
|
|
||||||
|
|
||||||
if (mServices & Service_Training)
|
|
||||||
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
|
|
||||||
|
|
||||||
if (mServices & Service_Repair)
|
|
||||||
mTopicsList->addItem(gmst.find("sRepair")->getString());
|
|
||||||
|
|
||||||
if (isCompanion)
|
|
||||||
mTopicsList->addItem(gmst.find("sCompanionShare")->getString());
|
|
||||||
|
|
||||||
if (anyService)
|
|
||||||
mTopicsList->addSeparator();
|
|
||||||
|
|
||||||
|
|
||||||
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
|
|
||||||
{
|
{
|
||||||
mTopicsList->addItem(*it);
|
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
|
||||||
}
|
|
||||||
mTopicsList->adjustSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::removeKeyword(std::string keyWord)
|
std::vector<std::string> topics;
|
||||||
{
|
|
||||||
if(mTopicsList->hasItem(keyWord))
|
|
||||||
{
|
|
||||||
mTopicsList->removeItem(keyWord);
|
|
||||||
}
|
|
||||||
mTopicsList->adjustSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2)
|
bool hasSeparator = false;
|
||||||
{
|
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
|
||||||
size_t pos = 0;
|
|
||||||
while((pos = find_str_ci(str,keyword, pos)) != std::string::npos)
|
|
||||||
{
|
|
||||||
// do not add color if this portion of text is already colored.
|
|
||||||
{
|
{
|
||||||
MyGUI::TextIterator iterator (str);
|
if (mTopicsList->getItemNameAt(i) == "")
|
||||||
MyGUI::UString colour;
|
hasSeparator = true;
|
||||||
while(iterator.moveNext())
|
|
||||||
{
|
|
||||||
size_t iteratorPos = iterator.getPosition();
|
|
||||||
iterator.getTagColour(colour);
|
|
||||||
if (iteratorPos == pos)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colour == color1)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
str.insert(pos,color1);
|
for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
|
||||||
pos += color1.length();
|
|
||||||
pos += keyword.length();
|
|
||||||
str.insert(pos,color2);
|
|
||||||
pos+= color2.length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DialogueWindow::parseText(const std::string& text)
|
|
||||||
{
|
|
||||||
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
|
|
||||||
|
|
||||||
std::vector<std::string> topics;
|
|
||||||
|
|
||||||
bool hasSeparator = false;
|
|
||||||
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
|
|
||||||
{
|
|
||||||
if (mTopicsList->getItemNameAt(i) == "")
|
|
||||||
hasSeparator = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
|
|
||||||
{
|
|
||||||
std::string keyWord = mTopicsList->getItemNameAt(i);
|
|
||||||
if (separatorReached || !hasSeparator)
|
|
||||||
topics.push_back(keyWord);
|
|
||||||
else if (keyWord == "")
|
|
||||||
separatorReached = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort by length to make sure longer topics are replaced first
|
|
||||||
std::sort(topics.begin(), topics.end(), sortByLength);
|
|
||||||
|
|
||||||
std::vector<MWDialogue::HyperTextToken> hypertext = MWDialogue::ParseHyperText(text);
|
|
||||||
|
|
||||||
size_t historySize = 0;
|
|
||||||
if(mHistory->getClient()->getSubWidgetText() != NULL)
|
|
||||||
{
|
|
||||||
historySize = mHistory->getOnlyText().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
size_t hypertextPos = 0;
|
|
||||||
for (size_t i = 0; i < hypertext.size(); ++i)
|
|
||||||
{
|
|
||||||
if (hypertext[i].mLink)
|
|
||||||
{
|
{
|
||||||
size_t asterisk_count = MWDialogue::RemovePseudoAsterisks(hypertext[i].mText);
|
std::string keyWord = mTopicsList->getItemNameAt(i);
|
||||||
std::string standardForm = hypertext[i].mText;
|
if (separatorReached || !hasSeparator)
|
||||||
for(; asterisk_count > 0; --asterisk_count)
|
topics.push_back(keyWord);
|
||||||
standardForm.append("*");
|
else if (keyWord == "")
|
||||||
|
separatorReached = true;
|
||||||
|
}
|
||||||
|
|
||||||
standardForm =
|
// sort by length to make sure longer topics are replaced first
|
||||||
MWBase::Environment::get().getWindowManager()->
|
std::sort(topics.begin(), topics.end(), sortByLength);
|
||||||
getTranslationDataStorage().topicStandardForm(standardForm);
|
|
||||||
|
|
||||||
if( std::find(topics.begin(), topics.end(), std::string(standardForm) ) != topics.end() )
|
std::vector<MWDialogue::HyperTextToken> hypertext = MWDialogue::ParseHyperText(text);
|
||||||
|
|
||||||
|
size_t historySize = 0;
|
||||||
|
if(mHistory->getClient()->getSubWidgetText() != NULL)
|
||||||
|
{
|
||||||
|
historySize = mHistory->getOnlyText().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
size_t hypertextPos = 0;
|
||||||
|
for (size_t i = 0; i < hypertext.size(); ++i)
|
||||||
|
{
|
||||||
|
if (hypertext[i].mLink)
|
||||||
{
|
{
|
||||||
result.append("#686EBA").append(hypertext[i].mText).append("#B29154");
|
size_t asterisk_count = MWDialogue::RemovePseudoAsterisks(hypertext[i].mText);
|
||||||
|
std::string standardForm = hypertext[i].mText;
|
||||||
|
for(; asterisk_count > 0; --asterisk_count)
|
||||||
|
standardForm.append("*");
|
||||||
|
|
||||||
mHyperLinks[historySize+hypertextPos].mLength = MyGUI::UString(hypertext[i].mText).length();
|
standardForm =
|
||||||
mHyperLinks[historySize+hypertextPos].mTrueValue = lower_string(standardForm);
|
MWBase::Environment::get().getWindowManager()->
|
||||||
|
getTranslationDataStorage().topicStandardForm(standardForm);
|
||||||
|
|
||||||
|
if( std::find(topics.begin(), topics.end(), std::string(standardForm) ) != topics.end() )
|
||||||
|
{
|
||||||
|
result.append("#686EBA").append(hypertext[i].mText).append("#B29154");
|
||||||
|
|
||||||
|
mHyperLinks[historySize+hypertextPos].mLength = MyGUI::UString(hypertext[i].mText).length();
|
||||||
|
mHyperLinks[historySize+hypertextPos].mTrueValue = lower_string(standardForm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result += hypertext[i].mText;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result += hypertext[i].mText;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation() )
|
|
||||||
{
|
{
|
||||||
for(std::vector<std::string>::const_iterator it = topics.begin(); it != topics.end(); ++it)
|
if( !MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation() )
|
||||||
{
|
{
|
||||||
addColorInString(hypertext[i].mText, *it, "#686EBA", "#B29154");
|
for(std::vector<std::string>::const_iterator it = topics.begin(); it != topics.end(); ++it)
|
||||||
|
{
|
||||||
|
addColorInString(hypertext[i].mText, *it, "#686EBA", "#B29154");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result += hypertext[i].mText;
|
||||||
}
|
}
|
||||||
|
|
||||||
result += hypertext[i].mText;
|
hypertextPos += MyGUI::UString(hypertext[i].mText).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
hypertextPos += MyGUI::UString(hypertext[i].mText).length();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
void DialogueWindow::addText(std::string text)
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::addText(std::string text)
|
|
||||||
{
|
|
||||||
mHistory->addDialogText("#B29154"+parseText(text)+"#B29154");
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::addMessageBox(const std::string& text)
|
|
||||||
{
|
|
||||||
mHistory->addDialogText("\n#FFFFFF"+text+"#B29154");
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::addTitle(std::string text)
|
|
||||||
{
|
|
||||||
// This is called from the dialogue manager, so text is
|
|
||||||
// case-smashed - thus we have to retrieve the correct case
|
|
||||||
// of the text through the topic list.
|
|
||||||
for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
|
|
||||||
{
|
{
|
||||||
std::string item = mTopicsList->getItemNameAt(i);
|
mHistory->addDialogText("#B29154"+parseText(text)+"#B29154");
|
||||||
if (lower_string(item) == text)
|
|
||||||
text = item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mHistory->addDialogHeading(text);
|
void DialogueWindow::addMessageBox(const std::string& text)
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::askQuestion(std::string question)
|
|
||||||
{
|
|
||||||
mHistory->addDialogText("#572D21"+question+"#B29154"+" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::updateOptions()
|
|
||||||
{
|
|
||||||
//Clear the list of topics
|
|
||||||
mTopicsList->clear();
|
|
||||||
mHyperLinks.clear();
|
|
||||||
mHistory->eraseText(0, mHistory->getTextLength());
|
|
||||||
|
|
||||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
|
||||||
{
|
{
|
||||||
mDispositionBar->setProgressRange(100);
|
mHistory->addDialogText("\n#FFFFFF"+text+"#B29154");
|
||||||
mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr));
|
|
||||||
mDispositionText->eraseText(0, mDispositionText->getTextLength());
|
|
||||||
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100")+"#B29154");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::goodbye()
|
void DialogueWindow::addTitle(std::string text)
|
||||||
{
|
|
||||||
mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString());
|
|
||||||
mTopicsList->setEnabled(false);
|
|
||||||
mEnabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onReferenceUnavailable()
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onFrame()
|
|
||||||
{
|
|
||||||
if(mMainWidget->getVisible() && mEnabled && mPtr.getTypeName() == typeid(ESM::NPC).name())
|
|
||||||
{
|
{
|
||||||
int disp = std::max(0, std::min(100,
|
// This is called from the dialogue manager, so text is
|
||||||
MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
|
// case-smashed - thus we have to retrieve the correct case
|
||||||
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()));
|
// of the text through the topic list.
|
||||||
mDispositionBar->setProgressRange(100);
|
for (size_t i=0; i<mTopicsList->getItemCount(); ++i)
|
||||||
mDispositionBar->setProgressPosition(disp);
|
{
|
||||||
mDispositionText->eraseText(0, mDispositionText->getTextLength());
|
std::string item = mTopicsList->getItemNameAt(i);
|
||||||
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(disp)+std::string("/100")+"#B29154");
|
if (lower_string(item) == text)
|
||||||
|
text = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHistory->addDialogHeading(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::askQuestion(std::string question)
|
||||||
|
{
|
||||||
|
mHistory->addDialogText("#572D21"+question+"#B29154"+" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::updateOptions()
|
||||||
|
{
|
||||||
|
//Clear the list of topics
|
||||||
|
mTopicsList->clear();
|
||||||
|
mHyperLinks.clear();
|
||||||
|
mHistory->eraseText(0, mHistory->getTextLength());
|
||||||
|
|
||||||
|
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||||
|
{
|
||||||
|
mDispositionBar->setProgressRange(100);
|
||||||
|
mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr));
|
||||||
|
mDispositionText->eraseText(0, mDispositionText->getTextLength());
|
||||||
|
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100")+"#B29154");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::goodbye()
|
||||||
|
{
|
||||||
|
mHistory->addDialogText("\n#572D21" + MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString());
|
||||||
|
mTopicsList->setEnabled(false);
|
||||||
|
mEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onReferenceUnavailable()
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onFrame()
|
||||||
|
{
|
||||||
|
if(mMainWidget->getVisible() && mEnabled && mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||||
|
{
|
||||||
|
int disp = std::max(0, std::min(100,
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)
|
||||||
|
+ MWBase::Environment::get().getDialogueManager()->getTemporaryDispositionChange()));
|
||||||
|
mDispositionBar->setProgressRange(100);
|
||||||
|
mDispositionBar->setProgressPosition(disp);
|
||||||
|
mDispositionText->eraseText(0, mDispositionText->getTextLength());
|
||||||
|
mDispositionText->addText("#B29154"+boost::lexical_cast<std::string>(disp)+std::string("/100")+"#B29154");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,65 +12,67 @@
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
using namespace Widgets;
|
|
||||||
|
|
||||||
MyGUI::UString DialogueHistory::getColorAtPos(size_t _pos)
|
|
||||||
{
|
{
|
||||||
MyGUI::UString colour = MyGUI::TextIterator::convertTagColour(getTextColour());
|
|
||||||
MyGUI::TextIterator iterator(getCaption());
|
|
||||||
while(iterator.moveNext())
|
|
||||||
{
|
|
||||||
size_t pos = iterator.getPosition();
|
|
||||||
iterator.getTagColour(colour);
|
|
||||||
if (pos < _pos)
|
|
||||||
continue;
|
|
||||||
else if (pos == _pos)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyGUI::UString DialogueHistory::getColorTextAt(size_t _pos)
|
MyGUI::UString DialogueHistory::getColorAtPos(size_t _pos)
|
||||||
{
|
|
||||||
bool breakOnNext = false;
|
|
||||||
MyGUI::UString colour = MyGUI::TextIterator::convertTagColour(getTextColour());
|
|
||||||
MyGUI::UString colour2 = colour;
|
|
||||||
MyGUI::TextIterator iterator(getCaption());
|
|
||||||
MyGUI::TextIterator col_start = iterator;
|
|
||||||
while(iterator.moveNext())
|
|
||||||
{
|
{
|
||||||
size_t pos = iterator.getPosition();
|
MyGUI::UString colour = MyGUI::TextIterator::convertTagColour(getTextColour());
|
||||||
iterator.getTagColour(colour);
|
MyGUI::TextIterator iterator(getCaption());
|
||||||
if(colour != colour2)
|
while(iterator.moveNext())
|
||||||
{
|
{
|
||||||
if(breakOnNext)
|
size_t pos = iterator.getPosition();
|
||||||
|
iterator.getTagColour(colour);
|
||||||
|
if (pos < _pos)
|
||||||
|
continue;
|
||||||
|
else if (pos == _pos)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyGUI::UString DialogueHistory::getColorTextAt(size_t _pos)
|
||||||
|
{
|
||||||
|
bool breakOnNext = false;
|
||||||
|
MyGUI::UString colour = MyGUI::TextIterator::convertTagColour(getTextColour());
|
||||||
|
MyGUI::UString colour2 = colour;
|
||||||
|
MyGUI::TextIterator iterator(getCaption());
|
||||||
|
MyGUI::TextIterator col_start = iterator;
|
||||||
|
while(iterator.moveNext())
|
||||||
|
{
|
||||||
|
size_t pos = iterator.getPosition();
|
||||||
|
iterator.getTagColour(colour);
|
||||||
|
if(colour != colour2)
|
||||||
{
|
{
|
||||||
return getOnlyText().substr(col_start.getPosition(), iterator.getPosition()-col_start.getPosition());
|
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;
|
||||||
}
|
}
|
||||||
col_start = iterator;
|
|
||||||
colour2 = colour;
|
|
||||||
}
|
|
||||||
if (pos < _pos)
|
|
||||||
continue;
|
|
||||||
else if (pos == _pos)
|
|
||||||
{
|
|
||||||
breakOnNext = true;
|
|
||||||
}
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueHistory::addDialogHeading(const MyGUI::UString& parText)
|
void DialogueHistory::addDialogHeading(const MyGUI::UString& parText)
|
||||||
{
|
{
|
||||||
MyGUI::UString head("\n#D8C09A");
|
MyGUI::UString head("\n#D8C09A");
|
||||||
head.append(parText);
|
head.append(parText);
|
||||||
head.append("#B29154\n");
|
head.append("#B29154\n");
|
||||||
addText(head);
|
addText(head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogueHistory::addDialogText(const MyGUI::UString& parText)
|
||||||
|
{
|
||||||
|
addText(parText);
|
||||||
|
addText("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void DialogueHistory::addDialogText(const MyGUI::UString& parText)
|
|
||||||
{
|
|
||||||
addText(parText);
|
|
||||||
addText("\n");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <OgreUTFString.h>
|
#include <OgreUTFString.h>
|
||||||
|
|
||||||
using namespace MWGui;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
int convertFromHex(std::string hex)
|
int convertFromHex(std::string hex)
|
||||||
|
@ -78,287 +76,292 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
|
namespace MWGui
|
||||||
{
|
{
|
||||||
using Ogre::UTFString;
|
|
||||||
std::vector<std::string> result;
|
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
|
std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
|
||||||
utf8Text = Interpreter::fixDefinesBook(utf8Text, interpreterContext);
|
|
||||||
|
|
||||||
boost::algorithm::replace_all(utf8Text, "\n", "");
|
|
||||||
boost::algorithm::replace_all(utf8Text, "<BR>", "\n");
|
|
||||||
boost::algorithm::replace_all(utf8Text, "<P>", "\n\n");
|
|
||||||
|
|
||||||
UTFString text(utf8Text);
|
|
||||||
const int spacing = 48;
|
|
||||||
|
|
||||||
const UTFString::unicode_char LEFT_ANGLE = unicodeCharFromChar('<');
|
|
||||||
const UTFString::unicode_char NEWLINE = unicodeCharFromChar('\n');
|
|
||||||
const UTFString::unicode_char SPACE = unicodeCharFromChar(' ');
|
|
||||||
|
|
||||||
while (!text.empty())
|
|
||||||
{
|
{
|
||||||
// read in characters until we have exceeded the size, or run out of text
|
using Ogre::UTFString;
|
||||||
int currentWidth = 0;
|
std::vector<std::string> result;
|
||||||
int currentHeight = 0;
|
|
||||||
|
|
||||||
size_t currentWordStart = 0;
|
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
|
||||||
size_t index = 0;
|
utf8Text = Interpreter::fixDefinesBook(utf8Text, interpreterContext);
|
||||||
while (currentHeight <= height - spacing && index < text.size())
|
|
||||||
|
boost::algorithm::replace_all(utf8Text, "\n", "");
|
||||||
|
boost::algorithm::replace_all(utf8Text, "<BR>", "\n");
|
||||||
|
boost::algorithm::replace_all(utf8Text, "<P>", "\n\n");
|
||||||
|
|
||||||
|
UTFString text(utf8Text);
|
||||||
|
const int spacing = 48;
|
||||||
|
|
||||||
|
const UTFString::unicode_char LEFT_ANGLE = unicodeCharFromChar('<');
|
||||||
|
const UTFString::unicode_char NEWLINE = unicodeCharFromChar('\n');
|
||||||
|
const UTFString::unicode_char SPACE = unicodeCharFromChar(' ');
|
||||||
|
|
||||||
|
while (!text.empty())
|
||||||
{
|
{
|
||||||
const UTFString::unicode_char ch = text.getChar(index);
|
// read in characters until we have exceeded the size, or run out of text
|
||||||
if (ch == LEFT_ANGLE)
|
int currentWidth = 0;
|
||||||
{
|
int currentHeight = 0;
|
||||||
const size_t tagStart = index + 1;
|
|
||||||
const size_t tagEnd = text.find('>', tagStart);
|
|
||||||
if (tagEnd == UTFString::npos)
|
|
||||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
|
||||||
const std::string tag = text.substr(tagStart, tagEnd - tagStart).asUTF8();
|
|
||||||
|
|
||||||
if (boost::algorithm::starts_with(tag, "IMG"))
|
size_t currentWordStart = 0;
|
||||||
|
size_t index = 0;
|
||||||
|
while (currentHeight <= height - spacing && index < text.size())
|
||||||
|
{
|
||||||
|
const UTFString::unicode_char ch = text.getChar(index);
|
||||||
|
if (ch == LEFT_ANGLE)
|
||||||
{
|
{
|
||||||
const int h = mHeight;
|
const size_t tagStart = index + 1;
|
||||||
parseImage(tag, false);
|
const size_t tagEnd = text.find('>', tagStart);
|
||||||
currentHeight += (mHeight - h);
|
if (tagEnd == UTFString::npos)
|
||||||
currentWidth = 0;
|
|
||||||
}
|
|
||||||
else if (boost::algorithm::starts_with(tag, "FONT"))
|
|
||||||
{
|
|
||||||
parseFont(tag);
|
|
||||||
if (currentWidth != 0) {
|
|
||||||
currentHeight += currentFontHeight();
|
|
||||||
currentWidth = 0;
|
|
||||||
}
|
|
||||||
currentWidth = 0;
|
|
||||||
}
|
|
||||||
else if (boost::algorithm::starts_with(tag, "DIV"))
|
|
||||||
{
|
|
||||||
parseDiv(tag);
|
|
||||||
if (currentWidth != 0) {
|
|
||||||
currentHeight += currentFontHeight();
|
|
||||||
currentWidth = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index = tagEnd;
|
|
||||||
}
|
|
||||||
else if (ch == NEWLINE)
|
|
||||||
{
|
|
||||||
currentHeight += currentFontHeight();
|
|
||||||
currentWidth = 0;
|
|
||||||
currentWordStart = index;
|
|
||||||
}
|
|
||||||
else if (ch == SPACE)
|
|
||||||
{
|
|
||||||
currentWidth += 3; // keep this in sync with the font's SpaceWidth property
|
|
||||||
currentWordStart = index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentWidth += widthForCharGlyph(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentWidth > width)
|
|
||||||
{
|
|
||||||
currentHeight += currentFontHeight();
|
|
||||||
currentWidth = 0;
|
|
||||||
// add size of the current word
|
|
||||||
UTFString word = text.substr(currentWordStart, index - currentWordStart);
|
|
||||||
for (UTFString::const_iterator it = word.begin(), end = word.end(); it != end; ++it)
|
|
||||||
currentWidth += widthForCharGlyph(it.getCharacter());
|
|
||||||
}
|
|
||||||
index += UTFString::_utf16_char_length(ch);
|
|
||||||
}
|
|
||||||
const size_t pageEnd = (currentHeight > height - spacing && currentWordStart != 0)
|
|
||||||
? currentWordStart : index;
|
|
||||||
|
|
||||||
result.push_back(text.substr(0, pageEnd).asUTF8());
|
|
||||||
text.erase(0, pageEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const
|
|
||||||
{
|
|
||||||
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
|
||||||
return MyGUI::FontManager::getInstance().getByName(fontName)
|
|
||||||
->getGlyphInfo(unicodeChar)->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
float BookTextParser::currentFontHeight() const
|
|
||||||
{
|
|
||||||
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
|
||||||
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width)
|
|
||||||
{
|
|
||||||
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
|
|
||||||
text = Interpreter::fixDefinesBook(text, interpreterContext);
|
|
||||||
|
|
||||||
mParent = parent;
|
|
||||||
mWidth = width;
|
|
||||||
mHeight = 0;
|
|
||||||
|
|
||||||
assert(mParent);
|
|
||||||
while (mParent->getChildCount())
|
|
||||||
{
|
|
||||||
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::algorithm::replace_all(text, "\n", "");
|
|
||||||
boost::algorithm::replace_all(text, "<BR>", "\n");
|
|
||||||
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
|
||||||
|
|
||||||
// remove leading newlines
|
|
||||||
// while (text[0] == '\n')
|
|
||||||
// text.erase(0);
|
|
||||||
|
|
||||||
// remove trailing "
|
|
||||||
if (text[text.size()-1] == '\"')
|
|
||||||
text.erase(text.size()-1);
|
|
||||||
|
|
||||||
parseSubText(text);
|
|
||||||
return MyGUI::IntSize(mWidth, mHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookTextParser::parseImage(std::string tag, bool createWidget)
|
|
||||||
{
|
|
||||||
int src_start = tag.find("SRC=")+5;
|
|
||||||
std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start);
|
|
||||||
|
|
||||||
// fix texture extension to .dds
|
|
||||||
if (image.size() > 4)
|
|
||||||
{
|
|
||||||
image[image.size()-3] = 'd';
|
|
||||||
image[image.size()-2] = 'd';
|
|
||||||
image[image.size()-1] = 's';
|
|
||||||
}
|
|
||||||
|
|
||||||
int width_start = tag.find("WIDTH=")+7;
|
|
||||||
int width = boost::lexical_cast<int>(tag.substr(width_start, tag.find('"', width_start)-width_start));
|
|
||||||
|
|
||||||
int height_start = tag.find("HEIGHT=")+8;
|
|
||||||
int height = boost::lexical_cast<int>(tag.substr(height_start, tag.find('"', height_start)-height_start));
|
|
||||||
|
|
||||||
if (createWidget)
|
|
||||||
{
|
|
||||||
MyGUI::ImageBox* box = mParent->createWidget<MyGUI::ImageBox> ("ImageBox",
|
|
||||||
MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top,
|
|
||||||
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
|
||||||
box->setImageTexture("bookart\\" + image);
|
|
||||||
box->setProperty("NeedMouse", "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
mWidth = std::max(mWidth, width);
|
|
||||||
mHeight += height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookTextParser::parseDiv(std::string tag)
|
|
||||||
{
|
|
||||||
if (tag.find("ALIGN=") == std::string::npos)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int align_start = tag.find("ALIGN=")+7;
|
|
||||||
std::string align = tag.substr(align_start, tag.find('"', align_start)-align_start);
|
|
||||||
if (align == "CENTER")
|
|
||||||
mTextStyle.mTextAlign = MyGUI::Align::HCenter;
|
|
||||||
else if (align == "LEFT")
|
|
||||||
mTextStyle.mTextAlign = MyGUI::Align::Left;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookTextParser::parseFont(std::string tag)
|
|
||||||
{
|
|
||||||
if (tag.find("COLOR=") != std::string::npos)
|
|
||||||
{
|
|
||||||
int color_start = tag.find("COLOR=")+7;
|
|
||||||
std::string color = tag.substr(color_start, tag.find('"', color_start)-color_start);
|
|
||||||
|
|
||||||
mTextStyle.mColour = MyGUI::Colour(
|
|
||||||
convertFromHex(color.substr(0, 2))/255.0,
|
|
||||||
convertFromHex(color.substr(2, 2))/255.0,
|
|
||||||
convertFromHex(color.substr(4, 2))/255.0);
|
|
||||||
}
|
|
||||||
if (tag.find("FACE=") != std::string::npos)
|
|
||||||
{
|
|
||||||
int face_start = tag.find("FACE=")+6;
|
|
||||||
std::string face = tag.substr(face_start, tag.find('"', face_start)-face_start);
|
|
||||||
|
|
||||||
if (face != "Magic Cards")
|
|
||||||
mTextStyle.mFont = face;
|
|
||||||
}
|
|
||||||
if (tag.find("SIZE=") != std::string::npos)
|
|
||||||
{
|
|
||||||
/// \todo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BookTextParser::parseSubText(std::string text)
|
|
||||||
{
|
|
||||||
if (text[0] == '<')
|
|
||||||
{
|
|
||||||
const size_t tagStart = 1;
|
|
||||||
const size_t tagEnd = text.find('>', tagStart);
|
|
||||||
if (tagEnd == std::string::npos)
|
|
||||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
|
||||||
const std::string tag = text.substr(tagStart, tagEnd - tagStart);
|
|
||||||
|
|
||||||
if (boost::algorithm::starts_with(tag, "IMG"))
|
|
||||||
parseImage(tag);
|
|
||||||
if (boost::algorithm::starts_with(tag, "FONT"))
|
|
||||||
parseFont(tag);
|
|
||||||
if (boost::algorithm::starts_with(tag, "DOV"))
|
|
||||||
parseDiv(tag);
|
|
||||||
|
|
||||||
text.erase(0, tagEnd + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t tagStart = std::string::npos;
|
|
||||||
std::string realText; // real text, without tags
|
|
||||||
for (size_t i = 0; i<text.size(); ++i)
|
|
||||||
{
|
|
||||||
char c = text[i];
|
|
||||||
if (c == '<')
|
|
||||||
{
|
|
||||||
if ((i + 1 < text.size()) && text[i+1] == '/') // ignore closing tags
|
|
||||||
{
|
|
||||||
while (c != '>')
|
|
||||||
{
|
|
||||||
if (i >= text.size())
|
|
||||||
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||||
++i;
|
const std::string tag = text.substr(tagStart, tagEnd - tagStart).asUTF8();
|
||||||
c = text[i];
|
|
||||||
|
if (boost::algorithm::starts_with(tag, "IMG"))
|
||||||
|
{
|
||||||
|
const int h = mHeight;
|
||||||
|
parseImage(tag, false);
|
||||||
|
currentHeight += (mHeight - h);
|
||||||
|
currentWidth = 0;
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::starts_with(tag, "FONT"))
|
||||||
|
{
|
||||||
|
parseFont(tag);
|
||||||
|
if (currentWidth != 0) {
|
||||||
|
currentHeight += currentFontHeight();
|
||||||
|
currentWidth = 0;
|
||||||
|
}
|
||||||
|
currentWidth = 0;
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::starts_with(tag, "DIV"))
|
||||||
|
{
|
||||||
|
parseDiv(tag);
|
||||||
|
if (currentWidth != 0) {
|
||||||
|
currentHeight += currentFontHeight();
|
||||||
|
currentWidth = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = tagEnd;
|
||||||
|
}
|
||||||
|
else if (ch == NEWLINE)
|
||||||
|
{
|
||||||
|
currentHeight += currentFontHeight();
|
||||||
|
currentWidth = 0;
|
||||||
|
currentWordStart = index;
|
||||||
|
}
|
||||||
|
else if (ch == SPACE)
|
||||||
|
{
|
||||||
|
currentWidth += 3; // keep this in sync with the font's SpaceWidth property
|
||||||
|
currentWordStart = index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentWidth += widthForCharGlyph(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentWidth > width)
|
||||||
|
{
|
||||||
|
currentHeight += currentFontHeight();
|
||||||
|
currentWidth = 0;
|
||||||
|
// add size of the current word
|
||||||
|
UTFString word = text.substr(currentWordStart, index - currentWordStart);
|
||||||
|
for (UTFString::const_iterator it = word.begin(), end = word.end(); it != end; ++it)
|
||||||
|
currentWidth += widthForCharGlyph(it.getCharacter());
|
||||||
|
}
|
||||||
|
index += UTFString::_utf16_char_length(ch);
|
||||||
|
}
|
||||||
|
const size_t pageEnd = (currentHeight > height - spacing && currentWordStart != 0)
|
||||||
|
? currentWordStart : index;
|
||||||
|
|
||||||
|
result.push_back(text.substr(0, pageEnd).asUTF8());
|
||||||
|
text.erase(0, pageEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const
|
||||||
|
{
|
||||||
|
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
||||||
|
return MyGUI::FontManager::getInstance().getByName(fontName)
|
||||||
|
->getGlyphInfo(unicodeChar)->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BookTextParser::currentFontHeight() const
|
||||||
|
{
|
||||||
|
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
||||||
|
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width)
|
||||||
|
{
|
||||||
|
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
|
||||||
|
text = Interpreter::fixDefinesBook(text, interpreterContext);
|
||||||
|
|
||||||
|
mParent = parent;
|
||||||
|
mWidth = width;
|
||||||
|
mHeight = 0;
|
||||||
|
|
||||||
|
assert(mParent);
|
||||||
|
while (mParent->getChildCount())
|
||||||
|
{
|
||||||
|
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::algorithm::replace_all(text, "\n", "");
|
||||||
|
boost::algorithm::replace_all(text, "<BR>", "\n");
|
||||||
|
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
||||||
|
|
||||||
|
// remove leading newlines
|
||||||
|
// while (text[0] == '\n')
|
||||||
|
// text.erase(0);
|
||||||
|
|
||||||
|
// remove trailing "
|
||||||
|
if (text[text.size()-1] == '\"')
|
||||||
|
text.erase(text.size()-1);
|
||||||
|
|
||||||
|
parseSubText(text);
|
||||||
|
return MyGUI::IntSize(mWidth, mHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookTextParser::parseImage(std::string tag, bool createWidget)
|
||||||
|
{
|
||||||
|
int src_start = tag.find("SRC=")+5;
|
||||||
|
std::string image = tag.substr(src_start, tag.find('"', src_start)-src_start);
|
||||||
|
|
||||||
|
// fix texture extension to .dds
|
||||||
|
if (image.size() > 4)
|
||||||
|
{
|
||||||
|
image[image.size()-3] = 'd';
|
||||||
|
image[image.size()-2] = 'd';
|
||||||
|
image[image.size()-1] = 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
int width_start = tag.find("WIDTH=")+7;
|
||||||
|
int width = boost::lexical_cast<int>(tag.substr(width_start, tag.find('"', width_start)-width_start));
|
||||||
|
|
||||||
|
int height_start = tag.find("HEIGHT=")+8;
|
||||||
|
int height = boost::lexical_cast<int>(tag.substr(height_start, tag.find('"', height_start)-height_start));
|
||||||
|
|
||||||
|
if (createWidget)
|
||||||
|
{
|
||||||
|
MyGUI::ImageBox* box = mParent->createWidget<MyGUI::ImageBox> ("ImageBox",
|
||||||
|
MyGUI::IntCoord(0, mHeight, width, height), MyGUI::Align::Left | MyGUI::Align::Top,
|
||||||
|
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
||||||
|
box->setImageTexture("bookart\\" + image);
|
||||||
|
box->setProperty("NeedMouse", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
mWidth = std::max(mWidth, width);
|
||||||
|
mHeight += height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookTextParser::parseDiv(std::string tag)
|
||||||
|
{
|
||||||
|
if (tag.find("ALIGN=") == std::string::npos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int align_start = tag.find("ALIGN=")+7;
|
||||||
|
std::string align = tag.substr(align_start, tag.find('"', align_start)-align_start);
|
||||||
|
if (align == "CENTER")
|
||||||
|
mTextStyle.mTextAlign = MyGUI::Align::HCenter;
|
||||||
|
else if (align == "LEFT")
|
||||||
|
mTextStyle.mTextAlign = MyGUI::Align::Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookTextParser::parseFont(std::string tag)
|
||||||
|
{
|
||||||
|
if (tag.find("COLOR=") != std::string::npos)
|
||||||
|
{
|
||||||
|
int color_start = tag.find("COLOR=")+7;
|
||||||
|
std::string color = tag.substr(color_start, tag.find('"', color_start)-color_start);
|
||||||
|
|
||||||
|
mTextStyle.mColour = MyGUI::Colour(
|
||||||
|
convertFromHex(color.substr(0, 2))/255.0,
|
||||||
|
convertFromHex(color.substr(2, 2))/255.0,
|
||||||
|
convertFromHex(color.substr(4, 2))/255.0);
|
||||||
|
}
|
||||||
|
if (tag.find("FACE=") != std::string::npos)
|
||||||
|
{
|
||||||
|
int face_start = tag.find("FACE=")+6;
|
||||||
|
std::string face = tag.substr(face_start, tag.find('"', face_start)-face_start);
|
||||||
|
|
||||||
|
if (face != "Magic Cards")
|
||||||
|
mTextStyle.mFont = face;
|
||||||
|
}
|
||||||
|
if (tag.find("SIZE=") != std::string::npos)
|
||||||
|
{
|
||||||
|
/// \todo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BookTextParser::parseSubText(std::string text)
|
||||||
|
{
|
||||||
|
if (text[0] == '<')
|
||||||
|
{
|
||||||
|
const size_t tagStart = 1;
|
||||||
|
const size_t tagEnd = text.find('>', tagStart);
|
||||||
|
if (tagEnd == std::string::npos)
|
||||||
|
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||||
|
const std::string tag = text.substr(tagStart, tagEnd - tagStart);
|
||||||
|
|
||||||
|
if (boost::algorithm::starts_with(tag, "IMG"))
|
||||||
|
parseImage(tag);
|
||||||
|
if (boost::algorithm::starts_with(tag, "FONT"))
|
||||||
|
parseFont(tag);
|
||||||
|
if (boost::algorithm::starts_with(tag, "DOV"))
|
||||||
|
parseDiv(tag);
|
||||||
|
|
||||||
|
text.erase(0, tagEnd + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t tagStart = std::string::npos;
|
||||||
|
std::string realText; // real text, without tags
|
||||||
|
for (size_t i = 0; i<text.size(); ++i)
|
||||||
|
{
|
||||||
|
char c = text[i];
|
||||||
|
if (c == '<')
|
||||||
|
{
|
||||||
|
if ((i + 1 < text.size()) && text[i+1] == '/') // ignore closing tags
|
||||||
|
{
|
||||||
|
while (c != '>')
|
||||||
|
{
|
||||||
|
if (i >= text.size())
|
||||||
|
throw std::runtime_error("BookTextParser Error: Tag is not terminated");
|
||||||
|
++i;
|
||||||
|
c = text[i];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tagStart = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
realText += c;
|
||||||
tagStart = i;
|
}
|
||||||
break;
|
|
||||||
}
|
MyGUI::EditBox* box = mParent->createWidget<MyGUI::EditBox>("NormalText",
|
||||||
|
MyGUI::IntCoord(0, mHeight, mWidth, 24), MyGUI::Align::Left | MyGUI::Align::Top,
|
||||||
|
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
||||||
|
box->setProperty("Static", "true");
|
||||||
|
box->setProperty("MultiLine", "true");
|
||||||
|
box->setProperty("WordWrap", "true");
|
||||||
|
box->setProperty("NeedMouse", "false");
|
||||||
|
box->setMaxTextLength(realText.size());
|
||||||
|
box->setTextAlign(mTextStyle.mTextAlign);
|
||||||
|
box->setTextColour(mTextStyle.mColour);
|
||||||
|
box->setFontName(mTextStyle.mFont);
|
||||||
|
box->setCaption(realText);
|
||||||
|
box->setSize(box->getSize().width, box->getTextSize().height);
|
||||||
|
mHeight += box->getTextSize().height;
|
||||||
|
|
||||||
|
if (tagStart != std::string::npos)
|
||||||
|
{
|
||||||
|
parseSubText(text.substr(tagStart, text.size()));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
realText += c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MyGUI::EditBox* box = mParent->createWidget<MyGUI::EditBox>("NormalText",
|
|
||||||
MyGUI::IntCoord(0, mHeight, mWidth, 24), MyGUI::Align::Left | MyGUI::Align::Top,
|
|
||||||
mParent->getName() + boost::lexical_cast<std::string>(mParent->getChildCount()));
|
|
||||||
box->setProperty("Static", "true");
|
|
||||||
box->setProperty("MultiLine", "true");
|
|
||||||
box->setProperty("WordWrap", "true");
|
|
||||||
box->setProperty("NeedMouse", "false");
|
|
||||||
box->setMaxTextLength(realText.size());
|
|
||||||
box->setTextAlign(mTextStyle.mTextAlign);
|
|
||||||
box->setTextColour(mTextStyle.mColour);
|
|
||||||
box->setFontName(mTextStyle.mFont);
|
|
||||||
box->setCaption(realText);
|
|
||||||
box->setSize(box->getSize().width, box->getTextSize().height);
|
|
||||||
mHeight += box->getTextSize().height;
|
|
||||||
|
|
||||||
if (tagStart != std::string::npos)
|
|
||||||
{
|
|
||||||
parseSubText(text.substr(tagStart, text.size()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,159 +5,165 @@
|
||||||
#include <MyGUI_ImageBox.h>
|
#include <MyGUI_ImageBox.h>
|
||||||
#include <MyGUI_ScrollBar.h>
|
#include <MyGUI_ScrollBar.h>
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
using namespace MWGui::Widgets;
|
|
||||||
|
|
||||||
MWList::MWList() :
|
|
||||||
mClient(0)
|
|
||||||
, mScrollView(0)
|
|
||||||
, mItemHeight(0)
|
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
void MWList::initialiseOverride()
|
namespace Widgets
|
||||||
{
|
|
||||||
Base::initialiseOverride();
|
|
||||||
|
|
||||||
assignWidget(mClient, "Client");
|
|
||||||
if (mClient == 0)
|
|
||||||
mClient = this;
|
|
||||||
|
|
||||||
mScrollView = mClient->createWidgetReal<MWGui::Widgets::MWScrollView>(
|
|
||||||
"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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWList::addSeparator()
|
|
||||||
{
|
|
||||||
mItems.push_back("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWList::adjustSize()
|
|
||||||
{
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWList::redraw(bool scrollbarShown)
|
|
||||||
{
|
|
||||||
const int _scrollBarWidth = 24; // fetch this from skin?
|
|
||||||
const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
|
|
||||||
const int spacing = 3;
|
|
||||||
size_t scrollbarPosition = mScrollView->getScrollPosition();
|
|
||||||
|
|
||||||
while (mScrollView->getChildCount())
|
|
||||||
{
|
{
|
||||||
MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
mItemHeight = 0;
|
MWList::MWList() :
|
||||||
int i=0;
|
mClient(0)
|
||||||
for (std::vector<std::string>::const_iterator it=mItems.begin();
|
, mScrollView(0)
|
||||||
it!=mItems.end(); ++it)
|
, mItemHeight(0)
|
||||||
{
|
|
||||||
if (*it != "")
|
|
||||||
{
|
{
|
||||||
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
|
|
||||||
"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));
|
|
||||||
button->setUserData(i);
|
|
||||||
|
|
||||||
mItemHeight += height + spacing;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
void MWList::initialiseOverride()
|
||||||
{
|
{
|
||||||
MyGUI::ImageBox* separator = mScrollView->createWidget<MyGUI::ImageBox>("MW_HLine",
|
Base::initialiseOverride();
|
||||||
MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth()-4, 18),
|
|
||||||
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
|
||||||
separator->setNeedMouseFocus(false);
|
|
||||||
|
|
||||||
mItemHeight += 18 + spacing;
|
assignWidget(mClient, "Client");
|
||||||
|
if (mClient == 0)
|
||||||
|
mClient = this;
|
||||||
|
|
||||||
|
mScrollView = mClient->createWidgetReal<MWGui::Widgets::MWScrollView>(
|
||||||
|
"MW_ScrollView", MyGUI::FloatCoord(0.0, 0.0, 1.0, 1.0),
|
||||||
|
MyGUI::Align::Top | MyGUI::Align::Left | MyGUI::Align::Stretch, getName() + "_ScrollView");
|
||||||
}
|
}
|
||||||
++i;
|
|
||||||
|
void MWList::addItem(const std::string& name)
|
||||||
|
{
|
||||||
|
mItems.push_back(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWList::addSeparator()
|
||||||
|
{
|
||||||
|
mItems.push_back("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWList::adjustSize()
|
||||||
|
{
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWList::redraw(bool scrollbarShown)
|
||||||
|
{
|
||||||
|
const int _scrollBarWidth = 24; // fetch this from skin?
|
||||||
|
const int scrollBarWidth = scrollbarShown ? _scrollBarWidth : 0;
|
||||||
|
const int spacing = 3;
|
||||||
|
size_t scrollbarPosition = mScrollView->getScrollPosition();
|
||||||
|
|
||||||
|
while (mScrollView->getChildCount())
|
||||||
|
{
|
||||||
|
MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
mItemHeight = 0;
|
||||||
|
int i=0;
|
||||||
|
for (std::vector<std::string>::const_iterator it=mItems.begin();
|
||||||
|
it!=mItems.end(); ++it)
|
||||||
|
{
|
||||||
|
if (*it != "")
|
||||||
|
{
|
||||||
|
MyGUI::Button* button = mScrollView->createWidget<MyGUI::Button>(
|
||||||
|
"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));
|
||||||
|
button->setUserData(i);
|
||||||
|
|
||||||
|
mItemHeight += height + spacing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MyGUI::ImageBox* separator = mScrollView->createWidget<MyGUI::ImageBox>("MW_HLine",
|
||||||
|
MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth()-4, 18),
|
||||||
|
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
|
||||||
|
separator->setNeedMouseFocus(false);
|
||||||
|
|
||||||
|
mItemHeight += 18 + spacing;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
mScrollView->setCanvasSize(mClient->getSize().width + (_scrollBarWidth-scrollBarWidth), std::max(mItemHeight, mClient->getSize().height));
|
||||||
|
|
||||||
|
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
|
||||||
|
redraw(true);
|
||||||
|
|
||||||
|
size_t scrollbarRange = mScrollView->getScrollRange();
|
||||||
|
if(scrollbarPosition > scrollbarRange)
|
||||||
|
scrollbarPosition = scrollbarRange;
|
||||||
|
mScrollView->setScrollPosition(scrollbarPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWList::clear()
|
||||||
|
{
|
||||||
|
mItems.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<MyGUI::Button*>(_sender)->getCaption();
|
||||||
|
int id = *_sender->getUserData<int>();
|
||||||
|
eventItemSelected(name, id);
|
||||||
|
eventWidgetSelected(_sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
MyGUI::Widget* MWList::getItemWidget(const std::string& name)
|
||||||
|
{
|
||||||
|
return mScrollView->findWidget (getName() + "_item_" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MWScrollView::getScrollPosition()
|
||||||
|
{
|
||||||
|
return getVScroll()->getScrollPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWScrollView::setScrollPosition(size_t position)
|
||||||
|
{
|
||||||
|
getVScroll()->setScrollPosition(position);
|
||||||
|
}
|
||||||
|
size_t MWScrollView::getScrollRange()
|
||||||
|
{
|
||||||
|
return getVScroll()->getScrollRange();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
mScrollView->setCanvasSize(mClient->getSize().width + (_scrollBarWidth-scrollBarWidth), std::max(mItemHeight, mClient->getSize().height));
|
|
||||||
|
|
||||||
if (!scrollbarShown && mItemHeight > mClient->getSize().height)
|
|
||||||
redraw(true);
|
|
||||||
|
|
||||||
size_t scrollbarRange = mScrollView->getScrollRange();
|
|
||||||
if(scrollbarPosition > scrollbarRange)
|
|
||||||
scrollbarPosition = scrollbarRange;
|
|
||||||
mScrollView->setScrollPosition(scrollbarPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWList::clear()
|
|
||||||
{
|
|
||||||
mItems.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<MyGUI::Button*>(_sender)->getCaption();
|
|
||||||
int id = *_sender->getUserData<int>();
|
|
||||||
eventItemSelected(name, id);
|
|
||||||
eventWidgetSelected(_sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
MyGUI::Widget* MWList::getItemWidget(const std::string& name)
|
|
||||||
{
|
|
||||||
return mScrollView->findWidget (getName() + "_item_" + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MWScrollView::getScrollPosition()
|
|
||||||
{
|
|
||||||
return getVScroll()->getScrollPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MWScrollView::setScrollPosition(size_t position)
|
|
||||||
{
|
|
||||||
getVScroll()->setScrollPosition(position);
|
|
||||||
}
|
|
||||||
size_t MWScrollView::getScrollRange()
|
|
||||||
{
|
|
||||||
return getVScroll()->getScrollRange();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,430 +13,433 @@
|
||||||
|
|
||||||
#include "widgets.hpp"
|
#include "widgets.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
|
|
||||||
LocalMapBase::LocalMapBase()
|
|
||||||
: mCurX(0)
|
|
||||||
, mCurY(0)
|
|
||||||
, mInterior(false)
|
|
||||||
, mFogOfWar(true)
|
|
||||||
, mLocalMap(NULL)
|
|
||||||
, mMapDragAndDrop(false)
|
|
||||||
, mPrefix()
|
|
||||||
, mChanged(true)
|
|
||||||
, mLayout(NULL)
|
|
||||||
, mLastPositionX(0.0f)
|
|
||||||
, mLastPositionY(0.0f)
|
|
||||||
, mLastDirectionX(0.0f)
|
|
||||||
, mLastDirectionY(0.0f)
|
|
||||||
, mCompass(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
|
LocalMapBase::LocalMapBase()
|
||||||
{
|
: mCurX(0)
|
||||||
mLocalMap = widget;
|
, mCurY(0)
|
||||||
mLayout = layout;
|
, mInterior(false)
|
||||||
mMapDragAndDrop = mapDragAndDrop;
|
, mFogOfWar(true)
|
||||||
mCompass = compass;
|
, mLocalMap(NULL)
|
||||||
|
, mMapDragAndDrop(false)
|
||||||
// create 3x3 map widgets, 512x512 each, holding a 1024x1024 texture each
|
, mPrefix()
|
||||||
const int widgetSize = 512;
|
, mChanged(true)
|
||||||
for (int mx=0; mx<3; ++mx)
|
, mLayout(NULL)
|
||||||
|
, mLastPositionX(0.0f)
|
||||||
|
, mLastPositionY(0.0f)
|
||||||
|
, mLastDirectionX(0.0f)
|
||||||
|
, mLastDirectionY(0.0f)
|
||||||
|
, mCompass(NULL)
|
||||||
{
|
{
|
||||||
for (int my=0; my<3; ++my)
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
|
||||||
|
{
|
||||||
|
mLocalMap = widget;
|
||||||
|
mLayout = layout;
|
||||||
|
mMapDragAndDrop = mapDragAndDrop;
|
||||||
|
mCompass = compass;
|
||||||
|
|
||||||
|
// create 3x3 map widgets, 512x512 each, holding a 1024x1024 texture each
|
||||||
|
const int widgetSize = 512;
|
||||||
|
for (int mx=0; mx<3; ++mx)
|
||||||
{
|
{
|
||||||
MyGUI::ImageBox* map = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
|
for (int my=0; my<3; ++my)
|
||||||
MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize),
|
|
||||||
MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my));
|
|
||||||
|
|
||||||
MyGUI::ImageBox* fog = map->createWidget<MyGUI::ImageBox>("ImageBox",
|
|
||||||
MyGUI::IntCoord(0, 0, widgetSize, widgetSize),
|
|
||||||
MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my) + "_fog");
|
|
||||||
|
|
||||||
if (!mMapDragAndDrop)
|
|
||||||
{
|
{
|
||||||
map->setNeedMouseFocus(false);
|
MyGUI::ImageBox* map = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||||
fog->setNeedMouseFocus(false);
|
MyGUI::IntCoord(mx*widgetSize, my*widgetSize, widgetSize, widgetSize),
|
||||||
}
|
MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my));
|
||||||
|
|
||||||
mMapWidgets.push_back(map);
|
MyGUI::ImageBox* fog = map->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||||
mFogWidgets.push_back(fog);
|
MyGUI::IntCoord(0, 0, widgetSize, widgetSize),
|
||||||
}
|
MyGUI::Align::Top | MyGUI::Align::Left, "Map_" + boost::lexical_cast<std::string>(mx) + "_" + boost::lexical_cast<std::string>(my) + "_fog");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::setCellPrefix(const std::string& prefix)
|
if (!mMapDragAndDrop)
|
||||||
{
|
|
||||||
mPrefix = prefix;
|
|
||||||
mChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::toggleFogOfWar()
|
|
||||||
{
|
|
||||||
mFogOfWar = !mFogOfWar;
|
|
||||||
applyFogOfWar();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::applyFogOfWar()
|
|
||||||
{
|
|
||||||
for (int mx=0; mx<3; ++mx)
|
|
||||||
{
|
|
||||||
for (int my=0; my<3; ++my)
|
|
||||||
{
|
|
||||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
|
||||||
+ boost::lexical_cast<std::string>(my);
|
|
||||||
|
|
||||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
|
|
||||||
+ boost::lexical_cast<std::string>(mCurY + (-1*(my-1)));
|
|
||||||
MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
|
|
||||||
fog->setImageTexture(mFogOfWar ?
|
|
||||||
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
|
||||||
: "black.png" )
|
|
||||||
: "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notifyMapChanged ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
|
|
||||||
{
|
|
||||||
applyFogOfWar ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::onMarkerUnfocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
|
|
||||||
{
|
|
||||||
applyFogOfWar ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
|
||||||
{
|
|
||||||
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
|
||||||
|
|
||||||
// clear all previous markers
|
|
||||||
for (unsigned int i=0; i< mLocalMap->getChildCount(); ++i)
|
|
||||||
{
|
|
||||||
if (mLocalMap->getChildAt(i)->getName ().substr (0, 6) == "Marker")
|
|
||||||
{
|
|
||||||
MyGUI::Gui::getInstance ().destroyWidget (mLocalMap->getChildAt(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int mx=0; mx<3; ++mx)
|
|
||||||
{
|
|
||||||
for (int my=0; my<3; ++my)
|
|
||||||
{
|
|
||||||
// map
|
|
||||||
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
|
|
||||||
+ boost::lexical_cast<std::string>(y + (-1*(my-1)));
|
|
||||||
|
|
||||||
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
|
||||||
+ boost::lexical_cast<std::string>(my);
|
|
||||||
|
|
||||||
MyGUI::ImageBox* box = mMapWidgets[my + 3*mx];
|
|
||||||
|
|
||||||
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
|
||||||
box->setImageTexture(image);
|
|
||||||
else
|
|
||||||
box->setImageTexture("black.png");
|
|
||||||
|
|
||||||
|
|
||||||
// door markers
|
|
||||||
|
|
||||||
// interior map only consists of one cell, so handle the markers only once
|
|
||||||
if (interior && (mx != 2 || my != 2))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MWWorld::CellStore* cell;
|
|
||||||
if (interior)
|
|
||||||
cell = MWBase::Environment::get().getWorld ()->getInterior (mPrefix);
|
|
||||||
else
|
|
||||||
cell = MWBase::Environment::get().getWorld ()->getExterior (x+mx-1, y-(my-1));
|
|
||||||
|
|
||||||
std::vector<MWBase::World::DoorMarker> doors = MWBase::Environment::get().getWorld ()->getDoorMarkers (cell);
|
|
||||||
|
|
||||||
for (std::vector<MWBase::World::DoorMarker>::iterator it = doors.begin(); it != doors.end(); ++it)
|
|
||||||
{
|
|
||||||
MWBase::World::DoorMarker marker = *it;
|
|
||||||
|
|
||||||
// convert world coordinates to normalized cell coordinates
|
|
||||||
MyGUI::IntCoord widgetCoord;
|
|
||||||
float nX,nY;
|
|
||||||
int cellDx, cellDy;
|
|
||||||
if (!interior)
|
|
||||||
{
|
{
|
||||||
const int cellSize = 8192;
|
map->setNeedMouseFocus(false);
|
||||||
|
fog->setNeedMouseFocus(false);
|
||||||
nX = (marker.x - cellSize * (x+mx-1)) / cellSize;
|
|
||||||
nY = 1 - (marker.y - cellSize * (y-(my-1))) / cellSize;
|
|
||||||
|
|
||||||
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + mx * 512, nY * 512 - 4 + my * 512, 8, 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mMapWidgets.push_back(map);
|
||||||
|
mFogWidgets.push_back(fog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::setCellPrefix(const std::string& prefix)
|
||||||
|
{
|
||||||
|
mPrefix = prefix;
|
||||||
|
mChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::toggleFogOfWar()
|
||||||
|
{
|
||||||
|
mFogOfWar = !mFogOfWar;
|
||||||
|
applyFogOfWar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::applyFogOfWar()
|
||||||
|
{
|
||||||
|
for (int mx=0; mx<3; ++mx)
|
||||||
|
{
|
||||||
|
for (int my=0; my<3; ++my)
|
||||||
|
{
|
||||||
|
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(my);
|
||||||
|
|
||||||
|
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(mCurY + (-1*(my-1)));
|
||||||
|
MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
|
||||||
|
fog->setImageTexture(mFogOfWar ?
|
||||||
|
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
||||||
|
: "black.png" )
|
||||||
|
: "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyMapChanged ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
|
||||||
|
{
|
||||||
|
applyFogOfWar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::onMarkerUnfocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
|
||||||
|
{
|
||||||
|
applyFogOfWar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
||||||
|
{
|
||||||
|
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
||||||
|
|
||||||
|
// clear all previous markers
|
||||||
|
for (unsigned int i=0; i< mLocalMap->getChildCount(); ++i)
|
||||||
|
{
|
||||||
|
if (mLocalMap->getChildAt(i)->getName ().substr (0, 6) == "Marker")
|
||||||
|
{
|
||||||
|
MyGUI::Gui::getInstance ().destroyWidget (mLocalMap->getChildAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int mx=0; mx<3; ++mx)
|
||||||
|
{
|
||||||
|
for (int my=0; my<3; ++my)
|
||||||
|
{
|
||||||
|
// map
|
||||||
|
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(y + (-1*(my-1)));
|
||||||
|
|
||||||
|
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(my);
|
||||||
|
|
||||||
|
MyGUI::ImageBox* box = mMapWidgets[my + 3*mx];
|
||||||
|
|
||||||
|
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
||||||
|
box->setImageTexture(image);
|
||||||
else
|
else
|
||||||
{
|
box->setImageTexture("black.png");
|
||||||
Ogre::Vector2 position (marker.x, marker.y);
|
|
||||||
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
|
|
||||||
|
|
||||||
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8);
|
|
||||||
|
// door markers
|
||||||
|
|
||||||
|
// interior map only consists of one cell, so handle the markers only once
|
||||||
|
if (interior && (mx != 2 || my != 2))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MWWorld::CellStore* cell;
|
||||||
|
if (interior)
|
||||||
|
cell = MWBase::Environment::get().getWorld ()->getInterior (mPrefix);
|
||||||
|
else
|
||||||
|
cell = MWBase::Environment::get().getWorld ()->getExterior (x+mx-1, y-(my-1));
|
||||||
|
|
||||||
|
std::vector<MWBase::World::DoorMarker> doors = MWBase::Environment::get().getWorld ()->getDoorMarkers (cell);
|
||||||
|
|
||||||
|
for (std::vector<MWBase::World::DoorMarker>::iterator it = doors.begin(); it != doors.end(); ++it)
|
||||||
|
{
|
||||||
|
MWBase::World::DoorMarker marker = *it;
|
||||||
|
|
||||||
|
// convert world coordinates to normalized cell coordinates
|
||||||
|
MyGUI::IntCoord widgetCoord;
|
||||||
|
float nX,nY;
|
||||||
|
int cellDx, cellDy;
|
||||||
|
if (!interior)
|
||||||
|
{
|
||||||
|
const int cellSize = 8192;
|
||||||
|
|
||||||
|
nX = (marker.x - cellSize * (x+mx-1)) / cellSize;
|
||||||
|
nY = 1 - (marker.y - cellSize * (y-(my-1))) / cellSize;
|
||||||
|
|
||||||
|
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + mx * 512, nY * 512 - 4 + my * 512, 8, 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ogre::Vector2 position (marker.x, marker.y);
|
||||||
|
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
|
||||||
|
|
||||||
|
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int counter = 0;
|
||||||
|
++counter;
|
||||||
|
MyGUI::Button* markerWidget = mLocalMap->createWidget<MyGUI::Button>("ButtonImage",
|
||||||
|
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(counter));
|
||||||
|
markerWidget->setImageResource("DoorMarker");
|
||||||
|
markerWidget->setUserString("ToolTipType", "Layout");
|
||||||
|
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
||||||
|
markerWidget->setUserString("Caption_TextOneLine", marker.name);
|
||||||
|
markerWidget->setUserString("IsMarker", "true");
|
||||||
|
markerWidget->eventMouseSetFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerFocused);
|
||||||
|
markerWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerUnfocused);
|
||||||
|
|
||||||
|
MarkerPosition markerPos;
|
||||||
|
markerPos.interior = interior;
|
||||||
|
markerPos.cellX = interior ? cellDx : x + mx - 1;
|
||||||
|
markerPos.cellY = interior ? cellDy : y + ((my - 1)*-1);
|
||||||
|
markerPos.nX = nX;
|
||||||
|
markerPos.nY = nY;
|
||||||
|
|
||||||
|
markerWidget->setUserData(markerPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int counter = 0;
|
|
||||||
++counter;
|
|
||||||
MyGUI::Button* markerWidget = mLocalMap->createWidget<MyGUI::Button>("ButtonImage",
|
|
||||||
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(counter));
|
|
||||||
markerWidget->setImageResource("DoorMarker");
|
|
||||||
markerWidget->setUserString("ToolTipType", "Layout");
|
|
||||||
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
|
||||||
markerWidget->setUserString("Caption_TextOneLine", marker.name);
|
|
||||||
markerWidget->setUserString("IsMarker", "true");
|
|
||||||
markerWidget->eventMouseSetFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerFocused);
|
|
||||||
markerWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &LocalMapBase::onMarkerUnfocused);
|
|
||||||
|
|
||||||
MarkerPosition markerPos;
|
|
||||||
markerPos.interior = interior;
|
|
||||||
markerPos.cellX = interior ? cellDx : x + mx - 1;
|
|
||||||
markerPos.cellY = interior ? cellDy : y + ((my - 1)*-1);
|
|
||||||
markerPos.nX = nX;
|
|
||||||
markerPos.nY = nY;
|
|
||||||
|
|
||||||
markerWidget->setUserData(markerPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
mInterior = interior;
|
||||||
mInterior = interior;
|
mCurX = x;
|
||||||
mCurX = x;
|
mCurY = y;
|
||||||
mCurY = y;
|
mChanged = false;
|
||||||
mChanged = false;
|
|
||||||
|
|
||||||
// fog of war
|
// fog of war
|
||||||
applyFogOfWar();
|
applyFogOfWar();
|
||||||
|
|
||||||
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets
|
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets
|
||||||
// based on the last setImageTexture call
|
// based on the last setImageTexture call
|
||||||
std::string tex = "textures\\compass.dds";
|
std::string tex = "textures\\compass.dds";
|
||||||
mCompass->setImageTexture("");
|
mCompass->setImageTexture("");
|
||||||
mCompass->setImageTexture(tex);
|
mCompass->setImageTexture(tex);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LocalMapBase::setPlayerPos(const float x, const float y)
|
|
||||||
{
|
|
||||||
if (x == mLastPositionX && y == mLastPositionY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
notifyPlayerUpdate ();
|
|
||||||
|
|
||||||
MyGUI::IntSize size = mLocalMap->getCanvasSize();
|
|
||||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
|
||||||
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
|
|
||||||
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
|
||||||
mLocalMap->setViewOffset(pos);
|
|
||||||
|
|
||||||
mCompass->setPosition(MyGUI::IntPoint(512+x*512-16, 512+y*512-16));
|
|
||||||
mLastPositionX = x;
|
|
||||||
mLastPositionY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalMapBase::setPlayerDir(const float x, const float y)
|
|
||||||
{
|
|
||||||
if (x == mLastDirectionX && y == mLastDirectionY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
notifyPlayerUpdate ();
|
|
||||||
|
|
||||||
MyGUI::ISubWidget* main = mCompass->getSubWidgetMain();
|
|
||||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
|
||||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
|
||||||
float angle = std::atan2(x,y);
|
|
||||||
rotatingSubskin->setAngle(angle);
|
|
||||||
|
|
||||||
mLastDirectionX = x;
|
|
||||||
mLastDirectionY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
MapWindow::MapWindow(const std::string& cacheDir)
|
|
||||||
: MWGui::WindowPinnableBase("openmw_map_window.layout")
|
|
||||||
, mGlobal(false)
|
|
||||||
{
|
|
||||||
setCoord(500,0,320,300);
|
|
||||||
|
|
||||||
mGlobalMapRender = new MWRender::GlobalMap(cacheDir);
|
|
||||||
mGlobalMapRender->render();
|
|
||||||
|
|
||||||
getWidget(mLocalMap, "LocalMap");
|
|
||||||
getWidget(mGlobalMap, "GlobalMap");
|
|
||||||
getWidget(mGlobalMapImage, "GlobalMapImage");
|
|
||||||
getWidget(mGlobalMapOverlay, "GlobalMapOverlay");
|
|
||||||
getWidget(mPlayerArrowLocal, "CompassLocal");
|
|
||||||
getWidget(mPlayerArrowGlobal, "CompassGlobal");
|
|
||||||
|
|
||||||
mGlobalMapImage->setImageTexture("GlobalMap.png");
|
|
||||||
mGlobalMapOverlay->setImageTexture("GlobalMapOverlay");
|
|
||||||
|
|
||||||
mGlobalMap->setVisible (false);
|
|
||||||
|
|
||||||
getWidget(mButton, "WorldButton");
|
|
||||||
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
|
||||||
mButton->setCaptionWithReplacing("#{sWorld}");
|
|
||||||
|
|
||||||
getWidget(mEventBoxGlobal, "EventBoxGlobal");
|
|
||||||
mEventBoxGlobal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
|
||||||
mEventBoxGlobal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
|
||||||
getWidget(mEventBoxLocal, "EventBoxLocal");
|
|
||||||
mEventBoxLocal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
|
||||||
mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
|
||||||
|
|
||||||
LocalMapBase::init(mLocalMap, mPlayerArrowLocal, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
MapWindow::~MapWindow()
|
|
||||||
{
|
|
||||||
delete mGlobalMapRender;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::setCellName(const std::string& cellName)
|
|
||||||
{
|
|
||||||
setTitle("#{sCell=" + cellName + "}");
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
|
|
||||||
{
|
|
||||||
float worldX, worldY;
|
|
||||||
mGlobalMapRender->cellTopLeftCornerToImageSpace (x, y, worldX, worldY);
|
|
||||||
|
|
||||||
MyGUI::IntCoord widgetCoord(
|
|
||||||
worldX * mGlobalMapRender->getWidth()+6,
|
|
||||||
worldY * mGlobalMapRender->getHeight()+6,
|
|
||||||
12, 12);
|
|
||||||
|
|
||||||
|
|
||||||
static int _counter=0;
|
|
||||||
MyGUI::Button* markerWidget = mGlobalMapImage->createWidget<MyGUI::Button>("ButtonImage",
|
|
||||||
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(_counter));
|
|
||||||
markerWidget->setImageResource("DoorMarker");
|
|
||||||
markerWidget->setUserString("ToolTipType", "Layout");
|
|
||||||
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
|
||||||
markerWidget->setUserString("Caption_TextOneLine", name);
|
|
||||||
++_counter;
|
|
||||||
|
|
||||||
markerWidget = mEventBoxGlobal->createWidget<MyGUI::Button>("",
|
|
||||||
widgetCoord, MyGUI::Align::Default);
|
|
||||||
markerWidget->setNeedMouseFocus (true);
|
|
||||||
markerWidget->setUserString("ToolTipType", "Layout");
|
|
||||||
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
|
||||||
markerWidget->setUserString("Caption_TextOneLine", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::cellExplored(int x, int y)
|
|
||||||
{
|
|
||||||
mGlobalMapRender->exploreCell(x,y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
|
||||||
{
|
|
||||||
if (_id!=MyGUI::MouseButton::Left) return;
|
|
||||||
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
|
||||||
{
|
|
||||||
if (_id!=MyGUI::MouseButton::Left) return;
|
|
||||||
|
|
||||||
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
|
|
||||||
|
|
||||||
if (!mGlobal)
|
|
||||||
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
|
|
||||||
else
|
|
||||||
mGlobalMap->setViewOffset( mGlobalMap->getViewOffset() + diff );
|
|
||||||
|
|
||||||
|
|
||||||
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
mGlobal = !mGlobal;
|
|
||||||
mGlobalMap->setVisible(mGlobal);
|
|
||||||
mLocalMap->setVisible(!mGlobal);
|
|
||||||
|
|
||||||
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
|
|
||||||
"#{sWorld}");
|
|
||||||
|
|
||||||
if (mGlobal)
|
|
||||||
globalMapUpdatePlayer ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onPinToggled()
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->setMinimapVisibility(!mPinned);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::open()
|
|
||||||
{
|
|
||||||
mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
|
|
||||||
mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<mGlobalMapImage->getChildCount (); ++i)
|
|
||||||
{
|
|
||||||
if (mGlobalMapImage->getChildAt (i)->getName().substr(0,6) == "Marker")
|
|
||||||
mGlobalMapImage->getChildAt (i)->castType<MyGUI::Button>()->setImageResource("DoorMarker");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
globalMapUpdatePlayer();
|
|
||||||
|
|
||||||
mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds");
|
void LocalMapBase::setPlayerPos(const float x, const float y)
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::globalMapUpdatePlayer ()
|
|
||||||
{
|
|
||||||
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
|
|
||||||
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
|
|
||||||
Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
|
|
||||||
|
|
||||||
float worldX, worldY;
|
|
||||||
mGlobalMapRender->worldPosToImageSpace (pos.x, pos.y, worldX, worldY);
|
|
||||||
worldX *= mGlobalMapRender->getWidth();
|
|
||||||
worldY *= mGlobalMapRender->getHeight();
|
|
||||||
|
|
||||||
|
|
||||||
// for interiors, we have no choice other than using the last position & direction.
|
|
||||||
/// \todo save this last position in the savegame?
|
|
||||||
if (MWBase::Environment::get().getWorld ()->isCellExterior ())
|
|
||||||
{
|
{
|
||||||
mPlayerArrowGlobal->setPosition(MyGUI::IntPoint(worldX - 16, worldY - 16));
|
if (x == mLastPositionX && y == mLastPositionY)
|
||||||
|
return;
|
||||||
|
|
||||||
MyGUI::ISubWidget* main = mPlayerArrowGlobal->getSubWidgetMain();
|
notifyPlayerUpdate ();
|
||||||
|
|
||||||
|
MyGUI::IntSize size = mLocalMap->getCanvasSize();
|
||||||
|
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||||
|
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
|
||||||
|
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
||||||
|
mLocalMap->setViewOffset(pos);
|
||||||
|
|
||||||
|
mCompass->setPosition(MyGUI::IntPoint(512+x*512-16, 512+y*512-16));
|
||||||
|
mLastPositionX = x;
|
||||||
|
mLastPositionY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::setPlayerDir(const float x, const float y)
|
||||||
|
{
|
||||||
|
if (x == mLastDirectionX && y == mLastDirectionY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
notifyPlayerUpdate ();
|
||||||
|
|
||||||
|
MyGUI::ISubWidget* main = mCompass->getSubWidgetMain();
|
||||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||||
float angle = std::atan2(dir.x, dir.y);
|
float angle = std::atan2(x,y);
|
||||||
rotatingSubskin->setAngle(angle);
|
rotatingSubskin->setAngle(angle);
|
||||||
|
|
||||||
// set the view offset so that player is in the center
|
mLastDirectionX = x;
|
||||||
MyGUI::IntSize viewsize = mGlobalMap->getSize();
|
mLastDirectionY = y;
|
||||||
MyGUI::IntPoint viewoffs(0.5*viewsize.width - worldX, 0.5*viewsize.height - worldY);
|
|
||||||
mGlobalMap->setViewOffset(viewoffs);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::notifyPlayerUpdate ()
|
// ------------------------------------------------------------------------------------------
|
||||||
{
|
|
||||||
globalMapUpdatePlayer ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::notifyMapChanged ()
|
MapWindow::MapWindow(const std::string& cacheDir)
|
||||||
{
|
: MWGui::WindowPinnableBase("openmw_map_window.layout")
|
||||||
// workaround to prevent the map from drawing on top of the button
|
, mGlobal(false)
|
||||||
MyGUI::IntCoord oldCoord = mButton->getCoord ();
|
{
|
||||||
MyGUI::Gui::getInstance().destroyWidget (mButton);
|
setCoord(500,0,320,300);
|
||||||
mButton = mMainWidget->createWidget<MWGui::Widgets::AutoSizedButton>("MW_Button",
|
|
||||||
oldCoord, MyGUI::Align::Bottom | MyGUI::Align::Right);
|
mGlobalMapRender = new MWRender::GlobalMap(cacheDir);
|
||||||
mButton->setProperty ("ExpandDirection", "Left");
|
mGlobalMapRender->render();
|
||||||
|
|
||||||
|
getWidget(mLocalMap, "LocalMap");
|
||||||
|
getWidget(mGlobalMap, "GlobalMap");
|
||||||
|
getWidget(mGlobalMapImage, "GlobalMapImage");
|
||||||
|
getWidget(mGlobalMapOverlay, "GlobalMapOverlay");
|
||||||
|
getWidget(mPlayerArrowLocal, "CompassLocal");
|
||||||
|
getWidget(mPlayerArrowGlobal, "CompassGlobal");
|
||||||
|
|
||||||
|
mGlobalMapImage->setImageTexture("GlobalMap.png");
|
||||||
|
mGlobalMapOverlay->setImageTexture("GlobalMapOverlay");
|
||||||
|
|
||||||
|
mGlobalMap->setVisible (false);
|
||||||
|
|
||||||
|
getWidget(mButton, "WorldButton");
|
||||||
|
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
||||||
|
mButton->setCaptionWithReplacing("#{sWorld}");
|
||||||
|
|
||||||
|
getWidget(mEventBoxGlobal, "EventBoxGlobal");
|
||||||
|
mEventBoxGlobal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||||
|
mEventBoxGlobal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||||
|
getWidget(mEventBoxLocal, "EventBoxLocal");
|
||||||
|
mEventBoxLocal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||||
|
mEventBoxLocal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||||
|
|
||||||
|
LocalMapBase::init(mLocalMap, mPlayerArrowLocal, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWindow::~MapWindow()
|
||||||
|
{
|
||||||
|
delete mGlobalMapRender;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::setCellName(const std::string& cellName)
|
||||||
|
{
|
||||||
|
setTitle("#{sCell=" + cellName + "}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::addVisitedLocation(const std::string& name, int x, int y)
|
||||||
|
{
|
||||||
|
float worldX, worldY;
|
||||||
|
mGlobalMapRender->cellTopLeftCornerToImageSpace (x, y, worldX, worldY);
|
||||||
|
|
||||||
|
MyGUI::IntCoord widgetCoord(
|
||||||
|
worldX * mGlobalMapRender->getWidth()+6,
|
||||||
|
worldY * mGlobalMapRender->getHeight()+6,
|
||||||
|
12, 12);
|
||||||
|
|
||||||
|
|
||||||
|
static int _counter=0;
|
||||||
|
MyGUI::Button* markerWidget = mGlobalMapImage->createWidget<MyGUI::Button>("ButtonImage",
|
||||||
|
widgetCoord, MyGUI::Align::Default, "Marker" + boost::lexical_cast<std::string>(_counter));
|
||||||
|
markerWidget->setImageResource("DoorMarker");
|
||||||
|
markerWidget->setUserString("ToolTipType", "Layout");
|
||||||
|
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
||||||
|
markerWidget->setUserString("Caption_TextOneLine", name);
|
||||||
|
++_counter;
|
||||||
|
|
||||||
|
markerWidget = mEventBoxGlobal->createWidget<MyGUI::Button>("",
|
||||||
|
widgetCoord, MyGUI::Align::Default);
|
||||||
|
markerWidget->setNeedMouseFocus (true);
|
||||||
|
markerWidget->setUserString("ToolTipType", "Layout");
|
||||||
|
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
|
||||||
|
markerWidget->setUserString("Caption_TextOneLine", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::cellExplored(int x, int y)
|
||||||
|
{
|
||||||
|
mGlobalMapRender->exploreCell(x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||||
|
{
|
||||||
|
if (_id!=MyGUI::MouseButton::Left) return;
|
||||||
|
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||||
|
{
|
||||||
|
if (_id!=MyGUI::MouseButton::Left) return;
|
||||||
|
|
||||||
|
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
|
||||||
|
|
||||||
|
if (!mGlobal)
|
||||||
|
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
|
||||||
|
else
|
||||||
|
mGlobalMap->setViewOffset( mGlobalMap->getViewOffset() + diff );
|
||||||
|
|
||||||
|
|
||||||
|
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
mGlobal = !mGlobal;
|
||||||
|
mGlobalMap->setVisible(mGlobal);
|
||||||
|
mLocalMap->setVisible(!mGlobal);
|
||||||
|
|
||||||
|
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
|
||||||
|
"#{sWorld}");
|
||||||
|
|
||||||
|
if (mGlobal)
|
||||||
|
globalMapUpdatePlayer ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onPinToggled()
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->setMinimapVisibility(!mPinned);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::open()
|
||||||
|
{
|
||||||
|
mGlobalMap->setCanvasSize (mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
|
||||||
|
mGlobalMapImage->setSize(mGlobalMapRender->getWidth(), mGlobalMapRender->getHeight());
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<mGlobalMapImage->getChildCount (); ++i)
|
||||||
|
{
|
||||||
|
if (mGlobalMapImage->getChildAt (i)->getName().substr(0,6) == "Marker")
|
||||||
|
mGlobalMapImage->getChildAt (i)->castType<MyGUI::Button>()->setImageResource("DoorMarker");
|
||||||
|
}
|
||||||
|
|
||||||
|
globalMapUpdatePlayer();
|
||||||
|
|
||||||
|
mPlayerArrowGlobal->setImageTexture ("textures\\compass.dds");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::globalMapUpdatePlayer ()
|
||||||
|
{
|
||||||
|
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
|
||||||
|
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
|
||||||
|
Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
|
||||||
|
|
||||||
|
float worldX, worldY;
|
||||||
|
mGlobalMapRender->worldPosToImageSpace (pos.x, pos.y, worldX, worldY);
|
||||||
|
worldX *= mGlobalMapRender->getWidth();
|
||||||
|
worldY *= mGlobalMapRender->getHeight();
|
||||||
|
|
||||||
|
|
||||||
|
// for interiors, we have no choice other than using the last position & direction.
|
||||||
|
/// \todo save this last position in the savegame?
|
||||||
|
if (MWBase::Environment::get().getWorld ()->isCellExterior ())
|
||||||
|
{
|
||||||
|
mPlayerArrowGlobal->setPosition(MyGUI::IntPoint(worldX - 16, worldY - 16));
|
||||||
|
|
||||||
|
MyGUI::ISubWidget* main = mPlayerArrowGlobal->getSubWidgetMain();
|
||||||
|
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||||
|
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||||
|
float angle = std::atan2(dir.x, dir.y);
|
||||||
|
rotatingSubskin->setAngle(angle);
|
||||||
|
|
||||||
|
// set the view offset so that player is in the center
|
||||||
|
MyGUI::IntSize viewsize = mGlobalMap->getSize();
|
||||||
|
MyGUI::IntPoint viewoffs(0.5*viewsize.width - worldX, 0.5*viewsize.height - worldY);
|
||||||
|
mGlobalMap->setViewOffset(viewoffs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::notifyPlayerUpdate ()
|
||||||
|
{
|
||||||
|
globalMapUpdatePlayer ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::notifyMapChanged ()
|
||||||
|
{
|
||||||
|
// workaround to prevent the map from drawing on top of the button
|
||||||
|
MyGUI::IntCoord oldCoord = mButton->getCoord ();
|
||||||
|
MyGUI::Gui::getInstance().destroyWidget (mButton);
|
||||||
|
mButton = mMainWidget->createWidget<MWGui::Widgets::AutoSizedButton>("MW_Button",
|
||||||
|
oldCoord, MyGUI::Align::Bottom | MyGUI::Align::Right);
|
||||||
|
mButton->setProperty ("ExpandDirection", "Left");
|
||||||
|
|
||||||
|
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
||||||
|
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
|
||||||
|
"#{sWorld}");
|
||||||
|
}
|
||||||
|
|
||||||
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
|
||||||
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
|
|
||||||
"#{sWorld}");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,411 +5,414 @@
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/inputmanager.hpp"
|
#include "../mwbase/inputmanager.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
|
|
||||||
MessageBoxManager::MessageBoxManager ()
|
|
||||||
{
|
{
|
||||||
// defines
|
|
||||||
mMessageBoxSpeed = 0.1;
|
|
||||||
mInterMessageBoxe = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageBoxManager::onFrame (float frameDuration)
|
MessageBoxManager::MessageBoxManager ()
|
||||||
{
|
|
||||||
std::vector<MessageBoxManagerTimer>::iterator it;
|
|
||||||
for(it = mTimers.begin(); it != mTimers.end();)
|
|
||||||
{
|
{
|
||||||
// if this messagebox is already deleted, remove the timer and move on
|
// defines
|
||||||
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
|
mMessageBoxSpeed = 0.1;
|
||||||
{
|
mInterMessageBoxe = NULL;
|
||||||
it = mTimers.erase(it);
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
it->current += frameDuration;
|
void MessageBoxManager::onFrame (float frameDuration)
|
||||||
if(it->current >= it->max)
|
{
|
||||||
|
std::vector<MessageBoxManagerTimer>::iterator it;
|
||||||
|
for(it = mTimers.begin(); it != mTimers.end();)
|
||||||
{
|
{
|
||||||
it->messageBox->mMarkedToDelete = true;
|
// if this messagebox is already deleted, remove the timer and move on
|
||||||
|
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
|
||||||
if(*mMessageBoxes.begin() == it->messageBox) // if this box is the last one
|
|
||||||
{
|
{
|
||||||
// collect all with mMarkedToDelete and delete them.
|
it = mTimers.erase(it);
|
||||||
// and place the other messageboxes on the right position
|
continue;
|
||||||
int height = 0;
|
}
|
||||||
std::vector<MessageBox*>::iterator it2 = mMessageBoxes.begin();
|
|
||||||
while(it2 != mMessageBoxes.end())
|
it->current += frameDuration;
|
||||||
|
if(it->current >= it->max)
|
||||||
|
{
|
||||||
|
it->messageBox->mMarkedToDelete = true;
|
||||||
|
|
||||||
|
if(*mMessageBoxes.begin() == it->messageBox) // if this box is the last one
|
||||||
{
|
{
|
||||||
if((*it2)->mMarkedToDelete)
|
// collect all with mMarkedToDelete and delete them.
|
||||||
|
// and place the other messageboxes on the right position
|
||||||
|
int height = 0;
|
||||||
|
std::vector<MessageBox*>::iterator it2 = mMessageBoxes.begin();
|
||||||
|
while(it2 != mMessageBoxes.end())
|
||||||
{
|
{
|
||||||
delete (*it2);
|
if((*it2)->mMarkedToDelete)
|
||||||
it2 = mMessageBoxes.erase(it2);
|
{
|
||||||
}
|
delete (*it2);
|
||||||
else {
|
it2 = mMessageBoxes.erase(it2);
|
||||||
(*it2)->update(height);
|
}
|
||||||
height += (*it2)->getHeight();
|
else {
|
||||||
it2++;
|
(*it2)->update(height);
|
||||||
|
height += (*it2)->getHeight();
|
||||||
|
it2++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
it = mTimers.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
||||||
|
delete mInterMessageBoxe;
|
||||||
|
mInterMessageBoxe = NULL;
|
||||||
|
MWBase::Environment::get().getInputManager()->changeInputMode(
|
||||||
|
MWBase::Environment::get().getWindowManager()->isGuiMode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBoxManager::createMessageBox (const std::string& message)
|
||||||
|
{
|
||||||
|
MessageBox *box = new MessageBox(*this, message);
|
||||||
|
|
||||||
|
removeMessageBox(message.length()*mMessageBoxSpeed, box);
|
||||||
|
|
||||||
|
mMessageBoxes.push_back(box);
|
||||||
|
std::vector<MessageBox*>::iterator it;
|
||||||
|
|
||||||
|
if(mMessageBoxes.size() > 3) {
|
||||||
|
delete *mMessageBoxes.begin();
|
||||||
|
mMessageBoxes.erase(mMessageBoxes.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
int height = 0;
|
||||||
|
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->update(height);
|
||||||
|
height += (*it)->getHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
|
||||||
|
{
|
||||||
|
if(mInterMessageBoxe != NULL) {
|
||||||
|
throw std::runtime_error("There is a message box already");
|
||||||
|
}
|
||||||
|
|
||||||
|
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageBoxManager::isInteractiveMessageBox ()
|
||||||
|
{
|
||||||
|
return mInterMessageBoxe != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox)
|
||||||
|
{
|
||||||
|
MessageBoxManagerTimer timer;
|
||||||
|
timer.current = 0;
|
||||||
|
timer.max = time;
|
||||||
|
timer.messageBox = msgbox;
|
||||||
|
|
||||||
|
mTimers.insert(mTimers.end(), timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
|
||||||
|
{
|
||||||
|
std::vector<MessageBox*>::iterator it;
|
||||||
|
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
|
||||||
|
{
|
||||||
|
if((*it) == msgbox)
|
||||||
|
{
|
||||||
|
delete (*it);
|
||||||
|
mMessageBoxes.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBoxManager::setMessageBoxSpeed (int speed)
|
||||||
|
{
|
||||||
|
mMessageBoxSpeed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBoxManager::enterPressed ()
|
||||||
|
{
|
||||||
|
if(mInterMessageBoxe != NULL)
|
||||||
|
mInterMessageBoxe->enterPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MessageBoxManager::readPressedButton ()
|
||||||
|
{
|
||||||
|
if(mInterMessageBoxe != NULL)
|
||||||
|
{
|
||||||
|
return mInterMessageBoxe->readPressedButton();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
|
||||||
|
: Layout("openmw_messagebox.layout")
|
||||||
|
, mMessageBoxManager(parMessageBoxManager)
|
||||||
|
, mMessage(message)
|
||||||
|
{
|
||||||
|
// defines
|
||||||
|
mFixedWidth = 300;
|
||||||
|
mBottomPadding = 20;
|
||||||
|
mNextBoxPadding = 20;
|
||||||
|
mMarkedToDelete = false;
|
||||||
|
|
||||||
|
getWidget(mMessageWidget, "message");
|
||||||
|
|
||||||
|
mMessageWidget->setOverflowToTheLeft(true);
|
||||||
|
mMessageWidget->setCaptionWithReplacing(mMessage);
|
||||||
|
|
||||||
|
MyGUI::IntSize size;
|
||||||
|
size.width = mFixedWidth;
|
||||||
|
size.height = 100; // dummy
|
||||||
|
|
||||||
|
MyGUI::IntCoord coord;
|
||||||
|
coord.left = 10; // dummy
|
||||||
|
coord.top = 10; // dummy
|
||||||
|
|
||||||
|
mMessageWidget->setSize(size);
|
||||||
|
|
||||||
|
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
|
||||||
|
|
||||||
|
size.height = mHeight = textSize.height + 20; // this is the padding between the text and the box
|
||||||
|
|
||||||
|
mMainWidget->setSize(size);
|
||||||
|
size.width -= 15; // this is to center the text (see messagebox.layout, Widget type="Edit" position="-2 -3 0 0")
|
||||||
|
mMessageWidget->setSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBox::update (int height)
|
||||||
|
{
|
||||||
|
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||||
|
MyGUI::IntCoord coord;
|
||||||
|
coord.left = (gameWindowSize.width - mFixedWidth)/2;
|
||||||
|
coord.top = (gameWindowSize.height - mHeight - height - mBottomPadding);
|
||||||
|
|
||||||
|
MyGUI::IntSize size;
|
||||||
|
size.width = mFixedWidth;
|
||||||
|
size.height = mHeight;
|
||||||
|
|
||||||
|
mMainWidget->setCoord(coord);
|
||||||
|
mMainWidget->setSize(size);
|
||||||
|
mMainWidget->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MessageBox::getHeight ()
|
||||||
|
{
|
||||||
|
return mHeight+mNextBoxPadding; // 20 is the padding between this and the next MessageBox
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
|
||||||
|
: WindowModal("openmw_interactive_messagebox.layout")
|
||||||
|
, mMessageBoxManager(parMessageBoxManager)
|
||||||
|
, mButtonPressed(-1)
|
||||||
|
{
|
||||||
|
WindowModal::open();
|
||||||
|
|
||||||
|
int fixedWidth = 500;
|
||||||
|
int textPadding = 10; // padding between text-widget and main-widget
|
||||||
|
int textButtonPadding = 20; // padding between the text-widget und the button-widget
|
||||||
|
int buttonLeftPadding = 10; // padding between the buttons if horizontal
|
||||||
|
int buttonTopPadding = 5; // ^-- if vertical
|
||||||
|
int buttonPadding = 5; // padding between button label and button itself
|
||||||
|
int buttonMainPadding = 10; // padding between buttons and bottom of the main widget
|
||||||
|
|
||||||
|
mMarkedToDelete = false;
|
||||||
|
|
||||||
|
|
||||||
|
getWidget(mMessageWidget, "message");
|
||||||
|
getWidget(mButtonsWidget, "buttons");
|
||||||
|
|
||||||
|
mMessageWidget->setOverflowToTheLeft(true);
|
||||||
|
mMessageWidget->setCaptionWithReplacing(message);
|
||||||
|
|
||||||
|
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
|
||||||
|
|
||||||
|
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||||
|
|
||||||
|
int biggestButtonWidth = 0;
|
||||||
|
int buttonWidth = 0;
|
||||||
|
int buttonsWidth = 0;
|
||||||
|
int buttonHeight = 0;
|
||||||
|
MyGUI::IntCoord dummyCoord(0, 0, 0, 0);
|
||||||
|
|
||||||
|
std::vector<std::string>::const_iterator it;
|
||||||
|
for(it = buttons.begin(); it != buttons.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::Button* button = mButtonsWidget->createWidget<MyGUI::Button>(
|
||||||
|
MyGUI::WidgetStyle::Child,
|
||||||
|
std::string("MW_Button"),
|
||||||
|
dummyCoord,
|
||||||
|
MyGUI::Align::Default);
|
||||||
|
button->setCaptionWithReplacing(*it);
|
||||||
|
|
||||||
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed);
|
||||||
|
|
||||||
|
mButtons.push_back(button);
|
||||||
|
|
||||||
|
buttonWidth = button->getTextSize().width + 2*buttonPadding + buttonLeftPadding;
|
||||||
|
buttonsWidth += buttonWidth;
|
||||||
|
buttonHeight = button->getTextSize().height + 2*buttonPadding + buttonTopPadding;
|
||||||
|
|
||||||
|
if(buttonWidth > biggestButtonWidth)
|
||||||
|
{
|
||||||
|
biggestButtonWidth = buttonWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buttonsWidth += buttonLeftPadding;
|
||||||
|
|
||||||
|
MyGUI::IntSize mainWidgetSize;
|
||||||
|
if(buttonsWidth < fixedWidth)
|
||||||
|
{
|
||||||
|
// on one line
|
||||||
|
if(textSize.width + 2*textPadding < buttonsWidth)
|
||||||
|
{
|
||||||
|
mainWidgetSize.width = buttonsWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mainWidgetSize.width = textSize.width + 3*textPadding;
|
||||||
|
}
|
||||||
|
mainWidgetSize.height = textSize.height + textButtonPadding + buttonHeight + buttonMainPadding;
|
||||||
|
|
||||||
|
MyGUI::IntCoord absCoord;
|
||||||
|
absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2;
|
||||||
|
absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2;
|
||||||
|
|
||||||
|
mMainWidget->setCoord(absCoord);
|
||||||
|
mMainWidget->setSize(mainWidgetSize);
|
||||||
|
|
||||||
|
MyGUI::IntCoord messageWidgetCoord;
|
||||||
|
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
|
||||||
|
messageWidgetCoord.top = textPadding;
|
||||||
|
mMessageWidget->setCoord(messageWidgetCoord);
|
||||||
|
|
||||||
|
mMessageWidget->setSize(textSize);
|
||||||
|
|
||||||
|
MyGUI::IntCoord buttonCord;
|
||||||
|
MyGUI::IntSize buttonSize(0, buttonHeight);
|
||||||
|
int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding;
|
||||||
|
|
||||||
|
std::vector<MyGUI::Button*>::const_iterator button;
|
||||||
|
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
||||||
|
{
|
||||||
|
buttonCord.left = left;
|
||||||
|
buttonCord.top = textSize.height + textButtonPadding;
|
||||||
|
|
||||||
|
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
|
||||||
|
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
|
||||||
|
|
||||||
|
(*button)->setCoord(buttonCord);
|
||||||
|
(*button)->setSize(buttonSize);
|
||||||
|
|
||||||
|
left += buttonSize.width + buttonLeftPadding;
|
||||||
}
|
}
|
||||||
it = mTimers.erase(it);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
it++;
|
// among each other
|
||||||
|
if(biggestButtonWidth > textSize.width) {
|
||||||
|
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainWidgetSize.width = textSize.width + 3*textPadding;
|
||||||
|
}
|
||||||
|
mainWidgetSize.height = textSize.height + 2*textPadding + textButtonPadding + buttonHeight * buttons.size() + buttonMainPadding;
|
||||||
|
|
||||||
|
mMainWidget->setSize(mainWidgetSize);
|
||||||
|
|
||||||
|
MyGUI::IntCoord absCoord;
|
||||||
|
absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2;
|
||||||
|
absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2;
|
||||||
|
|
||||||
|
mMainWidget->setCoord(absCoord);
|
||||||
|
mMainWidget->setSize(mainWidgetSize);
|
||||||
|
|
||||||
|
|
||||||
|
MyGUI::IntCoord messageWidgetCoord;
|
||||||
|
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
|
||||||
|
messageWidgetCoord.top = textPadding;
|
||||||
|
mMessageWidget->setCoord(messageWidgetCoord);
|
||||||
|
|
||||||
|
mMessageWidget->setSize(textSize);
|
||||||
|
|
||||||
|
MyGUI::IntCoord buttonCord;
|
||||||
|
MyGUI::IntSize buttonSize(0, buttonHeight);
|
||||||
|
|
||||||
|
int top = textButtonPadding + buttonTopPadding + textSize.height;
|
||||||
|
|
||||||
|
std::vector<MyGUI::Button*>::const_iterator button;
|
||||||
|
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
||||||
|
{
|
||||||
|
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
|
||||||
|
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
|
||||||
|
|
||||||
|
buttonCord.top = top;
|
||||||
|
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
|
||||||
|
|
||||||
|
(*button)->setCoord(buttonCord);
|
||||||
|
(*button)->setSize(buttonSize);
|
||||||
|
|
||||||
|
top += buttonSize.height + 2*buttonTopPadding;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
|
void InteractiveMessageBox::enterPressed()
|
||||||
delete mInterMessageBoxe;
|
|
||||||
mInterMessageBoxe = NULL;
|
|
||||||
MWBase::Environment::get().getInputManager()->changeInputMode(
|
|
||||||
MWBase::Environment::get().getWindowManager()->isGuiMode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageBoxManager::createMessageBox (const std::string& message)
|
|
||||||
{
|
|
||||||
MessageBox *box = new MessageBox(*this, message);
|
|
||||||
|
|
||||||
removeMessageBox(message.length()*mMessageBoxSpeed, box);
|
|
||||||
|
|
||||||
mMessageBoxes.push_back(box);
|
|
||||||
std::vector<MessageBox*>::iterator it;
|
|
||||||
|
|
||||||
if(mMessageBoxes.size() > 3) {
|
|
||||||
delete *mMessageBoxes.begin();
|
|
||||||
mMessageBoxes.erase(mMessageBoxes.begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
int height = 0;
|
|
||||||
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
|
|
||||||
{
|
{
|
||||||
(*it)->update(height);
|
|
||||||
height += (*it)->getHeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
|
|
||||||
{
|
|
||||||
if(mInterMessageBoxe != NULL) {
|
|
||||||
throw std::runtime_error("There is a message box already");
|
|
||||||
}
|
|
||||||
|
|
||||||
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MessageBoxManager::isInteractiveMessageBox ()
|
|
||||||
{
|
|
||||||
return mInterMessageBoxe != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox)
|
|
||||||
{
|
|
||||||
MessageBoxManagerTimer timer;
|
|
||||||
timer.current = 0;
|
|
||||||
timer.max = time;
|
|
||||||
timer.messageBox = msgbox;
|
|
||||||
|
|
||||||
mTimers.insert(mTimers.end(), timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
|
|
||||||
{
|
|
||||||
std::vector<MessageBox*>::iterator it;
|
|
||||||
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
|
|
||||||
{
|
|
||||||
if((*it) == msgbox)
|
|
||||||
{
|
|
||||||
delete (*it);
|
|
||||||
mMessageBoxes.erase(it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageBoxManager::setMessageBoxSpeed (int speed)
|
|
||||||
{
|
|
||||||
mMessageBoxSpeed = speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageBoxManager::enterPressed ()
|
|
||||||
{
|
|
||||||
if(mInterMessageBoxe != NULL)
|
|
||||||
mInterMessageBoxe->enterPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
int MessageBoxManager::readPressedButton ()
|
|
||||||
{
|
|
||||||
if(mInterMessageBoxe != NULL)
|
|
||||||
{
|
|
||||||
return mInterMessageBoxe->readPressedButton();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message)
|
|
||||||
: Layout("openmw_messagebox.layout")
|
|
||||||
, mMessageBoxManager(parMessageBoxManager)
|
|
||||||
, mMessage(message)
|
|
||||||
{
|
|
||||||
// defines
|
|
||||||
mFixedWidth = 300;
|
|
||||||
mBottomPadding = 20;
|
|
||||||
mNextBoxPadding = 20;
|
|
||||||
mMarkedToDelete = false;
|
|
||||||
|
|
||||||
getWidget(mMessageWidget, "message");
|
|
||||||
|
|
||||||
mMessageWidget->setOverflowToTheLeft(true);
|
|
||||||
mMessageWidget->setCaptionWithReplacing(mMessage);
|
|
||||||
|
|
||||||
MyGUI::IntSize size;
|
|
||||||
size.width = mFixedWidth;
|
|
||||||
size.height = 100; // dummy
|
|
||||||
|
|
||||||
MyGUI::IntCoord coord;
|
|
||||||
coord.left = 10; // dummy
|
|
||||||
coord.top = 10; // dummy
|
|
||||||
|
|
||||||
mMessageWidget->setSize(size);
|
|
||||||
|
|
||||||
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
|
|
||||||
|
|
||||||
size.height = mHeight = textSize.height + 20; // this is the padding between the text and the box
|
|
||||||
|
|
||||||
mMainWidget->setSize(size);
|
|
||||||
size.width -= 15; // this is to center the text (see messagebox.layout, Widget type="Edit" position="-2 -3 0 0")
|
|
||||||
mMessageWidget->setSize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageBox::update (int height)
|
|
||||||
{
|
|
||||||
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
|
|
||||||
MyGUI::IntCoord coord;
|
|
||||||
coord.left = (gameWindowSize.width - mFixedWidth)/2;
|
|
||||||
coord.top = (gameWindowSize.height - mHeight - height - mBottomPadding);
|
|
||||||
|
|
||||||
MyGUI::IntSize size;
|
|
||||||
size.width = mFixedWidth;
|
|
||||||
size.height = mHeight;
|
|
||||||
|
|
||||||
mMainWidget->setCoord(coord);
|
|
||||||
mMainWidget->setSize(size);
|
|
||||||
mMainWidget->setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int MessageBox::getHeight ()
|
|
||||||
{
|
|
||||||
return mHeight+mNextBoxPadding; // 20 is the padding between this and the next MessageBox
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
|
|
||||||
: WindowModal("openmw_interactive_messagebox.layout")
|
|
||||||
, mMessageBoxManager(parMessageBoxManager)
|
|
||||||
, mButtonPressed(-1)
|
|
||||||
{
|
|
||||||
WindowModal::open();
|
|
||||||
|
|
||||||
int fixedWidth = 500;
|
|
||||||
int textPadding = 10; // padding between text-widget and main-widget
|
|
||||||
int textButtonPadding = 20; // padding between the text-widget und the button-widget
|
|
||||||
int buttonLeftPadding = 10; // padding between the buttons if horizontal
|
|
||||||
int buttonTopPadding = 5; // ^-- if vertical
|
|
||||||
int buttonPadding = 5; // padding between button label and button itself
|
|
||||||
int buttonMainPadding = 10; // padding between buttons and bottom of the main widget
|
|
||||||
|
|
||||||
mMarkedToDelete = false;
|
|
||||||
|
|
||||||
|
|
||||||
getWidget(mMessageWidget, "message");
|
|
||||||
getWidget(mButtonsWidget, "buttons");
|
|
||||||
|
|
||||||
mMessageWidget->setOverflowToTheLeft(true);
|
|
||||||
mMessageWidget->setCaptionWithReplacing(message);
|
|
||||||
|
|
||||||
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
|
|
||||||
|
|
||||||
MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize();
|
|
||||||
|
|
||||||
int biggestButtonWidth = 0;
|
|
||||||
int buttonWidth = 0;
|
|
||||||
int buttonsWidth = 0;
|
|
||||||
int buttonHeight = 0;
|
|
||||||
MyGUI::IntCoord dummyCoord(0, 0, 0, 0);
|
|
||||||
|
|
||||||
std::vector<std::string>::const_iterator it;
|
|
||||||
for(it = buttons.begin(); it != buttons.end(); ++it)
|
|
||||||
{
|
|
||||||
MyGUI::Button* button = mButtonsWidget->createWidget<MyGUI::Button>(
|
|
||||||
MyGUI::WidgetStyle::Child,
|
|
||||||
std::string("MW_Button"),
|
|
||||||
dummyCoord,
|
|
||||||
MyGUI::Align::Default);
|
|
||||||
button->setCaptionWithReplacing(*it);
|
|
||||||
|
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed);
|
|
||||||
|
|
||||||
mButtons.push_back(button);
|
|
||||||
|
|
||||||
buttonWidth = button->getTextSize().width + 2*buttonPadding + buttonLeftPadding;
|
|
||||||
buttonsWidth += buttonWidth;
|
|
||||||
buttonHeight = button->getTextSize().height + 2*buttonPadding + buttonTopPadding;
|
|
||||||
|
|
||||||
if(buttonWidth > biggestButtonWidth)
|
|
||||||
{
|
|
||||||
biggestButtonWidth = buttonWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buttonsWidth += buttonLeftPadding;
|
|
||||||
|
|
||||||
MyGUI::IntSize mainWidgetSize;
|
|
||||||
if(buttonsWidth < fixedWidth)
|
|
||||||
{
|
|
||||||
// on one line
|
|
||||||
if(textSize.width + 2*textPadding < buttonsWidth)
|
|
||||||
{
|
|
||||||
mainWidgetSize.width = buttonsWidth;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mainWidgetSize.width = textSize.width + 3*textPadding;
|
|
||||||
}
|
|
||||||
mainWidgetSize.height = textSize.height + textButtonPadding + buttonHeight + buttonMainPadding;
|
|
||||||
|
|
||||||
MyGUI::IntCoord absCoord;
|
|
||||||
absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2;
|
|
||||||
absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2;
|
|
||||||
|
|
||||||
mMainWidget->setCoord(absCoord);
|
|
||||||
mMainWidget->setSize(mainWidgetSize);
|
|
||||||
|
|
||||||
MyGUI::IntCoord messageWidgetCoord;
|
|
||||||
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
|
|
||||||
messageWidgetCoord.top = textPadding;
|
|
||||||
mMessageWidget->setCoord(messageWidgetCoord);
|
|
||||||
|
|
||||||
mMessageWidget->setSize(textSize);
|
|
||||||
|
|
||||||
MyGUI::IntCoord buttonCord;
|
|
||||||
MyGUI::IntSize buttonSize(0, buttonHeight);
|
|
||||||
int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding;
|
|
||||||
|
|
||||||
|
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
|
||||||
std::vector<MyGUI::Button*>::const_iterator button;
|
std::vector<MyGUI::Button*>::const_iterator button;
|
||||||
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
||||||
{
|
{
|
||||||
buttonCord.left = left;
|
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
|
||||||
buttonCord.top = textSize.height + textButtonPadding;
|
{
|
||||||
|
buttonActivated(*button);
|
||||||
buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding;
|
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||||
buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding;
|
break;
|
||||||
|
}
|
||||||
(*button)->setCoord(buttonCord);
|
|
||||||
(*button)->setSize(buttonSize);
|
|
||||||
|
|
||||||
left += buttonSize.width + buttonLeftPadding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
|
||||||
{
|
{
|
||||||
// among each other
|
buttonActivated (pressed);
|
||||||
if(biggestButtonWidth > textSize.width) {
|
}
|
||||||
mainWidgetSize.width = biggestButtonWidth + buttonTopPadding;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mainWidgetSize.width = textSize.width + 3*textPadding;
|
|
||||||
}
|
|
||||||
mainWidgetSize.height = textSize.height + 2*textPadding + textButtonPadding + buttonHeight * buttons.size() + buttonMainPadding;
|
|
||||||
|
|
||||||
mMainWidget->setSize(mainWidgetSize);
|
|
||||||
|
|
||||||
MyGUI::IntCoord absCoord;
|
|
||||||
absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2;
|
|
||||||
absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2;
|
|
||||||
|
|
||||||
mMainWidget->setCoord(absCoord);
|
|
||||||
mMainWidget->setSize(mainWidgetSize);
|
|
||||||
|
|
||||||
|
|
||||||
MyGUI::IntCoord messageWidgetCoord;
|
|
||||||
messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2;
|
|
||||||
messageWidgetCoord.top = textPadding;
|
|
||||||
mMessageWidget->setCoord(messageWidgetCoord);
|
|
||||||
|
|
||||||
mMessageWidget->setSize(textSize);
|
|
||||||
|
|
||||||
MyGUI::IntCoord buttonCord;
|
|
||||||
MyGUI::IntSize buttonSize(0, buttonHeight);
|
|
||||||
|
|
||||||
int top = textButtonPadding + buttonTopPadding + textSize.height;
|
|
||||||
|
|
||||||
|
void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
|
||||||
|
{
|
||||||
|
mMarkedToDelete = true;
|
||||||
|
int index = 0;
|
||||||
std::vector<MyGUI::Button*>::const_iterator button;
|
std::vector<MyGUI::Button*>::const_iterator button;
|
||||||
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
||||||
{
|
{
|
||||||
buttonSize.width = (*button)->getTextSize().width + buttonPadding*2;
|
if(*button == pressed)
|
||||||
buttonSize.height = (*button)->getTextSize().height + buttonPadding*2;
|
{
|
||||||
|
mButtonPressed = index;
|
||||||
buttonCord.top = top;
|
mMessageBoxManager.onButtonPressed(mButtonPressed);
|
||||||
buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/
|
return;
|
||||||
|
}
|
||||||
(*button)->setCoord(buttonCord);
|
index++;
|
||||||
(*button)->setSize(buttonSize);
|
|
||||||
|
|
||||||
top += buttonSize.height + 2*buttonTopPadding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void InteractiveMessageBox::enterPressed()
|
int InteractiveMessageBox::readPressedButton ()
|
||||||
{
|
|
||||||
|
|
||||||
std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}"));
|
|
||||||
std::vector<MyGUI::Button*>::const_iterator button;
|
|
||||||
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
|
||||||
{
|
{
|
||||||
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
|
int pressed = mButtonPressed;
|
||||||
{
|
mButtonPressed = -1;
|
||||||
buttonActivated(*button);
|
return pressed;
|
||||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
|
|
||||||
{
|
|
||||||
buttonActivated (pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
|
|
||||||
{
|
|
||||||
mMarkedToDelete = true;
|
|
||||||
int index = 0;
|
|
||||||
std::vector<MyGUI::Button*>::const_iterator button;
|
|
||||||
for(button = mButtons.begin(); button != mButtons.end(); ++button)
|
|
||||||
{
|
|
||||||
if(*button == pressed)
|
|
||||||
{
|
|
||||||
mButtonPressed = index;
|
|
||||||
mMessageBoxManager.onButtonPressed(mButtonPressed);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int InteractiveMessageBox::readPressedButton ()
|
|
||||||
{
|
|
||||||
int pressed = mButtonPressed;
|
|
||||||
mButtonPressed = -1;
|
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,435 +10,437 @@
|
||||||
|
|
||||||
#include "tooltips.hpp"
|
#include "tooltips.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
|
||||||
using namespace Widgets;
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
int wrap(int index, int max)
|
int wrap(int index, int max)
|
||||||
{
|
{
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return max - 1;
|
return max - 1;
|
||||||
else if (index >= max)
|
else if (index >= max)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return index;
|
return index;
|
||||||
}
|
|
||||||
|
|
||||||
int countParts(const std::string &part, const std::string &race, bool male)
|
|
||||||
{
|
|
||||||
/// \todo loop through the whole store for appropriate bodyparts instead of looking for fixed IDs
|
|
||||||
const MWWorld::Store<ESM::BodyPart> &store =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
|
||||||
|
|
||||||
std::string prefix =
|
|
||||||
"b_n_" + race + ((male) ? "_m_" : "_f_") + part;
|
|
||||||
|
|
||||||
std::string suffix;
|
|
||||||
suffix.reserve(prefix.size() + 3);
|
|
||||||
|
|
||||||
int count = -1;
|
|
||||||
do {
|
|
||||||
++count;
|
|
||||||
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
|
|
||||||
}
|
}
|
||||||
while (store.search(prefix + suffix) != 0);
|
|
||||||
|
|
||||||
if (count == 0 && part == "hair") {
|
int countParts(const std::string &part, const std::string &race, bool male)
|
||||||
count = -1;
|
{
|
||||||
|
/// \todo loop through the whole store for appropriate bodyparts instead of looking for fixed IDs
|
||||||
|
const MWWorld::Store<ESM::BodyPart> &store =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
||||||
|
|
||||||
|
std::string prefix =
|
||||||
|
"b_n_" + race + ((male) ? "_m_" : "_f_") + part;
|
||||||
|
|
||||||
|
std::string suffix;
|
||||||
|
suffix.reserve(prefix.size() + 3);
|
||||||
|
|
||||||
|
int count = -1;
|
||||||
do {
|
do {
|
||||||
++count;
|
++count;
|
||||||
suffix = (boost::format("%02d") % (count + 1)).str();
|
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
|
||||||
}
|
}
|
||||||
while (store.search(prefix + suffix) != 0);
|
while (store.search(prefix + suffix) != 0);
|
||||||
|
|
||||||
|
if (count == 0 && part == "hair") {
|
||||||
|
count = -1;
|
||||||
|
do {
|
||||||
|
++count;
|
||||||
|
suffix = (boost::format("%02d") % (count + 1)).str();
|
||||||
|
}
|
||||||
|
while (store.search(prefix + suffix) != 0);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RaceDialog::RaceDialog()
|
namespace MWGui
|
||||||
: WindowModal("openmw_chargen_race.layout")
|
|
||||||
, mGenderIndex(0)
|
|
||||||
, mFaceIndex(0)
|
|
||||||
, mHairIndex(0)
|
|
||||||
, mFaceCount(10)
|
|
||||||
, mHairCount(14)
|
|
||||||
, mCurrentAngle(0)
|
|
||||||
{
|
{
|
||||||
// Centre dialog
|
|
||||||
center();
|
|
||||||
|
|
||||||
setText("AppearanceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu1", "Appearance"));
|
RaceDialog::RaceDialog()
|
||||||
getWidget(mPreviewImage, "PreviewImage");
|
: WindowModal("openmw_chargen_race.layout")
|
||||||
|
, mGenderIndex(0)
|
||||||
getWidget(mHeadRotate, "HeadRotate");
|
, mFaceIndex(0)
|
||||||
mHeadRotate->setScrollRange(50);
|
, mHairIndex(0)
|
||||||
mHeadRotate->setScrollPosition(25);
|
, mFaceCount(10)
|
||||||
mHeadRotate->setScrollViewPage(10);
|
, mHairCount(14)
|
||||||
mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);
|
, mCurrentAngle(0)
|
||||||
|
|
||||||
// Set up next/previous buttons
|
|
||||||
MyGUI::Button *prevButton, *nextButton;
|
|
||||||
|
|
||||||
setText("GenderChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu2", "Change Sex"));
|
|
||||||
getWidget(prevButton, "PrevGenderButton");
|
|
||||||
getWidget(nextButton, "NextGenderButton");
|
|
||||||
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousGender);
|
|
||||||
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextGender);
|
|
||||||
|
|
||||||
setText("FaceChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu3", "Change Face"));
|
|
||||||
getWidget(prevButton, "PrevFaceButton");
|
|
||||||
getWidget(nextButton, "NextFaceButton");
|
|
||||||
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace);
|
|
||||||
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace);
|
|
||||||
|
|
||||||
setText("HairChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu4", "Change Hair"));
|
|
||||||
getWidget(prevButton, "PrevHairButton");
|
|
||||||
getWidget(nextButton, "NextHairButton");
|
|
||||||
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
|
|
||||||
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
|
|
||||||
|
|
||||||
setText("RaceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu5", "Race"));
|
|
||||||
getWidget(mRaceList, "RaceList");
|
|
||||||
mRaceList->setScrollVisible(true);
|
|
||||||
mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
|
|
||||||
mRaceList->eventListMouseItemActivate += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
|
|
||||||
mRaceList->eventListChangePosition += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
|
|
||||||
|
|
||||||
setText("SkillsT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sBonusSkillTitle", "Skill Bonus"));
|
|
||||||
getWidget(mSkillList, "SkillList");
|
|
||||||
setText("SpellPowerT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu7", "Specials"));
|
|
||||||
getWidget(mSpellPowerList, "SpellPowerList");
|
|
||||||
|
|
||||||
MyGUI::Button* backButton;
|
|
||||||
getWidget(backButton, "BackButton");
|
|
||||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked);
|
|
||||||
|
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
|
||||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked);
|
|
||||||
|
|
||||||
updateRaces();
|
|
||||||
updateSkills();
|
|
||||||
updateSpellPowers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::setNextButtonShow(bool shown)
|
|
||||||
{
|
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
|
|
||||||
if (shown)
|
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
|
|
||||||
else
|
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::open()
|
|
||||||
{
|
|
||||||
WindowModal::open();
|
|
||||||
|
|
||||||
updateRaces();
|
|
||||||
updateSkills();
|
|
||||||
updateSpellPowers();
|
|
||||||
|
|
||||||
mPreview = new MWRender::RaceSelectionPreview();
|
|
||||||
mPreview->setup();
|
|
||||||
mPreview->update (0);
|
|
||||||
|
|
||||||
const ESM::NPC proto = mPreview->getPrototype();
|
|
||||||
setRaceId(proto.mRace);
|
|
||||||
recountParts();
|
|
||||||
|
|
||||||
std::string index = proto.mHead.substr(proto.mHead.size() - 2, 2);
|
|
||||||
mFaceIndex = boost::lexical_cast<int>(index) - 1;
|
|
||||||
|
|
||||||
index = proto.mHair.substr(proto.mHair.size() - 2, 2);
|
|
||||||
mHairIndex = boost::lexical_cast<int>(index) - 1;
|
|
||||||
|
|
||||||
mPreviewImage->setImageTexture ("CharacterHeadPreview");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void RaceDialog::setRaceId(const std::string &raceId)
|
|
||||||
{
|
|
||||||
mCurrentRaceId = raceId;
|
|
||||||
mRaceList->setIndexSelected(MyGUI::ITEM_NONE);
|
|
||||||
size_t count = mRaceList->getItemCount();
|
|
||||||
for (size_t i = 0; i < count; ++i)
|
|
||||||
{
|
{
|
||||||
if (boost::iequals(*mRaceList->getItemDataAt<std::string>(i), raceId))
|
// Centre dialog
|
||||||
|
center();
|
||||||
|
|
||||||
|
setText("AppearanceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu1", "Appearance"));
|
||||||
|
getWidget(mPreviewImage, "PreviewImage");
|
||||||
|
|
||||||
|
getWidget(mHeadRotate, "HeadRotate");
|
||||||
|
mHeadRotate->setScrollRange(50);
|
||||||
|
mHeadRotate->setScrollPosition(25);
|
||||||
|
mHeadRotate->setScrollViewPage(10);
|
||||||
|
mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);
|
||||||
|
|
||||||
|
// Set up next/previous buttons
|
||||||
|
MyGUI::Button *prevButton, *nextButton;
|
||||||
|
|
||||||
|
setText("GenderChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu2", "Change Sex"));
|
||||||
|
getWidget(prevButton, "PrevGenderButton");
|
||||||
|
getWidget(nextButton, "NextGenderButton");
|
||||||
|
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousGender);
|
||||||
|
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextGender);
|
||||||
|
|
||||||
|
setText("FaceChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu3", "Change Face"));
|
||||||
|
getWidget(prevButton, "PrevFaceButton");
|
||||||
|
getWidget(nextButton, "NextFaceButton");
|
||||||
|
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace);
|
||||||
|
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace);
|
||||||
|
|
||||||
|
setText("HairChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu4", "Change Hair"));
|
||||||
|
getWidget(prevButton, "PrevHairButton");
|
||||||
|
getWidget(nextButton, "NextHairButton");
|
||||||
|
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
|
||||||
|
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
|
||||||
|
|
||||||
|
setText("RaceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu5", "Race"));
|
||||||
|
getWidget(mRaceList, "RaceList");
|
||||||
|
mRaceList->setScrollVisible(true);
|
||||||
|
mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
|
||||||
|
mRaceList->eventListMouseItemActivate += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
|
||||||
|
mRaceList->eventListChangePosition += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);
|
||||||
|
|
||||||
|
setText("SkillsT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sBonusSkillTitle", "Skill Bonus"));
|
||||||
|
getWidget(mSkillList, "SkillList");
|
||||||
|
setText("SpellPowerT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu7", "Specials"));
|
||||||
|
getWidget(mSpellPowerList, "SpellPowerList");
|
||||||
|
|
||||||
|
MyGUI::Button* backButton;
|
||||||
|
getWidget(backButton, "BackButton");
|
||||||
|
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked);
|
||||||
|
|
||||||
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
||||||
|
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked);
|
||||||
|
|
||||||
|
updateRaces();
|
||||||
|
updateSkills();
|
||||||
|
updateSpellPowers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::setNextButtonShow(bool shown)
|
||||||
|
{
|
||||||
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
|
||||||
|
if (shown)
|
||||||
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
|
||||||
|
else
|
||||||
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::open()
|
||||||
|
{
|
||||||
|
WindowModal::open();
|
||||||
|
|
||||||
|
updateRaces();
|
||||||
|
updateSkills();
|
||||||
|
updateSpellPowers();
|
||||||
|
|
||||||
|
mPreview = new MWRender::RaceSelectionPreview();
|
||||||
|
mPreview->setup();
|
||||||
|
mPreview->update (0);
|
||||||
|
|
||||||
|
const ESM::NPC proto = mPreview->getPrototype();
|
||||||
|
setRaceId(proto.mRace);
|
||||||
|
recountParts();
|
||||||
|
|
||||||
|
std::string index = proto.mHead.substr(proto.mHead.size() - 2, 2);
|
||||||
|
mFaceIndex = boost::lexical_cast<int>(index) - 1;
|
||||||
|
|
||||||
|
index = proto.mHair.substr(proto.mHair.size() - 2, 2);
|
||||||
|
mHairIndex = boost::lexical_cast<int>(index) - 1;
|
||||||
|
|
||||||
|
mPreviewImage->setImageTexture ("CharacterHeadPreview");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RaceDialog::setRaceId(const std::string &raceId)
|
||||||
|
{
|
||||||
|
mCurrentRaceId = raceId;
|
||||||
|
mRaceList->setIndexSelected(MyGUI::ITEM_NONE);
|
||||||
|
size_t count = mRaceList->getItemCount();
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
mRaceList->setIndexSelected(i);
|
if (boost::iequals(*mRaceList->getItemDataAt<std::string>(i), raceId))
|
||||||
MyGUI::Button* okButton;
|
{
|
||||||
getWidget(okButton, "OKButton");
|
mRaceList->setIndexSelected(i);
|
||||||
break;
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSkills();
|
||||||
|
updateSpellPowers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::close()
|
||||||
|
{
|
||||||
|
delete mPreview;
|
||||||
|
mPreview = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// widget controls
|
||||||
|
|
||||||
|
void RaceDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
if(mRaceList->getIndexSelected() == MyGUI::ITEM_NONE)
|
||||||
|
return;
|
||||||
|
eventDone(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onBackClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position)
|
||||||
|
{
|
||||||
|
float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2;
|
||||||
|
float diff = angle - mCurrentAngle;
|
||||||
|
mPreview->update (diff);
|
||||||
|
mCurrentAngle += diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onSelectPreviousGender(MyGUI::Widget*)
|
||||||
|
{
|
||||||
|
mGenderIndex = wrap(mGenderIndex - 1, 2);
|
||||||
|
|
||||||
|
recountParts();
|
||||||
|
updatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onSelectNextGender(MyGUI::Widget*)
|
||||||
|
{
|
||||||
|
mGenderIndex = wrap(mGenderIndex + 1, 2);
|
||||||
|
|
||||||
|
recountParts();
|
||||||
|
updatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
mFaceIndex = wrap(mFaceIndex - 1, mFaceCount);
|
||||||
|
while (!isFacePlayable());
|
||||||
|
updatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onSelectNextFace(MyGUI::Widget*)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
|
||||||
|
while (!isFacePlayable());
|
||||||
|
updatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
mHairIndex = wrap(mHairIndex - 1, mHairCount);
|
||||||
|
while (!isHairPlayable());
|
||||||
|
updatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onSelectNextHair(MyGUI::Widget*)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
mHairIndex = wrap(mHairIndex + 1, mHairCount);
|
||||||
|
while (!isHairPlayable());
|
||||||
|
updatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RaceDialog::isFacePlayable()
|
||||||
|
{
|
||||||
|
std::string prefix =
|
||||||
|
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
|
||||||
|
|
||||||
|
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::BodyPart> &parts =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
||||||
|
|
||||||
|
if (parts.search(prefix + "head_" + headIndex) == 0)
|
||||||
|
return !(parts.find(prefix + "head" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
else
|
||||||
|
return !(parts.find(prefix + "head_" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RaceDialog::isHairPlayable()
|
||||||
|
{
|
||||||
|
std::string prefix =
|
||||||
|
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
|
||||||
|
|
||||||
|
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::BodyPart> &parts =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
||||||
|
if (parts.search(prefix + "hair_" + hairIndex) == 0)
|
||||||
|
return !(parts.find(prefix + "hair" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
else
|
||||||
|
return !(parts.find(prefix + "hair_" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
|
||||||
|
{
|
||||||
|
if (_index == MyGUI::ITEM_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index);
|
||||||
|
if (boost::iequals(mCurrentRaceId, *raceId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mCurrentRaceId = *raceId;
|
||||||
|
|
||||||
|
recountParts();
|
||||||
|
|
||||||
|
updatePreview();
|
||||||
|
updateSkills();
|
||||||
|
updateSpellPowers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::recountParts()
|
||||||
|
{
|
||||||
|
mFaceCount = countParts("head", mCurrentRaceId, mGenderIndex == 0);
|
||||||
|
mHairCount = countParts("hair", mCurrentRaceId, mGenderIndex == 0);
|
||||||
|
|
||||||
|
mFaceIndex = 0;
|
||||||
|
mHairIndex = 0;
|
||||||
|
|
||||||
|
while (!isHairPlayable())
|
||||||
|
mHairIndex = wrap(mHairIndex + 1, mHairCount);
|
||||||
|
while (!isFacePlayable())
|
||||||
|
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update widget content
|
||||||
|
|
||||||
|
void RaceDialog::updatePreview()
|
||||||
|
{
|
||||||
|
ESM::NPC record = mPreview->getPrototype();
|
||||||
|
record.mRace = mCurrentRaceId;
|
||||||
|
record.setIsMale(mGenderIndex == 0);
|
||||||
|
|
||||||
|
std::string prefix =
|
||||||
|
"b_n_" + mCurrentRaceId + ((record.isMale()) ? "_m_" : "_f_");
|
||||||
|
|
||||||
|
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
|
||||||
|
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
|
||||||
|
|
||||||
|
record.mHead = prefix + "head_" + headIndex;
|
||||||
|
record.mHair = prefix + "hair_" + hairIndex;
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::BodyPart> &parts =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
||||||
|
|
||||||
|
if (parts.search(record.mHair) == 0) {
|
||||||
|
record.mHair = prefix + "hair" + hairIndex;
|
||||||
|
}
|
||||||
|
mPreview->setPrototype(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaceDialog::updateRaces()
|
||||||
|
{
|
||||||
|
mRaceList->removeAllItems();
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::Race> &races =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>();
|
||||||
|
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
MWWorld::Store<ESM::Race>::iterator it = races.begin();
|
||||||
|
for (; it != races.end(); ++it)
|
||||||
|
{
|
||||||
|
bool playable = it->mData.mFlags & ESM::Race::Playable;
|
||||||
|
if (!playable) // Only display playable races
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mRaceList->addItem(it->mName, it->mId);
|
||||||
|
if (boost::iequals(it->mId, mCurrentRaceId))
|
||||||
|
mRaceList->setIndexSelected(index);
|
||||||
|
++index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSkills();
|
void RaceDialog::updateSkills()
|
||||||
updateSpellPowers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::close()
|
|
||||||
{
|
|
||||||
delete mPreview;
|
|
||||||
mPreview = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// widget controls
|
|
||||||
|
|
||||||
void RaceDialog::onOkClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
if(mRaceList->getIndexSelected() == MyGUI::ITEM_NONE)
|
|
||||||
return;
|
|
||||||
eventDone(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onBackClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position)
|
|
||||||
{
|
|
||||||
float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2;
|
|
||||||
float diff = angle - mCurrentAngle;
|
|
||||||
mPreview->update (diff);
|
|
||||||
mCurrentAngle += diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onSelectPreviousGender(MyGUI::Widget*)
|
|
||||||
{
|
|
||||||
mGenderIndex = wrap(mGenderIndex - 1, 2);
|
|
||||||
|
|
||||||
recountParts();
|
|
||||||
updatePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onSelectNextGender(MyGUI::Widget*)
|
|
||||||
{
|
|
||||||
mGenderIndex = wrap(mGenderIndex + 1, 2);
|
|
||||||
|
|
||||||
recountParts();
|
|
||||||
updatePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
mFaceIndex = wrap(mFaceIndex - 1, mFaceCount);
|
|
||||||
while (!isFacePlayable());
|
|
||||||
updatePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onSelectNextFace(MyGUI::Widget*)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
|
|
||||||
while (!isFacePlayable());
|
|
||||||
updatePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
mHairIndex = wrap(mHairIndex - 1, mHairCount);
|
|
||||||
while (!isHairPlayable());
|
|
||||||
updatePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onSelectNextHair(MyGUI::Widget*)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
mHairIndex = wrap(mHairIndex + 1, mHairCount);
|
|
||||||
while (!isHairPlayable());
|
|
||||||
updatePreview();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RaceDialog::isFacePlayable()
|
|
||||||
{
|
|
||||||
std::string prefix =
|
|
||||||
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
|
|
||||||
|
|
||||||
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::BodyPart> &parts =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
|
||||||
|
|
||||||
if (parts.search(prefix + "head_" + headIndex) == 0)
|
|
||||||
return !(parts.find(prefix + "head" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
|
||||||
else
|
|
||||||
return !(parts.find(prefix + "head_" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RaceDialog::isHairPlayable()
|
|
||||||
{
|
|
||||||
std::string prefix =
|
|
||||||
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
|
|
||||||
|
|
||||||
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::BodyPart> &parts =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
|
||||||
if (parts.search(prefix + "hair_" + hairIndex) == 0)
|
|
||||||
return !(parts.find(prefix + "hair" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
|
||||||
else
|
|
||||||
return !(parts.find(prefix + "hair_" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
|
|
||||||
{
|
|
||||||
if (_index == MyGUI::ITEM_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
const std::string *raceId = mRaceList->getItemDataAt<std::string>(_index);
|
|
||||||
if (boost::iequals(mCurrentRaceId, *raceId))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mCurrentRaceId = *raceId;
|
|
||||||
|
|
||||||
recountParts();
|
|
||||||
|
|
||||||
updatePreview();
|
|
||||||
updateSkills();
|
|
||||||
updateSpellPowers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::recountParts()
|
|
||||||
{
|
|
||||||
mFaceCount = countParts("head", mCurrentRaceId, mGenderIndex == 0);
|
|
||||||
mHairCount = countParts("hair", mCurrentRaceId, mGenderIndex == 0);
|
|
||||||
|
|
||||||
mFaceIndex = 0;
|
|
||||||
mHairIndex = 0;
|
|
||||||
|
|
||||||
while (!isHairPlayable())
|
|
||||||
mHairIndex = wrap(mHairIndex + 1, mHairCount);
|
|
||||||
while (!isFacePlayable())
|
|
||||||
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update widget content
|
|
||||||
|
|
||||||
void RaceDialog::updatePreview()
|
|
||||||
{
|
|
||||||
ESM::NPC record = mPreview->getPrototype();
|
|
||||||
record.mRace = mCurrentRaceId;
|
|
||||||
record.setIsMale(mGenderIndex == 0);
|
|
||||||
|
|
||||||
std::string prefix =
|
|
||||||
"b_n_" + mCurrentRaceId + ((record.isMale()) ? "_m_" : "_f_");
|
|
||||||
|
|
||||||
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
|
|
||||||
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
|
|
||||||
|
|
||||||
record.mHead = prefix + "head_" + headIndex;
|
|
||||||
record.mHair = prefix + "hair_" + hairIndex;
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::BodyPart> &parts =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
|
||||||
|
|
||||||
if (parts.search(record.mHair) == 0) {
|
|
||||||
record.mHair = prefix + "hair" + hairIndex;
|
|
||||||
}
|
|
||||||
mPreview->setPrototype(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::updateRaces()
|
|
||||||
{
|
|
||||||
mRaceList->removeAllItems();
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::Race> &races =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>();
|
|
||||||
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
MWWorld::Store<ESM::Race>::iterator it = races.begin();
|
|
||||||
for (; it != races.end(); ++it)
|
|
||||||
{
|
{
|
||||||
bool playable = it->mData.mFlags & ESM::Race::Playable;
|
for (std::vector<MyGUI::Widget*>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it)
|
||||||
if (!playable) // Only display playable races
|
{
|
||||||
continue;
|
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||||
|
}
|
||||||
|
mSkillItems.clear();
|
||||||
|
|
||||||
mRaceList->addItem(it->mName, it->mId);
|
if (mCurrentRaceId.empty())
|
||||||
if (boost::iequals(it->mId, mCurrentRaceId))
|
return;
|
||||||
mRaceList->setIndexSelected(index);
|
|
||||||
++index;
|
Widgets::MWSkillPtr skillWidget;
|
||||||
}
|
const int lineHeight = 18;
|
||||||
}
|
MyGUI::IntCoord coord1(0, 0, mSkillList->getWidth(), 18);
|
||||||
|
|
||||||
void RaceDialog::updateSkills()
|
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
{
|
const ESM::Race *race = store.get<ESM::Race>().find(mCurrentRaceId);
|
||||||
for (std::vector<MyGUI::Widget*>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it)
|
int count = sizeof(race->mData.mBonus)/sizeof(race->mData.mBonus[0]); // TODO: Find a portable macro for this ARRAYSIZE?
|
||||||
{
|
for (int i = 0; i < count; ++i)
|
||||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
{
|
||||||
}
|
int skillId = race->mData.mBonus[i].mSkill;
|
||||||
mSkillItems.clear();
|
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
|
||||||
|
continue;
|
||||||
if (mCurrentRaceId.empty())
|
|
||||||
return;
|
skillWidget = mSkillList->createWidget<Widgets::MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
|
||||||
|
std::string("Skill") + boost::lexical_cast<std::string>(i));
|
||||||
MWSkillPtr skillWidget;
|
skillWidget->setSkillNumber(skillId);
|
||||||
const int lineHeight = 18;
|
skillWidget->setSkillValue(Widgets::MWSkill::SkillValue(race->mData.mBonus[i].mBonus));
|
||||||
MyGUI::IntCoord coord1(0, 0, mSkillList->getWidth(), 18);
|
ToolTips::createSkillToolTip(skillWidget, skillId);
|
||||||
|
|
||||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
|
||||||
const ESM::Race *race = store.get<ESM::Race>().find(mCurrentRaceId);
|
mSkillItems.push_back(skillWidget);
|
||||||
int count = sizeof(race->mData.mBonus)/sizeof(race->mData.mBonus[0]); // TODO: Find a portable macro for this ARRAYSIZE?
|
|
||||||
for (int i = 0; i < count; ++i)
|
coord1.top += lineHeight;
|
||||||
{
|
}
|
||||||
int skillId = race->mData.mBonus[i].mSkill;
|
|
||||||
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
|
|
||||||
continue;
|
|
||||||
|
|
||||||
skillWidget = mSkillList->createWidget<MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
|
|
||||||
std::string("Skill") + boost::lexical_cast<std::string>(i));
|
|
||||||
skillWidget->setSkillNumber(skillId);
|
|
||||||
skillWidget->setSkillValue(MWSkill::SkillValue(race->mData.mBonus[i].mBonus));
|
|
||||||
ToolTips::createSkillToolTip(skillWidget, skillId);
|
|
||||||
|
|
||||||
|
|
||||||
mSkillItems.push_back(skillWidget);
|
|
||||||
|
|
||||||
coord1.top += lineHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::updateSpellPowers()
|
|
||||||
{
|
|
||||||
for (std::vector<MyGUI::Widget*>::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it)
|
|
||||||
{
|
|
||||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
|
||||||
}
|
|
||||||
mSpellPowerItems.clear();
|
|
||||||
|
|
||||||
if (mCurrentRaceId.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
MWSpellPtr spellPowerWidget;
|
|
||||||
const int lineHeight = 18;
|
|
||||||
MyGUI::IntCoord coord(0, 0, mSpellPowerList->getWidth(), 18);
|
|
||||||
|
|
||||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
|
||||||
const ESM::Race *race = store.get<ESM::Race>().find(mCurrentRaceId);
|
|
||||||
|
|
||||||
std::vector<std::string>::const_iterator it = race->mPowers.mList.begin();
|
|
||||||
std::vector<std::string>::const_iterator end = race->mPowers.mList.end();
|
|
||||||
for (int i = 0; it != end; ++it)
|
|
||||||
{
|
|
||||||
const std::string &spellpower = *it;
|
|
||||||
spellPowerWidget = mSpellPowerList->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
|
|
||||||
spellPowerWidget->setSpellId(spellpower);
|
|
||||||
spellPowerWidget->setUserString("ToolTipType", "Spell");
|
|
||||||
spellPowerWidget->setUserString("Spell", spellpower);
|
|
||||||
|
|
||||||
mSpellPowerItems.push_back(spellPowerWidget);
|
|
||||||
|
|
||||||
coord.top += lineHeight;
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RaceDialog::updateSpellPowers()
|
||||||
|
{
|
||||||
|
for (std::vector<MyGUI::Widget*>::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||||
|
}
|
||||||
|
mSpellPowerItems.clear();
|
||||||
|
|
||||||
|
if (mCurrentRaceId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Widgets::MWSpellPtr spellPowerWidget;
|
||||||
|
const int lineHeight = 18;
|
||||||
|
MyGUI::IntCoord coord(0, 0, mSpellPowerList->getWidth(), 18);
|
||||||
|
|
||||||
|
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
const ESM::Race *race = store.get<ESM::Race>().find(mCurrentRaceId);
|
||||||
|
|
||||||
|
std::vector<std::string>::const_iterator it = race->mPowers.mList.begin();
|
||||||
|
std::vector<std::string>::const_iterator end = race->mPowers.mList.end();
|
||||||
|
for (int i = 0; it != end; ++it)
|
||||||
|
{
|
||||||
|
const std::string &spellpower = *it;
|
||||||
|
spellPowerWidget = mSpellPowerList->createWidget<Widgets::MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast<std::string>(i));
|
||||||
|
spellPowerWidget->setSpellId(spellpower);
|
||||||
|
spellPowerWidget->setUserString("ToolTipType", "Spell");
|
||||||
|
spellPowerWidget->setUserString("Spell", spellpower);
|
||||||
|
|
||||||
|
mSpellPowerItems.push_back(spellPowerWidget);
|
||||||
|
|
||||||
|
coord.top += lineHeight;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,357 +11,359 @@
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
using namespace Widgets;
|
|
||||||
|
|
||||||
const int ReviewDialog::sLineHeight = 18;
|
|
||||||
|
|
||||||
ReviewDialog::ReviewDialog()
|
|
||||||
: WindowModal("openmw_chargen_review.layout")
|
|
||||||
, mLastPos(0)
|
|
||||||
{
|
{
|
||||||
// Centre dialog
|
|
||||||
center();
|
|
||||||
|
|
||||||
// Setup static stats
|
const int ReviewDialog::sLineHeight = 18;
|
||||||
MyGUI::Button* button;
|
|
||||||
getWidget(mNameWidget, "NameText");
|
|
||||||
getWidget(button, "NameButton");
|
|
||||||
adjustButtonSize(button);
|
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
|
|
||||||
|
|
||||||
getWidget(mRaceWidget, "RaceText");
|
ReviewDialog::ReviewDialog()
|
||||||
getWidget(button, "RaceButton");
|
: WindowModal("openmw_chargen_review.layout")
|
||||||
adjustButtonSize(button);
|
, mLastPos(0)
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
|
|
||||||
|
|
||||||
getWidget(mClassWidget, "ClassText");
|
|
||||||
getWidget(button, "ClassButton");
|
|
||||||
adjustButtonSize(button);
|
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
|
|
||||||
|
|
||||||
getWidget(mBirthSignWidget, "SignText");
|
|
||||||
getWidget(button, "SignButton");
|
|
||||||
adjustButtonSize(button);
|
|
||||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
|
|
||||||
|
|
||||||
// Setup dynamic stats
|
|
||||||
getWidget(mHealth, "Health");
|
|
||||||
mHealth->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sHealth", ""));
|
|
||||||
mHealth->setValue(45, 45);
|
|
||||||
|
|
||||||
getWidget(mMagicka, "Magicka");
|
|
||||||
mMagicka->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sMagic", ""));
|
|
||||||
mMagicka->setValue(50, 50);
|
|
||||||
|
|
||||||
getWidget(mFatigue, "Fatigue");
|
|
||||||
mFatigue->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sFatigue", ""));
|
|
||||||
mFatigue->setValue(160, 160);
|
|
||||||
|
|
||||||
// Setup attributes
|
|
||||||
|
|
||||||
MWAttributePtr attribute;
|
|
||||||
for (int idx = 0; idx < ESM::Attribute::Length; ++idx)
|
|
||||||
{
|
{
|
||||||
getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx));
|
// Centre dialog
|
||||||
mAttributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::sAttributeIds[idx]), attribute));
|
center();
|
||||||
attribute->setAttributeId(ESM::Attribute::sAttributeIds[idx]);
|
|
||||||
attribute->setAttributeValue(MWAttribute::AttributeValue(0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup skills
|
// Setup static stats
|
||||||
getWidget(mSkillView, "SkillView");
|
MyGUI::Button* button;
|
||||||
mSkillView->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
getWidget(mNameWidget, "NameText");
|
||||||
|
getWidget(button, "NameButton");
|
||||||
|
adjustButtonSize(button);
|
||||||
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
|
||||||
|
|
||||||
for (int i = 0; i < ESM::Skill::Length; ++i)
|
getWidget(mRaceWidget, "RaceText");
|
||||||
{
|
getWidget(button, "RaceButton");
|
||||||
mSkillValues.insert(std::make_pair(i, MWMechanics::Stat<float>()));
|
adjustButtonSize(button);
|
||||||
mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
|
||||||
}
|
|
||||||
|
|
||||||
MyGUI::Button* backButton;
|
getWidget(mClassWidget, "ClassText");
|
||||||
getWidget(backButton, "BackButton");
|
getWidget(button, "ClassButton");
|
||||||
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
|
adjustButtonSize(button);
|
||||||
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
|
||||||
|
|
||||||
MyGUI::Button* okButton;
|
getWidget(mBirthSignWidget, "SignText");
|
||||||
getWidget(okButton, "OKButton");
|
getWidget(button, "SignButton");
|
||||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
|
adjustButtonSize(button);
|
||||||
}
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
|
||||||
|
|
||||||
void ReviewDialog::open()
|
// Setup dynamic stats
|
||||||
{
|
getWidget(mHealth, "Health");
|
||||||
WindowModal::open();
|
mHealth->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sHealth", ""));
|
||||||
updateSkillArea();
|
mHealth->setValue(45, 45);
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setPlayerName(const std::string &name)
|
getWidget(mMagicka, "Magicka");
|
||||||
{
|
mMagicka->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sMagic", ""));
|
||||||
mNameWidget->setCaption(name);
|
mMagicka->setValue(50, 50);
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setRace(const std::string &raceId)
|
getWidget(mFatigue, "Fatigue");
|
||||||
{
|
mFatigue->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sFatigue", ""));
|
||||||
mRaceId = raceId;
|
mFatigue->setValue(160, 160);
|
||||||
|
|
||||||
const ESM::Race *race =
|
// Setup attributes
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().search(mRaceId);
|
|
||||||
if (race)
|
|
||||||
{
|
|
||||||
ToolTips::createRaceToolTip(mRaceWidget, race);
|
|
||||||
mRaceWidget->setCaption(race->mName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setClass(const ESM::Class& class_)
|
Widgets::MWAttributePtr attribute;
|
||||||
{
|
for (int idx = 0; idx < ESM::Attribute::Length; ++idx)
|
||||||
mKlass = class_;
|
|
||||||
mClassWidget->setCaption(mKlass.mName);
|
|
||||||
ToolTips::createClassToolTip(mClassWidget, mKlass);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setBirthSign(const std::string& signId)
|
|
||||||
{
|
|
||||||
mBirthSignId = signId;
|
|
||||||
|
|
||||||
const ESM::BirthSign *sign =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>().search(mBirthSignId);
|
|
||||||
if (sign)
|
|
||||||
{
|
|
||||||
mBirthSignWidget->setCaption(sign->mName);
|
|
||||||
ToolTips::createBirthsignToolTip(mBirthSignWidget, mBirthSignId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<float>& value)
|
|
||||||
{
|
|
||||||
mHealth->setValue(value.getCurrent(), value.getModified());
|
|
||||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
|
||||||
mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<float>& value)
|
|
||||||
{
|
|
||||||
mMagicka->setValue(value.getCurrent(), value.getModified());
|
|
||||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
|
||||||
mMagicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<float>& value)
|
|
||||||
{
|
|
||||||
mFatigue->setValue(value.getCurrent(), value.getModified());
|
|
||||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
|
||||||
mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
|
|
||||||
{
|
|
||||||
std::map<int, MWAttributePtr>::iterator attr = mAttributeWidgets.find(static_cast<int>(attributeId));
|
|
||||||
if (attr == mAttributeWidgets.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
attr->second->setAttributeValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value)
|
|
||||||
{
|
|
||||||
mSkillValues[skillId] = value;
|
|
||||||
MyGUI::TextBox* widget = mSkillWidgetMap[skillId];
|
|
||||||
if (widget)
|
|
||||||
{
|
|
||||||
float modified = value.getModified(), base = value.getBase();
|
|
||||||
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
|
|
||||||
std::string state = "normal";
|
|
||||||
if (modified > base)
|
|
||||||
state = "increased";
|
|
||||||
else if (modified < base)
|
|
||||||
state = "decreased";
|
|
||||||
|
|
||||||
widget->setCaption(text);
|
|
||||||
widget->_setWidgetState(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
|
|
||||||
{
|
|
||||||
mMajorSkills = major;
|
|
||||||
mMinorSkills = minor;
|
|
||||||
|
|
||||||
// Update misc skills with the remaining skills not in major or minor
|
|
||||||
std::set<int> skillSet;
|
|
||||||
std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin()));
|
|
||||||
std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin()));
|
|
||||||
boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator end = ESM::Skill::sSkillIds.end();
|
|
||||||
mMiscSkills.clear();
|
|
||||||
for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::sSkillIds.begin(); it != end; ++it)
|
|
||||||
{
|
|
||||||
int skill = *it;
|
|
||||||
if (skillSet.find(skill) == skillSet.end())
|
|
||||||
mMiscSkills.push_back(skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSkillArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
|
||||||
{
|
|
||||||
MyGUI::ImageBox* separator = mSkillView->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
|
|
||||||
separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
|
||||||
|
|
||||||
mSkillWidgets.push_back(separator);
|
|
||||||
|
|
||||||
coord1.top += separator->getHeight();
|
|
||||||
coord2.top += separator->getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
|
||||||
{
|
|
||||||
MyGUI::TextBox* groupWidget = mSkillView->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
|
|
||||||
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
|
||||||
groupWidget->setCaption(label);
|
|
||||||
mSkillWidgets.push_back(groupWidget);
|
|
||||||
|
|
||||||
coord1.top += sLineHeight;
|
|
||||||
coord2.top += sLineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
|
||||||
{
|
|
||||||
MyGUI::TextBox* skillNameWidget;
|
|
||||||
MyGUI::TextBox* skillValueWidget;
|
|
||||||
|
|
||||||
skillNameWidget = mSkillView->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default);
|
|
||||||
skillNameWidget->setCaption(text);
|
|
||||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
|
||||||
|
|
||||||
skillValueWidget = mSkillView->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right);
|
|
||||||
skillValueWidget->setCaption(value);
|
|
||||||
skillValueWidget->_setWidgetState(state);
|
|
||||||
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
|
||||||
|
|
||||||
mSkillWidgets.push_back(skillNameWidget);
|
|
||||||
mSkillWidgets.push_back(skillValueWidget);
|
|
||||||
|
|
||||||
coord1.top += sLineHeight;
|
|
||||||
coord2.top += sLineHeight;
|
|
||||||
|
|
||||||
return skillValueWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
|
||||||
{
|
|
||||||
MyGUI::TextBox* skillNameWidget;
|
|
||||||
|
|
||||||
skillNameWidget = mSkillView->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
|
|
||||||
skillNameWidget->setCaption(text);
|
|
||||||
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
|
||||||
|
|
||||||
mSkillWidgets.push_back(skillNameWidget);
|
|
||||||
|
|
||||||
coord1.top += sLineHeight;
|
|
||||||
coord2.top += sLineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
|
||||||
{
|
|
||||||
// Add a line separator if there are items above
|
|
||||||
if (!mSkillWidgets.empty())
|
|
||||||
{
|
|
||||||
addSeparator(coord1, coord2);
|
|
||||||
}
|
|
||||||
|
|
||||||
addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2);
|
|
||||||
|
|
||||||
SkillList::const_iterator end = skills.end();
|
|
||||||
for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
|
|
||||||
{
|
|
||||||
int skillId = *it;
|
|
||||||
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
|
|
||||||
continue;
|
|
||||||
assert(skillId >= 0 && skillId < ESM::Skill::Length);
|
|
||||||
const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
|
|
||||||
const MWMechanics::Stat<float> &stat = mSkillValues.find(skillId)->second;
|
|
||||||
float base = stat.getBase();
|
|
||||||
float modified = stat.getModified();
|
|
||||||
|
|
||||||
std::string state = "normal";
|
|
||||||
if (modified > base)
|
|
||||||
state = "increased";
|
|
||||||
else if (modified < base)
|
|
||||||
state = "decreased";
|
|
||||||
MyGUI::TextBox* widget = addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), state, coord1, coord2);
|
|
||||||
|
|
||||||
for (int i=0; i<2; ++i)
|
|
||||||
{
|
{
|
||||||
ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size()-1-i], skillId);
|
getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx));
|
||||||
|
mAttributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::sAttributeIds[idx]), attribute));
|
||||||
|
attribute->setAttributeId(ESM::Attribute::sAttributeIds[idx]);
|
||||||
|
attribute->setAttributeValue(Widgets::MWAttribute::AttributeValue(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
mSkillWidgetMap[skillId] = widget;
|
// Setup skills
|
||||||
}
|
getWidget(mSkillView, "SkillView");
|
||||||
}
|
mSkillView->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||||
|
|
||||||
void ReviewDialog::updateSkillArea()
|
for (int i = 0; i < ESM::Skill::Length; ++i)
|
||||||
{
|
{
|
||||||
for (std::vector<MyGUI::Widget*>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
|
mSkillValues.insert(std::make_pair(i, MWMechanics::Stat<float>()));
|
||||||
|
mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
MyGUI::Button* backButton;
|
||||||
|
getWidget(backButton, "BackButton");
|
||||||
|
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
|
||||||
|
|
||||||
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::open()
|
||||||
{
|
{
|
||||||
MyGUI::Gui::getInstance().destroyWidget(*it);
|
WindowModal::open();
|
||||||
|
updateSkillArea();
|
||||||
}
|
}
|
||||||
mSkillWidgets.clear();
|
|
||||||
|
|
||||||
const int valueSize = 40;
|
void ReviewDialog::setPlayerName(const std::string &name)
|
||||||
MyGUI::IntCoord coord1(10, 0, mSkillView->getWidth() - (10 + valueSize) - 24, 18);
|
{
|
||||||
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
|
mNameWidget->setCaption(name);
|
||||||
|
}
|
||||||
|
|
||||||
if (!mMajorSkills.empty())
|
void ReviewDialog::setRace(const std::string &raceId)
|
||||||
addSkills(mMajorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
|
{
|
||||||
|
mRaceId = raceId;
|
||||||
|
|
||||||
if (!mMinorSkills.empty())
|
const ESM::Race *race =
|
||||||
addSkills(mMinorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().search(mRaceId);
|
||||||
|
if (race)
|
||||||
|
{
|
||||||
|
ToolTips::createRaceToolTip(mRaceWidget, race);
|
||||||
|
mRaceWidget->setCaption(race->mName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!mMiscSkills.empty())
|
void ReviewDialog::setClass(const ESM::Class& class_)
|
||||||
addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
|
{
|
||||||
|
mKlass = class_;
|
||||||
|
mClassWidget->setCaption(mKlass.mName);
|
||||||
|
ToolTips::createClassToolTip(mClassWidget, mKlass);
|
||||||
|
}
|
||||||
|
|
||||||
mClientHeight = coord1.top;
|
void ReviewDialog::setBirthSign(const std::string& signId)
|
||||||
|
{
|
||||||
|
mBirthSignId = signId;
|
||||||
|
|
||||||
|
const ESM::BirthSign *sign =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BirthSign>().search(mBirthSignId);
|
||||||
|
if (sign)
|
||||||
|
{
|
||||||
|
mBirthSignWidget->setCaption(sign->mName);
|
||||||
|
ToolTips::createBirthsignToolTip(mBirthSignWidget, mBirthSignId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<float>& value)
|
||||||
|
{
|
||||||
|
mHealth->setValue(value.getCurrent(), value.getModified());
|
||||||
|
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||||
|
mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<float>& value)
|
||||||
|
{
|
||||||
|
mMagicka->setValue(value.getCurrent(), value.getModified());
|
||||||
|
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||||
|
mMagicka->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<float>& value)
|
||||||
|
{
|
||||||
|
mFatigue->setValue(value.getCurrent(), value.getModified());
|
||||||
|
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||||
|
mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
|
||||||
|
{
|
||||||
|
std::map<int, Widgets::MWAttributePtr>::iterator attr = mAttributeWidgets.find(static_cast<int>(attributeId));
|
||||||
|
if (attr == mAttributeWidgets.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
attr->second->setAttributeValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value)
|
||||||
|
{
|
||||||
|
mSkillValues[skillId] = value;
|
||||||
|
MyGUI::TextBox* widget = mSkillWidgetMap[skillId];
|
||||||
|
if (widget)
|
||||||
|
{
|
||||||
|
float modified = value.getModified(), base = value.getBase();
|
||||||
|
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
|
||||||
|
std::string state = "normal";
|
||||||
|
if (modified > base)
|
||||||
|
state = "increased";
|
||||||
|
else if (modified < base)
|
||||||
|
state = "decreased";
|
||||||
|
|
||||||
|
widget->setCaption(text);
|
||||||
|
widget->_setWidgetState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
|
||||||
|
{
|
||||||
|
mMajorSkills = major;
|
||||||
|
mMinorSkills = minor;
|
||||||
|
|
||||||
|
// Update misc skills with the remaining skills not in major or minor
|
||||||
|
std::set<int> skillSet;
|
||||||
|
std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin()));
|
||||||
|
std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin()));
|
||||||
|
boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator end = ESM::Skill::sSkillIds.end();
|
||||||
|
mMiscSkills.clear();
|
||||||
|
for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::sSkillIds.begin(); it != end; ++it)
|
||||||
|
{
|
||||||
|
int skill = *it;
|
||||||
|
if (skillSet.find(skill) == skillSet.end())
|
||||||
|
mMiscSkills.push_back(skill);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSkillArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||||
|
{
|
||||||
|
MyGUI::ImageBox* separator = mSkillView->createWidget<MyGUI::ImageBox>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
|
||||||
|
separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||||
|
|
||||||
|
mSkillWidgets.push_back(separator);
|
||||||
|
|
||||||
|
coord1.top += separator->getHeight();
|
||||||
|
coord2.top += separator->getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||||
|
{
|
||||||
|
MyGUI::TextBox* groupWidget = mSkillView->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
|
||||||
|
groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||||
|
groupWidget->setCaption(label);
|
||||||
|
mSkillWidgets.push_back(groupWidget);
|
||||||
|
|
||||||
|
coord1.top += sLineHeight;
|
||||||
|
coord2.top += sLineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyGUI::TextBox* ReviewDialog::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||||
|
{
|
||||||
|
MyGUI::TextBox* skillNameWidget;
|
||||||
|
MyGUI::TextBox* skillValueWidget;
|
||||||
|
|
||||||
|
skillNameWidget = mSkillView->createWidget<MyGUI::TextBox>("SandText", coord1, MyGUI::Align::Default);
|
||||||
|
skillNameWidget->setCaption(text);
|
||||||
|
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||||
|
|
||||||
|
skillValueWidget = mSkillView->createWidget<MyGUI::TextBox>("SandTextRight", coord2, MyGUI::Align::Top | MyGUI::Align::Right);
|
||||||
|
skillValueWidget->setCaption(value);
|
||||||
|
skillValueWidget->_setWidgetState(state);
|
||||||
|
skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||||
|
|
||||||
|
mSkillWidgets.push_back(skillNameWidget);
|
||||||
|
mSkillWidgets.push_back(skillValueWidget);
|
||||||
|
|
||||||
|
coord1.top += sLineHeight;
|
||||||
|
coord2.top += sLineHeight;
|
||||||
|
|
||||||
|
return skillValueWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||||
|
{
|
||||||
|
MyGUI::TextBox* skillNameWidget;
|
||||||
|
|
||||||
|
skillNameWidget = mSkillView->createWidget<MyGUI::TextBox>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
|
||||||
|
skillNameWidget->setCaption(text);
|
||||||
|
skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
|
||||||
|
|
||||||
|
mSkillWidgets.push_back(skillNameWidget);
|
||||||
|
|
||||||
|
coord1.top += sLineHeight;
|
||||||
|
coord2.top += sLineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
|
||||||
|
{
|
||||||
|
// Add a line separator if there are items above
|
||||||
|
if (!mSkillWidgets.empty())
|
||||||
|
{
|
||||||
|
addSeparator(coord1, coord2);
|
||||||
|
}
|
||||||
|
|
||||||
|
addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2);
|
||||||
|
|
||||||
|
SkillList::const_iterator end = skills.end();
|
||||||
|
for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
|
||||||
|
{
|
||||||
|
int skillId = *it;
|
||||||
|
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
|
||||||
|
continue;
|
||||||
|
assert(skillId >= 0 && skillId < ESM::Skill::Length);
|
||||||
|
const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId];
|
||||||
|
const MWMechanics::Stat<float> &stat = mSkillValues.find(skillId)->second;
|
||||||
|
float base = stat.getBase();
|
||||||
|
float modified = stat.getModified();
|
||||||
|
|
||||||
|
std::string state = "normal";
|
||||||
|
if (modified > base)
|
||||||
|
state = "increased";
|
||||||
|
else if (modified < base)
|
||||||
|
state = "decreased";
|
||||||
|
MyGUI::TextBox* widget = addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), state, coord1, coord2);
|
||||||
|
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
{
|
||||||
|
ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size()-1-i], skillId);
|
||||||
|
}
|
||||||
|
|
||||||
|
mSkillWidgetMap[skillId] = widget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::updateSkillArea()
|
||||||
|
{
|
||||||
|
for (std::vector<MyGUI::Widget*>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
|
||||||
|
{
|
||||||
|
MyGUI::Gui::getInstance().destroyWidget(*it);
|
||||||
|
}
|
||||||
|
mSkillWidgets.clear();
|
||||||
|
|
||||||
|
const int valueSize = 40;
|
||||||
|
MyGUI::IntCoord coord1(10, 0, mSkillView->getWidth() - (10 + valueSize) - 24, 18);
|
||||||
|
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
|
||||||
|
|
||||||
|
if (!mMajorSkills.empty())
|
||||||
|
addSkills(mMajorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
|
||||||
|
|
||||||
|
if (!mMinorSkills.empty())
|
||||||
|
addSkills(mMinorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
|
||||||
|
|
||||||
|
if (!mMiscSkills.empty())
|
||||||
|
addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
|
||||||
|
|
||||||
|
mClientHeight = coord1.top;
|
||||||
|
|
||||||
|
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), mClientHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
// widget controls
|
||||||
|
|
||||||
|
void ReviewDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventDone(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::onBackClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::onNameClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventActivateDialog(NAME_DIALOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::onRaceClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventActivateDialog(RACE_DIALOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::onClassClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventActivateDialog(CLASS_DIALOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
eventActivateDialog(BIRTHSIGN_DIALOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||||
|
{
|
||||||
|
if (mSkillView->getViewOffset().top + _rel*0.3 > 0)
|
||||||
|
mSkillView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||||
|
else
|
||||||
|
mSkillView->setViewOffset(MyGUI::IntPoint(0, mSkillView->getViewOffset().top + _rel*0.3));
|
||||||
|
}
|
||||||
|
|
||||||
mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), mClientHeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
// widget controls
|
|
||||||
|
|
||||||
void ReviewDialog::onOkClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventDone(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::onBackClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::onNameClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventActivateDialog(NAME_DIALOG);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::onRaceClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventActivateDialog(RACE_DIALOG);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::onClassClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventActivateDialog(CLASS_DIALOG);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
eventActivateDialog(BIRTHSIGN_DIALOG);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
|
||||||
{
|
|
||||||
if (mSkillView->getViewOffset().top + _rel*0.3 > 0)
|
|
||||||
mSkillView->setViewOffset(MyGUI::IntPoint(0, 0));
|
|
||||||
else
|
|
||||||
mSkillView->setViewOffset(MyGUI::IntPoint(0, mSkillView->getViewOffset().top + _rel*0.3));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,71 +10,73 @@
|
||||||
|
|
||||||
#include "formatting.hpp"
|
#include "formatting.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
|
|
||||||
ScrollWindow::ScrollWindow ()
|
|
||||||
: WindowBase("openmw_scroll.layout")
|
|
||||||
, mTakeButtonShow(true)
|
|
||||||
, mTakeButtonAllowed(true)
|
|
||||||
{
|
{
|
||||||
getWidget(mTextView, "TextView");
|
|
||||||
|
|
||||||
getWidget(mCloseButton, "CloseButton");
|
ScrollWindow::ScrollWindow ()
|
||||||
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onCloseButtonClicked);
|
: WindowBase("openmw_scroll.layout")
|
||||||
|
, mTakeButtonShow(true)
|
||||||
|
, mTakeButtonAllowed(true)
|
||||||
|
{
|
||||||
|
getWidget(mTextView, "TextView");
|
||||||
|
|
||||||
getWidget(mTakeButton, "TakeButton");
|
getWidget(mCloseButton, "CloseButton");
|
||||||
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
|
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onCloseButtonClicked);
|
||||||
|
|
||||||
center();
|
getWidget(mTakeButton, "TakeButton");
|
||||||
}
|
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
|
||||||
|
|
||||||
void ScrollWindow::open (MWWorld::Ptr scroll)
|
center();
|
||||||
{
|
}
|
||||||
// no 3d sounds because the object could be in a container.
|
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
void ScrollWindow::open (MWWorld::Ptr scroll)
|
||||||
|
{
|
||||||
mScroll = scroll;
|
// no 3d sounds because the object could be in a container.
|
||||||
|
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||||
MWWorld::LiveCellRef<ESM::Book> *ref = mScroll.get<ESM::Book>();
|
|
||||||
|
mScroll = scroll;
|
||||||
BookTextParser parser;
|
|
||||||
MyGUI::IntSize size = parser.parse(ref->mBase->mText, mTextView, 390);
|
MWWorld::LiveCellRef<ESM::Book> *ref = mScroll.get<ESM::Book>();
|
||||||
|
|
||||||
if (size.height > mTextView->getSize().height)
|
BookTextParser parser;
|
||||||
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
|
MyGUI::IntSize size = parser.parse(ref->mBase->mText, mTextView, 390);
|
||||||
else
|
|
||||||
mTextView->setCanvasSize(410, mTextView->getSize().height);
|
if (size.height > mTextView->getSize().height)
|
||||||
|
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
|
||||||
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
|
else
|
||||||
|
mTextView->setCanvasSize(410, mTextView->getSize().height);
|
||||||
setTakeButtonShow(true);
|
|
||||||
}
|
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
|
||||||
|
|
||||||
void ScrollWindow::setTakeButtonShow(bool show)
|
setTakeButtonShow(true);
|
||||||
{
|
}
|
||||||
mTakeButtonShow = show;
|
|
||||||
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
void ScrollWindow::setTakeButtonShow(bool show)
|
||||||
}
|
{
|
||||||
|
mTakeButtonShow = show;
|
||||||
void ScrollWindow::setInventoryAllowed(bool allowed)
|
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
||||||
{
|
}
|
||||||
mTakeButtonAllowed = allowed;
|
|
||||||
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
void ScrollWindow::setInventoryAllowed(bool allowed)
|
||||||
}
|
{
|
||||||
|
mTakeButtonAllowed = allowed;
|
||||||
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
|
||||||
{
|
}
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
|
||||||
|
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
|
{
|
||||||
}
|
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
|
||||||
|
|
||||||
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
|
||||||
{
|
}
|
||||||
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
|
|
||||||
|
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
|
||||||
MWWorld::ActionTake take(mScroll);
|
{
|
||||||
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
|
MWWorld::ActionTake take(mScroll);
|
||||||
|
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,68 +3,71 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
|
|
||||||
TextInputDialog::TextInputDialog()
|
|
||||||
: WindowModal("openmw_text_input.layout")
|
|
||||||
{
|
{
|
||||||
// Centre dialog
|
|
||||||
center();
|
|
||||||
|
|
||||||
getWidget(mTextEdit, "TextEdit");
|
TextInputDialog::TextInputDialog()
|
||||||
mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted);
|
: WindowModal("openmw_text_input.layout")
|
||||||
|
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked);
|
|
||||||
|
|
||||||
// Make sure the edit box has focus
|
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextInputDialog::setNextButtonShow(bool shown)
|
|
||||||
{
|
|
||||||
MyGUI::Button* okButton;
|
|
||||||
getWidget(okButton, "OKButton");
|
|
||||||
|
|
||||||
if (shown)
|
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
|
|
||||||
else
|
|
||||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextInputDialog::setTextLabel(const std::string &label)
|
|
||||||
{
|
|
||||||
setText("LabelT", label);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextInputDialog::open()
|
|
||||||
{
|
|
||||||
WindowModal::open();
|
|
||||||
// Make sure the edit box has focus
|
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
|
|
||||||
}
|
|
||||||
|
|
||||||
// widget controls
|
|
||||||
|
|
||||||
void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
if (mTextEdit->getCaption() == "")
|
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
|
// Centre dialog
|
||||||
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
|
center();
|
||||||
}
|
|
||||||
else
|
|
||||||
eventDone(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
|
getWidget(mTextEdit, "TextEdit");
|
||||||
{
|
mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted);
|
||||||
if (mTextEdit->getCaption() == "")
|
|
||||||
{
|
MyGUI::Button* okButton;
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
|
getWidget(okButton, "OKButton");
|
||||||
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
|
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked);
|
||||||
|
|
||||||
|
// Make sure the edit box has focus
|
||||||
|
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
eventDone(this);
|
void TextInputDialog::setNextButtonShow(bool shown)
|
||||||
|
{
|
||||||
|
MyGUI::Button* okButton;
|
||||||
|
getWidget(okButton, "OKButton");
|
||||||
|
|
||||||
|
if (shown)
|
||||||
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
|
||||||
|
else
|
||||||
|
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextInputDialog::setTextLabel(const std::string &label)
|
||||||
|
{
|
||||||
|
setText("LabelT", label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextInputDialog::open()
|
||||||
|
{
|
||||||
|
WindowModal::open();
|
||||||
|
// Make sure the edit box has focus
|
||||||
|
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// widget controls
|
||||||
|
|
||||||
|
void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
if (mTextEdit->getCaption() == "")
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
|
||||||
|
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
eventDone(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
|
||||||
|
{
|
||||||
|
if (mTextEdit->getCaption() == "")
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
|
||||||
|
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
eventDone(this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -2,25 +2,26 @@
|
||||||
|
|
||||||
#include "exposedwindow.hpp"
|
#include "exposedwindow.hpp"
|
||||||
|
|
||||||
using namespace MWGui;
|
namespace MWGui
|
||||||
|
|
||||||
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout)
|
|
||||||
: WindowBase(parLayout), mPinned(false), mVisible(false)
|
|
||||||
{
|
{
|
||||||
ExposedWindow* window = static_cast<ExposedWindow*>(mMainWidget);
|
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout)
|
||||||
mPinButton = window->getSkinWidget ("Button");
|
: WindowBase(parLayout), mPinned(false), mVisible(false)
|
||||||
|
{
|
||||||
|
ExposedWindow* window = static_cast<ExposedWindow*>(mMainWidget);
|
||||||
|
mPinButton = window->getSkinWidget ("Button");
|
||||||
|
|
||||||
mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked);
|
mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
|
void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
mPinned = !mPinned;
|
mPinned = !mPinned;
|
||||||
|
|
||||||
if (mPinned)
|
if (mPinned)
|
||||||
mPinButton->changeWidgetSkin ("PinDown");
|
mPinButton->changeWidgetSkin ("PinDown");
|
||||||
else
|
else
|
||||||
mPinButton->changeWidgetSkin ("PinUp");
|
mPinButton->changeWidgetSkin ("PinUp");
|
||||||
|
|
||||||
onPinToggled();
|
onPinToggled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue