diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index d58e53b4b..89cd02d84 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -36,6 +36,7 @@ source_group(apps\\openmw\\mwinput FILES ${GAMEINPUT} ${GAMEINPUT_HEADER}) set(GAMEGUI_HEADER mwgui/layouts.hpp mwgui/text_input.hpp + mwgui/widgets.hpp mwgui/race.hpp mwgui/class.hpp mwgui/window_manager.hpp @@ -46,6 +47,7 @@ set(GAMEGUI mwgui/layouts.cpp mwgui/console.cpp mwgui/text_input.cpp + mwgui/widgets.cpp mwgui/race.cpp mwgui/class.cpp ) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 426876f61..7e7df4e21 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -34,6 +34,9 @@ #include +#include +#include "mwgui/class.hpp" + void OMW::Engine::executeLocalScripts() { for (MWWorld::World::ScriptList::const_iterator iter ( @@ -237,6 +240,8 @@ void OMW::Engine::go() // Set up the GUI system mGuiManager = new OEngine::GUI::MyGUIManager(mOgre.getWindow(), mOgre.getScene()); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); // Create window manager - this manages all the MW-specific GUI windows MWScript::registerExtensions (mExtensions); diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index ff1f90bbb..7c56c553d 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -29,6 +29,8 @@ PickClassDialog::PickClassDialog(MWWorld::Environment& environment, MyGUI::IntSi setText("FavoriteAttributesT", wm->getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); getWidget(favoriteAttribute0, "FavoriteAttribute0"); getWidget(favoriteAttribute1, "FavoriteAttribute1"); + favoriteAttribute0->setWindowManager(wm); + favoriteAttribute1->setWindowManager(wm); setText("MajorSkillT", wm->getGameSettingString("sChooseClassMenu3", "Major Skills:")); getWidget(majorSkill0, "MajorSkill0"); @@ -36,6 +38,11 @@ PickClassDialog::PickClassDialog(MWWorld::Environment& environment, MyGUI::IntSi getWidget(majorSkill2, "MajorSkill2"); getWidget(majorSkill3, "MajorSkill3"); getWidget(majorSkill4, "MajorSkill4"); + majorSkill0->setWindowManager(wm); + majorSkill1->setWindowManager(wm); + majorSkill2->setWindowManager(wm); + majorSkill3->setWindowManager(wm); + majorSkill4->setWindowManager(wm); setText("MinorSkillT", wm->getGameSettingString("sChooseClassMenu4", "Minor Skills:")); getWidget(minorSkill0, "MinorSkill0"); @@ -43,6 +50,11 @@ PickClassDialog::PickClassDialog(MWWorld::Environment& environment, MyGUI::IntSi getWidget(minorSkill2, "MinorSkill2"); getWidget(minorSkill3, "MinorSkill3"); getWidget(minorSkill4, "MinorSkill4"); + minorSkill0->setWindowManager(wm); + minorSkill1->setWindowManager(wm); + minorSkill2->setWindowManager(wm); + minorSkill3->setWindowManager(wm); + minorSkill4->setWindowManager(wm); getWidget(classList, "ClassList"); classList->setScrollVisible(true); @@ -182,41 +194,29 @@ void PickClassDialog::updateStats() "sSpecializationStealth" }; specializationName->setCaption(wm->getGameSettingString(specIds[specialization], specIds[specialization])); - static const char *attributes[8] = { - "sAttributeStrength", - "sAttributeIntelligence", - "sAttributeWillpower", - "sAttributeAgility", - "sAttributeSpeed", - "sAttributeEndurance", - "sAttributePersonality", - "sAttributeLuck" - }; - favoriteAttribute0->setCaption(wm->getGameSettingString(attributes[klass->data.attribute[0]], "")); - favoriteAttribute1->setCaption(wm->getGameSettingString(attributes[klass->data.attribute[1]], "")); + favoriteAttribute0->setAttributeId(klass->data.attribute[0]); + favoriteAttribute1->setAttributeId(klass->data.attribute[1]); - MyGUI::StaticTextPtr skills[2][5] = { - { - majorSkill0, - majorSkill1, - majorSkill2, - majorSkill3, - majorSkill4 - }, - { - minorSkill0, - minorSkill1, - minorSkill2, - minorSkill3, - minorSkill4 - } + Widgets::MWSkillPtr majorSkills[5] = { + majorSkill0, + majorSkill1, + majorSkill2, + majorSkill3, + majorSkill4 + }; + Widgets::MWSkillPtr minorSkills[5] = { + minorSkill0, + minorSkill1, + minorSkill2, + minorSkill3, + minorSkill4 }; for (int i = 0; i < 5; ++i) { - skills[0][i]->setCaption(wm->getGameSettingString(ESM::Skill::sSkillNameIds[klass->data.skills[i][0]], "")); - skills[1][i]->setCaption(wm->getGameSettingString(ESM::Skill::sSkillNameIds[klass->data.skills[i][1]], "")); + majorSkills[i]->setSkillNumber(klass->data.skills[i][0]); + minorSkills[i]->setSkillNumber(klass->data.skills[i][1]); } classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index 8a406d110..35b18f63f 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -5,6 +5,10 @@ #include +#include + +#include "widgets.hpp" + namespace MWWorld { class Environment; @@ -58,9 +62,9 @@ namespace MWGui MyGUI::StaticImagePtr classImage; MyGUI::ListPtr classList; MyGUI::StaticTextPtr specializationName; - MyGUI::StaticTextPtr favoriteAttribute0, favoriteAttribute1; - MyGUI::StaticTextPtr majorSkill0, majorSkill1, majorSkill2, majorSkill3, majorSkill4; - MyGUI::StaticTextPtr minorSkill0, minorSkill1, minorSkill2, minorSkill3, minorSkill4; + Widgets::MWAttributePtr favoriteAttribute0, favoriteAttribute1; + Widgets::MWSkillPtr majorSkill0, majorSkill1, majorSkill2, majorSkill3, majorSkill4; + Widgets::MWSkillPtr minorSkill0, minorSkill1, minorSkill2, minorSkill3, minorSkill4; std::string currentClassId; }; diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 6a1990311..e9cd78173 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -2,6 +2,7 @@ #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" #include "window_manager.hpp" +#include "widgets.hpp" #include "components/esm_store/store.hpp" #include @@ -12,6 +13,7 @@ #include using namespace MWGui; +using namespace Widgets; RaceDialog::RaceDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) : Layout("openmw_chargen_race_layout.xml") @@ -247,10 +249,9 @@ void RaceDialog::updateSkills() if (currentRaceId.empty()) return; - MyGUI::StaticTextPtr skillNameWidget, skillBonusWidget; + MWSkillPtr skillWidget; const int lineHeight = 18; - MyGUI::IntCoord coord1(0, 0, skillList->getWidth() - (40 + 4), 18); - MyGUI::IntCoord coord2(coord1.left + coord1.width, 0, 40, 18); + MyGUI::IntCoord coord1(0, 0, skillList->getWidth(), 18); WindowManager *wm = environment.mWindowManager; ESMS::ESMStore &store = environment.mWorld->getStore(); @@ -262,22 +263,15 @@ void RaceDialog::updateSkills() if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes continue; - skillNameWidget = skillList->createWidget("SandText", coord1, MyGUI::Align::Default, - std::string("SkillName") + boost::lexical_cast(i)); - assert(skillId >= 0 && skillId < ESM::Skill::Length); - const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId]; - skillNameWidget->setCaption(wm->getGameSettingString(skillNameId, skillNameId)); + skillWidget = skillList->createWidget("MW_StatNameValue", coord1, MyGUI::Align::Default, + std::string("Skill") + boost::lexical_cast(i)); + skillWidget->setWindowManager(wm); + skillWidget->setSkillNumber(skillId); + skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus)); - skillBonusWidget = skillList->createWidget("SandTextRight", coord2, MyGUI::Align::Default, - std::string("SkillBonus") + boost::lexical_cast(i)); - int bonus = race->data.bonus[i].bonus; - skillBonusWidget->setCaption(boost::lexical_cast(bonus)); - - skillItems.push_back(skillNameWidget); - skillItems.push_back(skillBonusWidget); + skillItems.push_back(skillWidget); coord1.top += lineHeight; - coord2.top += lineHeight; } } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp new file mode 100644 index 000000000..573636932 --- /dev/null +++ b/apps/openmw/mwgui/widgets.cpp @@ -0,0 +1,206 @@ +#include "widgets.hpp" +#include "window_manager.hpp" + +//#include +#include + +using namespace MWGui; +using namespace MWGui::Widgets; + +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(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) + { + skillNameWidget->setCaption(""); + } + else + { + const std::string &name = manager->getGameSettingString(ESM::Skill::sSkillNameIds[skillId], ""); + skillNameWidget->setCaption(name); + } + } + if (skillValueWidget) + { + SkillValue::Type modified = value.getModified(), base = value.getBase(); + skillValueWidget->setCaption(boost::lexical_cast(modified)); + if (modified > base) + skillValueWidget->setState("increased"); + else if (modified < base) + skillValueWidget->setState("decreased"); + else + skillValueWidget->setState("normal"); + } +} + +void MWSkill::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name) +{ + Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name); + + initialiseWidgetSkin(_info); +} + +MWSkill::~MWSkill() +{ + shutdownWidgetSkin(); +} + +void MWSkill::baseChangeWidgetSkin(ResourceSkin* _info) +{ + shutdownWidgetSkin(); + Base::baseChangeWidgetSkin(_info); + initialiseWidgetSkin(_info); +} + +void MWSkill::initialiseWidgetSkin(ResourceSkin* _info) +{ + for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter) + { + const std::string &name = *(*iter)->_getInternalData(); + if (name == "StatName") + { + MYGUI_DEBUG_ASSERT( ! skillNameWidget, "widget already assigned"); + skillNameWidget = (*iter)->castType(); + } + else if (name == "StatValue") + { + MYGUI_DEBUG_ASSERT( ! skillValueWidget, "widget already assigned"); + skillValueWidget = (*iter)->castType(); + } + } +} + +void MWSkill::shutdownWidgetSkin() +{ +} + +/* MWSkill */ + +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::updateWidgets() +{ + if (attributeNameWidget && manager) + { + if (id < 0 || id >= 8) + { + attributeNameWidget->setCaption(""); + } + else + { + static const char *attributes[8] = { + "sAttributeStrength", + "sAttributeIntelligence", + "sAttributeWillpower", + "sAttributeAgility", + "sAttributeSpeed", + "sAttributeEndurance", + "sAttributePersonality", + "sAttributeLuck" + }; + const std::string &name = manager->getGameSettingString(attributes[id], ""); + attributeNameWidget->setCaption(name); + } + } + if (attributeValueWidget) + { + AttributeValue::Type modified = value.getModified(), base = value.getBase(); + attributeValueWidget->setCaption(boost::lexical_cast(modified)); + if (modified > base) + attributeValueWidget->setState("increased"); + else if (modified < base) + attributeValueWidget->setState("decreased"); + else + attributeValueWidget->setState("normal"); + } +} + +void MWAttribute::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name) +{ + Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name); + + initialiseWidgetSkin(_info); +} + +MWAttribute::~MWAttribute() +{ + shutdownWidgetSkin(); +} + +void MWAttribute::baseChangeWidgetSkin(ResourceSkin* _info) +{ + shutdownWidgetSkin(); + Base::baseChangeWidgetSkin(_info); + initialiseWidgetSkin(_info); +} + +void MWAttribute::initialiseWidgetSkin(ResourceSkin* _info) +{ + for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter) + { + const std::string &name = *(*iter)->_getInternalData(); + if (name == "StatName") + { + MYGUI_DEBUG_ASSERT( ! attributeNameWidget, "widget already assigned"); + attributeNameWidget = (*iter)->castType(); + } + else if (name == "StatValue") + { + MYGUI_DEBUG_ASSERT( ! attributeValueWidget, "widget already assigned"); + attributeValueWidget = (*iter)->castType(); + } + } +} + +void MWAttribute::shutdownWidgetSkin() +{ +} diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp new file mode 100644 index 000000000..d6d59d803 --- /dev/null +++ b/apps/openmw/mwgui/widgets.hpp @@ -0,0 +1,98 @@ +#ifndef MWGUI_WIDGETS_H +#define MWGUI_WIDGETS_H + +#include + +#include + +#include "../mwmechanics/stat.hpp" + +/* + This file contains various custom widgets used in OpenMW. + */ + +namespace MWGui +{ + using namespace MyGUI; + class WindowManager; + + namespace Widgets + { + class MYGUI_EXPORT MWSkill : public Widget + { + MYGUI_RTTI_DERIVED( MWSkill ); + public: + MWSkill(); + + typedef MWMechanics::Stat SkillValue; + + void setWindowManager(WindowManager *m) { manager = m; } + void setSkillId(ESM::Skill::SkillEnum skillId); + void setSkillNumber(int skillId); + void setSkillValue(const SkillValue& value); + + WindowManager *getWindowManager() const { return manager; } + ESM::Skill::SkillEnum getSkillId() const { return skillId; } + const SkillValue& getSkillValue() const { return value; } + + /*internal:*/ + virtual void _initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name); + + protected: + virtual ~MWSkill(); + + void baseChangeWidgetSkin(ResourceSkin* _info); + + private: + void initialiseWidgetSkin(ResourceSkin* _info); + void shutdownWidgetSkin(); + + void updateWidgets(); + + WindowManager *manager; + ESM::Skill::SkillEnum skillId; + SkillValue value; + MyGUI::StaticTextPtr skillNameWidget, skillValueWidget; + }; + typedef MWSkill* MWSkillPtr; + + class MYGUI_EXPORT MWAttribute : public Widget + { + MYGUI_RTTI_DERIVED( MWAttribute ); + public: + MWAttribute(); + + typedef MWMechanics::Stat AttributeValue; + + void setWindowManager(WindowManager *m) { manager = m; } + void setAttributeId(int attributeId); + void setAttributeValue(const AttributeValue& value); + + WindowManager *getWindowManager() const { return manager; } + int getAttributeId() const { return id; } + const AttributeValue& getAttributeValue() const { return value; } + + /*internal:*/ + virtual void _initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name); + + protected: + virtual ~MWAttribute(); + + void baseChangeWidgetSkin(ResourceSkin* _info); + + private: + void initialiseWidgetSkin(ResourceSkin* _info); + void shutdownWidgetSkin(); + + void updateWidgets(); + + WindowManager *manager; + int id; + AttributeValue value; + MyGUI::StaticTextPtr attributeNameWidget, attributeValueWidget; + }; + typedef MWAttribute* MWAttributePtr; + } +} + +#endif diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_chargen_class_layout.xml b/extern/mygui_3.0.1/openmw_resources/openmw_chargen_class_layout.xml index 3b6e8245d..7e2432e28 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_chargen_class_layout.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_chargen_class_layout.xml @@ -27,54 +27,30 @@ - - - - - - + + - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - + + + + + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml index 91dc8bd33..c615effc4 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml @@ -22,7 +22,11 @@ - + + + + + @@ -48,4 +52,13 @@ + + + + + + + + +