1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 20:53:50 +00:00

No more using namespace

This commit is contained in:
Britt Mathis 2013-04-17 18:56:48 -04:00
parent 60fadaeaf0
commit 7eee86ab66
22 changed files with 8609 additions and 8557 deletions

View file

@ -9,237 +9,239 @@
#include "widgets.hpp"
using namespace MWGui;
using namespace Widgets;
namespace
{
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;
}
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;
}
}
BirthDialog::BirthDialog()
: WindowModal("openmw_chargen_birth.layout")
namespace MWGui
{
// 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");
mBirthList->setScrollVisible(true);
mBirthList->eventListSelectAccept += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
mBirthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
mBirthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth);
getWidget(mBirthImage, "BirthsignImage");
MyGUI::Button* backButton;
getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
getWidget(mBirthList, "BirthsignList");
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* okButton;
getWidget(okButton, "OKButton");
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked);
MyGUI::Button* backButton;
getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked);
updateBirths();
updateSpells();
}
void BirthDialog::setNextButtonShow(bool shown)
{
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
if (shown)
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", ""));
else
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", ""));
}
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked);
void BirthDialog::open()
{
WindowModal::open();
updateBirths();
updateSpells();
}
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)
void BirthDialog::setNextButtonShow(bool shown)
{
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);
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)
if (boost::iequals(*mBirthList->getItemDataAt<std::string>(i), birthId))
{
const std::string &spellId = *it;
spellWidget = mSpellArea->createWidget<MWSpell>("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast<std::string>(i));
spellWidget->setSpellId(spellId);
mBirthList->setIndexSelected(i);
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
break;
}
}
mSpellItems.push_back(spellWidget);
coord.top += lineHeight;
updateSpells();
}
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) ? MWEffectList::EF_Constant : 0);
coord.top = spellCoord.top;
// widget controls
++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;
}
}
}
}
}

View file

@ -12,148 +12,151 @@
#include "formatting.hpp"
using namespace MWGui;
BookWindow::BookWindow ()
: WindowBase("openmw_book.layout")
, mTakeButtonShow(true)
, mTakeButtonAllowed(true)
namespace MWGui
{
getWidget(mCloseButton, "CloseButton");
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);
getWidget(mTakeButton, "TakeButton");
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onTakeButtonClicked);
getWidget(mNextPageButton, "NextPageBTN");
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)
BookWindow::BookWindow ()
: WindowBase("openmw_book.layout")
, mTakeButtonShow(true)
, mTakeButtonAllowed(true)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
mPages.clear();
}
getWidget(mCloseButton, "CloseButton");
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onCloseButtonClicked);
void BookWindow::open (MWWorld::Ptr book)
{
mBook = book;
getWidget(mTakeButton, "TakeButton");
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BookWindow::onTakeButtonClicked);
clearPages();
mCurrentPage = 0;
getWidget(mNextPageButton, "NextPageBTN");
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;
std::vector<std::string> results = parser.split(ref->mBase->mText, mLeftPage->getSize().width, mLeftPage->getSize().height);
getWidget(mLeftPage, "LeftPage");
getWidget(mRightPage, "RightPage");
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;
center();
}
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())
void BookWindow::clearPages()
{
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
for (std::vector<MyGUI::Widget*>::iterator it=mPages.begin();
it!=mPages.end(); ++it)
{
(*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

View file

@ -278,16 +278,15 @@ namespace MWGui
std::string Console::complete( std::string input, std::vector<std::string> &matches )
{
using namespace std;
string output=input;
string tmp=input;
std::string output = input;
std::string tmp = input;
bool has_front_quote = false;
/* Does the input string contain things that don't have to be completed? If yes erase them. */
/* Are there quotation marks? */
if( tmp.find('"') != string::npos ) {
if( tmp.find('"') != std::string::npos ) {
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 == '"' )
numquotes++;
}
@ -299,7 +298,7 @@ namespace MWGui
}
else {
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);
}
else {
@ -311,7 +310,7 @@ namespace MWGui
/* No quotation marks. Are there spaces?*/
else {
size_t rpos;
if( (rpos=tmp.rfind(' ')) != string::npos ) {
if( (rpos=tmp.rfind(' ')) != std::string::npos ) {
if( rpos == 0 ) {
tmp.clear();
}
@ -330,7 +329,7 @@ namespace MWGui
}
/* 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;
/* Is the string shorter than the input string? If yes skip it. */
@ -338,7 +337,7 @@ namespace MWGui
continue;
/* 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) ) {
string_different=true;
break;
@ -361,24 +360,24 @@ namespace MWGui
/* Only one match. We're done. */
if( matches.size() == 1 ) {
/* 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 )
output.append(string("\""));
return output.append(matches.front() + string("\" "));
output.append(std::string("\""));
return output.append(matches.front() + std::string("\" "));
}
else if( has_front_quote ) {
return output.append(matches.front() + string("\" "));
return output.append(matches.front() + std::string("\" "));
}
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. */
int i = tmp.length();
for(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::string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) {
for(std::vector<std::string>::iterator it=matches.begin(); it < matches.end();++it) {
if( tolower((*it)[i]) != tolower(*iter) ) {
/* Append the longest match to the end of the output string*/
output.append(matches.front().substr( 0, i));

File diff suppressed because it is too large Load diff

View file

@ -19,521 +19,521 @@
#include "inventorywindow.hpp"
#include "travelwindow.hpp"
using namespace MWGui;
using namespace Widgets;
/**
*Copied from the internet.
*/
namespace {
std::string lower_string(const std::string& str)
namespace
{
std::string lowerCase = Misc::StringUtils::lowerCase (str);
return lowerCase;
}
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
return lower_string(str).find(lower_string(substr),pos);
}
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)
std::string lower_string(const std::string& str)
{
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-10);
type = MWBase::MechanicsManager::PT_Bribe10;
}
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;
std::string lowerCase = Misc::StringUtils::lowerCase (str);
return lowerCase;
}
MWBase::Environment::get().getDialogueManager()->persuade(type);
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")
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
{
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);
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));
}
MWBase::Environment::get().getWindowManager()->getTradeWindow()->addOrRemoveGold(-10);
type = MWBase::MechanicsManager::PT_Bribe10;
}
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;
}
if(color == "#572D21")
MWBase::Environment::get().getDialogueManager()->questionAnswered(lower_string(key));
}
}
MWBase::Environment::get().getDialogueManager()->persuade(type);
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;
setVisible(false);
}
if (id >= separatorPos)
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
else
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);
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 =
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);
MWBase::Environment::get().getWindowManager()->showCompanionWindow(mPtr);
mTopicsList->removeItem(keyWord);
}
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);
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);
MyGUI::TextIterator iterator (str);
MyGUI::UString colour;
while(iterator.moveNext())
{
size_t iteratorPos = iterator.getPosition();
iterator.getTagColour(colour);
if (iteratorPos == pos)
break;
}
if (colour == color1)
return;
}
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)
{
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)
std::string DialogueWindow::parseText(const std::string& text)
{
mTopicsList->addItem(*it);
}
mTopicsList->adjustSize();
}
bool separatorReached = false; // only parse topics that are below the separator (this prevents actions like "Barter" that are not topics from getting blue-colored)
void DialogueWindow::removeKeyword(std::string keyWord)
{
if(mTopicsList->hasItem(keyWord))
{
mTopicsList->removeItem(keyWord);
}
mTopicsList->adjustSize();
}
std::vector<std::string> topics;
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)
{
// do not add color if this portion of text is already colored.
bool hasSeparator = false;
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
{
MyGUI::TextIterator iterator (str);
MyGUI::UString colour;
while(iterator.moveNext())
{
size_t iteratorPos = iterator.getPosition();
iterator.getTagColour(colour);
if (iteratorPos == pos)
break;
}
if (colour == color1)
return;
if (mTopicsList->getItemNameAt(i) == "")
hasSeparator = true;
}
str.insert(pos,color1);
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)
for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
{
size_t asterisk_count = MWDialogue::RemovePseudoAsterisks(hypertext[i].mText);
std::string standardForm = hypertext[i].mText;
for(; asterisk_count > 0; --asterisk_count)
standardForm.append("*");
std::string keyWord = mTopicsList->getItemNameAt(i);
if (separatorReached || !hasSeparator)
topics.push_back(keyWord);
else if (keyWord == "")
separatorReached = true;
}
standardForm =
MWBase::Environment::get().getWindowManager()->
getTranslationDataStorage().topicStandardForm(standardForm);
// sort by length to make sure longer topics are replaced first
std::sort(topics.begin(), topics.end(), sortByLength);
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();
mHyperLinks[historySize+hypertextPos].mTrueValue = lower_string(standardForm);
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
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)
{
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)
void DialogueWindow::addText(std::string text)
{
std::string item = mTopicsList->getItemNameAt(i);
if (lower_string(item) == text)
text = item;
mHistory->addDialogText("#B29154"+parseText(text)+"#B29154");
}
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())
void DialogueWindow::addMessageBox(const std::string& text)
{
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");
mHistory->addDialogText("\n#FFFFFF"+text+"#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())
void DialogueWindow::addTitle(std::string text)
{
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");
// 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);
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");
}
}
}

View file

@ -12,65 +12,67 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
using namespace MWGui;
using namespace Widgets;
MyGUI::UString DialogueHistory::getColorAtPos(size_t _pos)
namespace MWGui
{
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)
{
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())
MyGUI::UString DialogueHistory::getColorAtPos(size_t _pos)
{
size_t pos = iterator.getPosition();
iterator.getTagColour(colour);
if(colour != colour2)
MyGUI::UString colour = MyGUI::TextIterator::convertTagColour(getTextColour());
MyGUI::TextIterator iterator(getCaption());
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)
{
MyGUI::UString head("\n#D8C09A");
head.append(parText);
head.append("#B29154\n");
addText(head);
}
void DialogueHistory::addDialogHeading(const MyGUI::UString& parText)
{
MyGUI::UString head("\n#D8C09A");
head.append(parText);
head.append("#B29154\n");
addText(head);
}
void DialogueHistory::addDialogText(const MyGUI::UString& parText)
{
addText(parText);
addText("\n");
}
void DialogueHistory::addDialogText(const MyGUI::UString& parText)
{
addText(parText);
addText("\n");
}

View file

@ -9,8 +9,6 @@
#include <boost/lexical_cast.hpp>
#include <OgreUTFString.h>
using namespace MWGui;
namespace
{
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
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())
std::vector<std::string> BookTextParser::split(std::string utf8Text, const int width, const int height)
{
// read in characters until we have exceeded the size, or run out of text
int currentWidth = 0;
int currentHeight = 0;
using Ogre::UTFString;
std::vector<std::string> result;
size_t currentWordStart = 0;
size_t index = 0;
while (currentHeight <= height - spacing && index < text.size())
MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor
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())
{
const UTFString::unicode_char ch = text.getChar(index);
if (ch == LEFT_ANGLE)
{
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();
// read in characters until we have exceeded the size, or run out of text
int currentWidth = 0;
int currentHeight = 0;
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;
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())
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");
++i;
c = text[i];
const std::string tag = text.substr(tagStart, tagEnd - tagStart).asUTF8();
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
{
tagStart = i;
break;
}
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()));
}
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

View file

@ -5,159 +5,165 @@
#include <MyGUI_ImageBox.h>
#include <MyGUI_ScrollBar.h>
using namespace MWGui;
using namespace MWGui::Widgets;
MWList::MWList() :
mClient(0)
, mScrollView(0)
, mItemHeight(0)
namespace MWGui
{
}
void MWList::initialiseOverride()
{
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())
namespace Widgets
{
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 != "")
MWList::MWList() :
mClient(0)
, mScrollView(0)
, mItemHeight(0)
{
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",
MyGUI::IntCoord(2, mItemHeight, mScrollView->getWidth()-4, 18),
MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch);
separator->setNeedMouseFocus(false);
Base::initialiseOverride();
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();
}

View file

@ -13,430 +13,433 @@
#include "widgets.hpp"
using 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)
namespace MWGui
{
}
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)
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)
{
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",
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)
for (int my=0; my<3; ++my)
{
map->setNeedMouseFocus(false);
fog->setNeedMouseFocus(false);
}
MyGUI::ImageBox* map = mLocalMap->createWidget<MyGUI::ImageBox>("ImageBox",
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);
mFogWidgets.push_back(fog);
}
}
}
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");
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
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)
if (!mMapDragAndDrop)
{
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);
map->setNeedMouseFocus(false);
fog->setNeedMouseFocus(false);
}
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
{
Ogre::Vector2 position (marker.x, marker.y);
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
box->setImageTexture("black.png");
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;
mCurX = x;
mCurY = y;
mChanged = false;
mInterior = interior;
mCurX = x;
mCurY = y;
mChanged = false;
// fog of war
applyFogOfWar();
// fog of war
applyFogOfWar();
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets
// based on the last setImageTexture call
std::string tex = "textures\\compass.dds";
mCompass->setImageTexture("");
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");
// set the compass texture again, because MyGUI determines sorting of ImageBox widgets
// based on the last setImageTexture call
std::string tex = "textures\\compass.dds";
mCompass->setImageTexture("");
mCompass->setImageTexture(tex);
}
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 ())
void LocalMapBase::setPlayerPos(const float x, const float y)
{
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>();
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
float angle = std::atan2(dir.x, dir.y);
float angle = std::atan2(x,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);
mLastDirectionX = x;
mLastDirectionY = y;
}
}
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");
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 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}");
}

View file

@ -5,411 +5,414 @@
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/inputmanager.hpp"
using namespace MWGui;
MessageBoxManager::MessageBoxManager ()
namespace MWGui
{
// defines
mMessageBoxSpeed = 0.1;
mInterMessageBoxe = NULL;
}
void MessageBoxManager::onFrame (float frameDuration)
{
std::vector<MessageBoxManagerTimer>::iterator it;
for(it = mTimers.begin(); it != mTimers.end();)
MessageBoxManager::MessageBoxManager ()
{
// if this messagebox is already deleted, remove the timer and move on
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
{
it = mTimers.erase(it);
continue;
}
// defines
mMessageBoxSpeed = 0.1;
mInterMessageBoxe = NULL;
}
it->current += frameDuration;
if(it->current >= it->max)
void MessageBoxManager::onFrame (float frameDuration)
{
std::vector<MessageBoxManagerTimer>::iterator it;
for(it = mTimers.begin(); it != mTimers.end();)
{
it->messageBox->mMarkedToDelete = true;
if(*mMessageBoxes.begin() == it->messageBox) // if this box is the last one
// if this messagebox is already deleted, remove the timer and move on
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end())
{
// 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())
it = mTimers.erase(it);
continue;
}
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);
it2 = mMessageBoxes.erase(it2);
}
else {
(*it2)->update(height);
height += (*it2)->getHeight();
it2++;
if((*it2)->mMarkedToDelete)
{
delete (*it2);
it2 = mMessageBoxes.erase(it2);
}
else {
(*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
{
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) {
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)
void InteractiveMessageBox::enterPressed()
{
(*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;
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;
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
{
buttonActivated(*button);
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
break;
}
}
}
else
void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed)
{
// 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;
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)
{
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(*button == pressed)
{
mButtonPressed = index;
mMessageBoxManager.onButtonPressed(mButtonPressed);
return;
}
index++;
}
}
}
void InteractiveMessageBox::enterPressed()
{
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)
int InteractiveMessageBox::readPressedButton ()
{
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
{
buttonActivated(*button);
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
break;
}
int pressed = mButtonPressed;
mButtonPressed = -1;
return pressed;
}
}
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;
}

View file

@ -10,435 +10,437 @@
#include "tooltips.hpp"
using namespace MWGui;
using namespace Widgets;
namespace
{
int wrap(int index, int max)
{
if (index < 0)
return max - 1;
else if (index >= max)
return 0;
else
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();
int wrap(int index, int max)
{
if (index < 0)
return max - 1;
else if (index >= max)
return 0;
else
return index;
}
while (store.search(prefix + suffix) != 0);
if (count == 0 && part == "hair") {
count = -1;
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();
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
}
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()
: WindowModal("openmw_chargen_race.layout")
, mGenderIndex(0)
, mFaceIndex(0)
, mHairIndex(0)
, mFaceCount(10)
, mHairCount(14)
, mCurrentAngle(0)
namespace MWGui
{
// 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)
RaceDialog::RaceDialog()
: WindowModal("openmw_chargen_race.layout")
, mGenderIndex(0)
, mFaceIndex(0)
, mHairIndex(0)
, mFaceCount(10)
, mHairCount(14)
, mCurrentAngle(0)
{
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);
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
break;
if (boost::iequals(*mRaceList->getItemDataAt<std::string>(i), raceId))
{
mRaceList->setIndexSelected(i);
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();
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)
void RaceDialog::updateSkills()
{
bool playable = it->mData.mFlags & ESM::Race::Playable;
if (!playable) // Only display playable races
continue;
for (std::vector<MyGUI::Widget*>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
mSkillItems.clear();
mRaceList->addItem(it->mName, it->mId);
if (boost::iequals(it->mId, mCurrentRaceId))
mRaceList->setIndexSelected(index);
++index;
}
}
void RaceDialog::updateSkills()
{
for (std::vector<MyGUI::Widget*>::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
mSkillItems.clear();
if (mCurrentRaceId.empty())
return;
MWSkillPtr skillWidget;
const int lineHeight = 18;
MyGUI::IntCoord coord1(0, 0, mSkillList->getWidth(), 18);
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mCurrentRaceId);
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)
{
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;
if (mCurrentRaceId.empty())
return;
Widgets::MWSkillPtr skillWidget;
const int lineHeight = 18;
MyGUI::IntCoord coord1(0, 0, mSkillList->getWidth(), 18);
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mCurrentRaceId);
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)
{
int skillId = race->mData.mBonus[i].mSkill;
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
continue;
skillWidget = mSkillList->createWidget<Widgets::MWSkill>("MW_StatNameValue", coord1, MyGUI::Align::Default,
std::string("Skill") + boost::lexical_cast<std::string>(i));
skillWidget->setSkillNumber(skillId);
skillWidget->setSkillValue(Widgets::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;
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;
}
}
}

View file

@ -11,357 +11,359 @@
#undef min
#undef max
using namespace MWGui;
using namespace Widgets;
const int ReviewDialog::sLineHeight = 18;
ReviewDialog::ReviewDialog()
: WindowModal("openmw_chargen_review.layout")
, mLastPos(0)
namespace MWGui
{
// Centre dialog
center();
// Setup static stats
MyGUI::Button* button;
getWidget(mNameWidget, "NameText");
getWidget(button, "NameButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
const int ReviewDialog::sLineHeight = 18;
getWidget(mRaceWidget, "RaceText");
getWidget(button, "RaceButton");
adjustButtonSize(button);
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)
ReviewDialog::ReviewDialog()
: WindowModal("openmw_chargen_review.layout")
, mLastPos(0)
{
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(MWAttribute::AttributeValue(0, 0));
}
// Centre dialog
center();
// Setup skills
getWidget(mSkillView, "SkillView");
mSkillView->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel);
// Setup static stats
MyGUI::Button* button;
getWidget(mNameWidget, "NameText");
getWidget(button, "NameButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);;
for (int i = 0; i < ESM::Skill::Length; ++i)
{
mSkillValues.insert(std::make_pair(i, MWMechanics::Stat<float>()));
mSkillWidgetMap.insert(std::make_pair(i, static_cast<MyGUI::TextBox*> (0)));
}
getWidget(mRaceWidget, "RaceText");
getWidget(button, "RaceButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);;
MyGUI::Button* backButton;
getWidget(backButton, "BackButton");
backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked);
getWidget(mClassWidget, "ClassText");
getWidget(button, "ClassButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);;
MyGUI::Button* okButton;
getWidget(okButton, "OKButton");
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
}
getWidget(mBirthSignWidget, "SignText");
getWidget(button, "SignButton");
adjustButtonSize(button);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);;
void ReviewDialog::open()
{
WindowModal::open();
updateSkillArea();
}
// Setup dynamic stats
getWidget(mHealth, "Health");
mHealth->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sHealth", ""));
mHealth->setValue(45, 45);
void ReviewDialog::setPlayerName(const std::string &name)
{
mNameWidget->setCaption(name);
}
getWidget(mMagicka, "Magicka");
mMagicka->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sMagic", ""));
mMagicka->setValue(50, 50);
void ReviewDialog::setRace(const std::string &raceId)
{
mRaceId = raceId;
getWidget(mFatigue, "Fatigue");
mFatigue->setTitle(MWBase::Environment::get().getWindowManager()->getGameSettingString("sFatigue", ""));
mFatigue->setValue(160, 160);
const ESM::Race *race =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().search(mRaceId);
if (race)
{
ToolTips::createRaceToolTip(mRaceWidget, race);
mRaceWidget->setCaption(race->mName);
}
}
// Setup attributes
void ReviewDialog::setClass(const ESM::Class& class_)
{
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)
Widgets::MWAttributePtr attribute;
for (int idx = 0; idx < ESM::Attribute::Length; ++idx)
{
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 (std::vector<MyGUI::Widget*>::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it)
for (int i = 0; i < ESM::Skill::Length; ++i)
{
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;
MyGUI::IntCoord coord1(10, 0, mSkillView->getWidth() - (10 + valueSize) - 24, 18);
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
void ReviewDialog::setPlayerName(const std::string &name)
{
mNameWidget->setCaption(name);
}
if (!mMajorSkills.empty())
addSkills(mMajorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
void ReviewDialog::setRace(const std::string &raceId)
{
mRaceId = raceId;
if (!mMinorSkills.empty())
addSkills(mMinorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
const ESM::Race *race =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().search(mRaceId);
if (race)
{
ToolTips::createRaceToolTip(mRaceWidget, race);
mRaceWidget->setCaption(race->mName);
}
}
if (!mMiscSkills.empty())
addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
void ReviewDialog::setClass(const ESM::Class& class_)
{
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));
}

View file

@ -10,71 +10,73 @@
#include "formatting.hpp"
using namespace MWGui;
ScrollWindow::ScrollWindow ()
: WindowBase("openmw_scroll.layout")
, mTakeButtonShow(true)
, mTakeButtonAllowed(true)
namespace MWGui
{
getWidget(mTextView, "TextView");
getWidget(mCloseButton, "CloseButton");
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onCloseButtonClicked);
ScrollWindow::ScrollWindow ()
: WindowBase("openmw_scroll.layout")
, mTakeButtonShow(true)
, mTakeButtonAllowed(true)
{
getWidget(mTextView, "TextView");
getWidget(mTakeButton, "TakeButton");
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
getWidget(mCloseButton, "CloseButton");
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onCloseButtonClicked);
center();
}
void ScrollWindow::open (MWWorld::Ptr scroll)
{
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
mScroll = scroll;
MWWorld::LiveCellRef<ESM::Book> *ref = mScroll.get<ESM::Book>();
BookTextParser parser;
MyGUI::IntSize size = parser.parse(ref->mBase->mText, mTextView, 390);
if (size.height > mTextView->getSize().height)
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
else
mTextView->setCanvasSize(410, mTextView->getSize().height);
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
setTakeButtonShow(true);
}
void ScrollWindow::setTakeButtonShow(bool show)
{
mTakeButtonShow = show;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
void ScrollWindow::setInventoryAllowed(bool allowed)
{
mTakeButtonAllowed = allowed;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
}
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
MWWorld::ActionTake take(mScroll);
take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
getWidget(mTakeButton, "TakeButton");
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
center();
}
void ScrollWindow::open (MWWorld::Ptr scroll)
{
// no 3d sounds because the object could be in a container.
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
mScroll = scroll;
MWWorld::LiveCellRef<ESM::Book> *ref = mScroll.get<ESM::Book>();
BookTextParser parser;
MyGUI::IntSize size = parser.parse(ref->mBase->mText, mTextView, 390);
if (size.height > mTextView->getSize().height)
mTextView->setCanvasSize(MyGUI::IntSize(410, size.height));
else
mTextView->setCanvasSize(410, mTextView->getSize().height);
mTextView->setViewOffset(MyGUI::IntPoint(0,0));
setTakeButtonShow(true);
}
void ScrollWindow::setTakeButtonShow(bool show)
{
mTakeButtonShow = show;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
void ScrollWindow::setInventoryAllowed(bool allowed)
{
mTakeButtonAllowed = allowed;
mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed);
}
void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound ("scroll", 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll);
}
void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender)
{
MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack);
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

View file

@ -3,68 +3,71 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
using namespace MWGui;
TextInputDialog::TextInputDialog()
: WindowModal("openmw_text_input.layout")
namespace MWGui
{
// Centre dialog
center();
getWidget(mTextEdit, "TextEdit");
mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted);
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() == "")
TextInputDialog::TextInputDialog()
: WindowModal("openmw_text_input.layout")
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
}
else
eventDone(this);
}
// Centre dialog
center();
void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
{
if (mTextEdit->getCaption() == "")
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
getWidget(mTextEdit, "TextEdit");
mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted);
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);
}
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

View file

@ -2,25 +2,26 @@
#include "exposedwindow.hpp"
using namespace MWGui;
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout)
: WindowBase(parLayout), mPinned(false), mVisible(false)
namespace MWGui
{
ExposedWindow* window = static_cast<ExposedWindow*>(mMainWidget);
mPinButton = window->getSkinWidget ("Button");
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout)
: WindowBase(parLayout), mPinned(false), mVisible(false)
{
ExposedWindow* window = static_cast<ExposedWindow*>(mMainWidget);
mPinButton = window->getSkinWidget ("Button");
mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked);
}
void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
{
mPinned = !mPinned;
if (mPinned)
mPinButton->changeWidgetSkin ("PinDown");
else
mPinButton->changeWidgetSkin ("PinUp");
onPinToggled();
mPinButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonClicked);
}
void WindowPinnableBase::onPinButtonClicked(MyGUI::Widget* _sender)
{
mPinned = !mPinned;
if (mPinned)
mPinButton->changeWidgetSkin ("PinDown");
else
mPinButton->changeWidgetSkin ("PinUp");
onPinToggled();
}
}