1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-10 15:39:02 +00:00
OpenMW/apps/openmw/mwgui/widgets.cpp

410 lines
11 KiB
C++

#include "widgets.hpp"
#include "window_manager.hpp"
#include "components/esm_store/store.hpp"
#include <boost/lexical_cast.hpp>
#undef min
#undef max
using namespace MWGui;
using namespace MWGui::Widgets;
/* Helper functions */
/*
* Fixes the filename of a texture path to use the correct .dds extension.
* This is needed on some ESM entries which point to a .tga file instead.
*/
void MWGui::Widgets::fixTexturePath(std::string &path)
{
int offset = path.rfind(".");
if (offset < 0)
return;
path.replace(offset, path.length() - offset, ".dds");
}
/* MWSkill */
MWSkill::MWSkill()
: manager(nullptr)
, skillId(ESM::Skill::Length)
, skillNameWidget(nullptr)
, skillValueWidget(nullptr)
{
}
void MWSkill::setSkillId(ESM::Skill::SkillEnum skill)
{
skillId = skill;
updateWidgets();
}
void MWSkill::setSkillNumber(int skill)
{
if (skill < 0)
setSkillId(ESM::Skill::Length);
else if (skill < ESM::Skill::Length)
setSkillId(static_cast<ESM::Skill::SkillEnum>(skill));
else
throw new std::runtime_error("Skill number out of range");
}
void MWSkill::setSkillValue(const SkillValue& value_)
{
value = value_;
updateWidgets();
}
void MWSkill::updateWidgets()
{
if (skillNameWidget && manager)
{
if (skillId == ESM::Skill::Length)
{
static_cast<MyGUI::TextBox*>(skillNameWidget)->setCaption("");
}
else
{
const std::string &name = manager->getGameSettingString(ESM::Skill::sSkillNameIds[skillId], "");
static_cast<MyGUI::TextBox*>(skillNameWidget)->setCaption(name);
}
}
if (skillValueWidget)
{
SkillValue::Type modified = value.getModified(), base = value.getBase();
static_cast<MyGUI::TextBox*>(skillValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
if (modified > base)
skillValueWidget->_setWidgetState("increased");
else if (modified < base)
skillValueWidget->_setWidgetState("decreased");
else
skillValueWidget->_setWidgetState("normal");
}
}
void MWSkill::onClicked(MyGUI::Widget* _sender)
{
eventClicked(this);
}
MWSkill::~MWSkill()
{
}
void MWSkill::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(skillNameWidget, "StatName");
assignWidget(skillValueWidget, "StatValue");
MyGUI::ButtonPtr button;
assignWidget(button, "StatNameButton");
if (button)
{
skillNameWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked);
}
button = 0;
assignWidget(button, "StatValueButton");
if (button)
{
skillNameWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked);
}
}
/* MWAttribute */
MWAttribute::MWAttribute()
: manager(nullptr)
, id(-1)
, attributeNameWidget(nullptr)
, attributeValueWidget(nullptr)
{
}
void MWAttribute::setAttributeId(int attributeId)
{
id = attributeId;
updateWidgets();
}
void MWAttribute::setAttributeValue(const AttributeValue& value_)
{
value = value_;
updateWidgets();
}
void MWAttribute::onClicked(MyGUI::Widget* _sender)
{
eventClicked(this);
}
void MWAttribute::updateWidgets()
{
if (attributeNameWidget && manager)
{
if (id < 0 || id >= 8)
{
static_cast<MyGUI::TextBox*>(attributeNameWidget)->setCaption("");
}
else
{
static const char *attributes[8] = {
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
const std::string &name = manager->getGameSettingString(attributes[id], "");
static_cast<MyGUI::TextBox*>(attributeNameWidget)->setCaption(name);
}
}
if (attributeValueWidget)
{
AttributeValue::Type modified = value.getModified(), base = value.getBase();
static_cast<MyGUI::TextBox*>(attributeValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
if (modified > base)
attributeValueWidget->_setWidgetState("increased");
else if (modified < base)
attributeValueWidget->_setWidgetState("decreased");
else
attributeValueWidget->_setWidgetState("normal");
}
}
MWAttribute::~MWAttribute()
{
}
void MWAttribute::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(attributeNameWidget, "StatName");
assignWidget(attributeValueWidget, "StatValue");
MyGUI::ButtonPtr button;
assignWidget(button, "StatNameButton");
if (button)
{
attributeNameWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked);
}
button = 0;
assignWidget(button, "StatValueButton");
if (button)
{
attributeValueWidget = button;
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked);
}
}
/* MWSpell */
MWSpell::MWSpell()
: mWindowManager(nullptr)
, spellNameWidget(nullptr)
{
}
void MWSpell::setSpellId(const std::string &spellId)
{
id = spellId;
updateWidgets();
}
void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord)
{
const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id);
MYGUI_ASSERT(spell, "spell with id '" << id << "' not found");
MWSpellEffectPtr effect = nullptr;
std::vector<ESM::ENAMstruct>::const_iterator end = spell->effects.list.end();
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->effects.list.begin(); it != end; ++it)
{
effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
effect->setWindowManager(mWindowManager);
effect->setSpellEffect(*it);
effects.push_back(effect);
coord.top += effect->getHeight();
}
}
void MWSpell::updateWidgets()
{
if (spellNameWidget && mWindowManager)
{
const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::Spell *spell = store.spells.search(id);
if (spell)
static_cast<MyGUI::TextBox*>(spellNameWidget)->setCaption(spell->name);
else
static_cast<MyGUI::TextBox*>(spellNameWidget)->setCaption("");
}
}
void MWSpell::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(spellNameWidget, "StatName");
}
MWSpell::~MWSpell()
{
}
/* MWSpellEffect */
MWSpellEffect::MWSpellEffect()
: mWindowManager(nullptr)
, imageWidget(nullptr)
, textWidget(nullptr)
{
}
void MWSpellEffect::setSpellEffect(SpellEffectValue value)
{
effect = value;
updateWidgets();
}
void MWSpellEffect::updateWidgets()
{
if (!mWindowManager)
return;
const ESMS::ESMStore &store = mWindowManager->getStore();
const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID);
if (textWidget)
{
if (magicEffect)
{
// TODO: Get name of effect from GMST
std::string spellLine = "";
if (effect.skill >= 0 && effect.skill < ESM::Skill::Length)
{
spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], "");
}
if (effect.attribute >= 0 && effect.attribute < 8)
{
static const char *attributes[8] = {
"sAttributeStrength",
"sAttributeIntelligence",
"sAttributeWillpower",
"sAttributeAgility",
"sAttributeSpeed",
"sAttributeEndurance",
"sAttributePersonality",
"sAttributeLuck"
};
spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], "");
}
if (effect.magnMin >= 0 || effect.magnMax >= 0)
{
if (effect.magnMin == effect.magnMax)
spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " pts";
else
{
spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " to " + boost::lexical_cast<std::string>(effect.magnMin) + " pts";
}
}
if (effect.duration >= 0)
{
spellLine += " for " + boost::lexical_cast<std::string>(effect.duration) + " secs";
}
if (effect.range == ESM::RT_Self)
spellLine += " on Self";
else if (effect.range == ESM::RT_Touch)
spellLine += " on Touch";
else if (effect.range == ESM::RT_Target)
spellLine += " on Target";
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(spellLine);
}
else
static_cast<MyGUI::TextBox*>(textWidget)->setCaption("");
}
if (imageWidget)
{
std::string path = std::string("icons\\") + magicEffect->icon;
fixTexturePath(path);
imageWidget->setImageTexture(path);
}
}
MWSpellEffect::~MWSpellEffect()
{
}
void MWSpellEffect::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(textWidget, "Text");
assignWidget(imageWidget, "Image");
}
/* MWDynamicStat */
MWDynamicStat::MWDynamicStat()
: value(0)
, max(1)
, textWidget(nullptr)
, barWidget(nullptr)
, barTextWidget(nullptr)
{
}
void MWDynamicStat::setValue(int cur, int max_)
{
value = cur;
max = max_;
if (barWidget)
{
barWidget->setProgressRange(max);
barWidget->setProgressPosition(value);
}
if (barTextWidget)
{
if (value >= 0 && max > 0)
{
std::stringstream out;
out << value << "/" << max;
static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption(out.str().c_str());
}
else
static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption("");
}
}
void MWDynamicStat::setTitle(const std::string text)
{
if (textWidget)
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(text);
}
MWDynamicStat::~MWDynamicStat()
{
}
void MWDynamicStat::initialiseOverride()
{
Base::initialiseOverride();
assignWidget(textWidget, "Text");
assignWidget(barWidget, "Bar");
assignWidget(barTextWidget, "BarText");
}