1 #ifndef MWGUI_WIDGETS_H
2 #define MWGUI_WIDGETS_H
3 
4 #include "../mwmechanics/stat.hpp"
5 
6 #include <components/esm/effectlist.hpp>
7 #include <components/esm/loadskil.hpp>
8 
9 #include <MyGUI_Button.h>
10 #include <MyGUI_EditBox.h>
11 #include <MyGUI_ScrollBar.h>
12 
13 namespace MyGUI
14 {
15     class ImageBox;
16     class ControllerItem;
17 }
18 
19 namespace MWBase
20 {
21     class WindowManager;
22 }
23 
24 /*
25   This file contains various custom widgets used in OpenMW.
26  */
27 
28 namespace MWGui
29 {
30     namespace Widgets
31     {
32         class MWEffectList;
33 
34         void fixTexturePath(std::string &path);
35 
36         struct SpellEffectParams
37         {
SpellEffectParamsMWGui::Widgets::SpellEffectParams38             SpellEffectParams()
39                 : mNoTarget(false)
40                 , mIsConstant(false)
41                 , mNoMagnitude(false)
42                 , mKnown(true)
43                 , mEffectID(-1)
44                 , mSkill(-1)
45                 , mAttribute(-1)
46                 , mMagnMin(-1)
47                 , mMagnMax(-1)
48                 , mRange(-1)
49                 , mDuration(-1)
50                 , mArea(0)
51             {
52             }
53 
54             bool mNoTarget; // potion effects for example have no target (target is always the player)
55             bool mIsConstant; // constant effect means that duration will not be displayed
56             bool mNoMagnitude; // effect magnitude will not be displayed (e.g ingredients)
57 
58             bool mKnown; // is this effect known to the player? (If not, will display as a question mark instead)
59 
60             // value of -1 here means the effect is unknown to the player
61             short mEffectID;
62 
63             // value of -1 here means there is no skill/attribute
64             signed char mSkill, mAttribute;
65 
66             // value of -1 here means the value is unavailable
67             int mMagnMin, mMagnMax, mRange, mDuration;
68 
69             // value of 0 -> no area effect
70             int mArea;
71 
operator ==MWGui::Widgets::SpellEffectParams72             bool operator==(const SpellEffectParams& other) const
73             {
74                 if (mEffectID !=  other.mEffectID)
75                     return false;
76 
77                 bool involvesAttribute = (mEffectID == 74 // restore attribute
78                                         || mEffectID == 85 // absorb attribute
79                                         || mEffectID == 17 // drain attribute
80                                         || mEffectID == 79 // fortify attribute
81                                         || mEffectID == 22); // damage attribute
82                 bool involvesSkill = (mEffectID == 78 // restore skill
83                                         || mEffectID == 89 // absorb skill
84                                         || mEffectID == 21 // drain skill
85                                         || mEffectID == 83 // fortify skill
86                                         || mEffectID == 26); // damage skill
87                 return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute) && (other.mArea == mArea);
88             }
89         };
90 
91         typedef std::vector<SpellEffectParams> SpellEffectList;
92 
93         class MWSkill final : public MyGUI::Widget
94         {
95             MYGUI_RTTI_DERIVED( MWSkill )
96         public:
97             MWSkill();
98 
99             typedef MWMechanics::Stat<float> SkillValue;
100 
101             void setSkillId(ESM::Skill::SkillEnum skillId);
102             void setSkillNumber(int skillId);
103             void setSkillValue(const SkillValue& value);
104 
getSkillId() const105             ESM::Skill::SkillEnum getSkillId() const { return mSkillId; }
getSkillValue() const106             const SkillValue& getSkillValue() const { return mValue; }
107 
108             // Events
109             typedef MyGUI::delegates::CMultiDelegate1<MWSkill*> EventHandle_SkillVoid;
110 
111             /** Event : Skill clicked.\n
112                 signature : void method(MWSkill* _sender)\n
113             */
114             EventHandle_SkillVoid eventClicked;
115 
116         protected:
117             virtual ~MWSkill();
118 
119             void initialiseOverride() override;
120 
121             void onClicked(MyGUI::Widget* _sender);
122 
123         private:
124 
125             void updateWidgets();
126 
127             ESM::Skill::SkillEnum mSkillId;
128             SkillValue mValue;
129             MyGUI::TextBox* mSkillNameWidget;
130             MyGUI::TextBox* mSkillValueWidget;
131         };
132         typedef MWSkill* MWSkillPtr;
133 
134         class MWAttribute final : public MyGUI::Widget
135         {
136             MYGUI_RTTI_DERIVED( MWAttribute )
137         public:
138             MWAttribute();
139 
140             typedef MWMechanics::AttributeValue AttributeValue;
141 
142             void setAttributeId(int attributeId);
143             void setAttributeValue(const AttributeValue& value);
144 
getAttributeId() const145             int getAttributeId() const { return mId; }
getAttributeValue() const146             const AttributeValue& getAttributeValue() const { return mValue; }
147 
148             // Events
149             typedef MyGUI::delegates::CMultiDelegate1<MWAttribute*> EventHandle_AttributeVoid;
150 
151             /** Event : Attribute clicked.\n
152                 signature : void method(MWAttribute* _sender)\n
153             */
154             EventHandle_AttributeVoid eventClicked;
155 
156         protected:
157             virtual ~MWAttribute();
158 
159             void initialiseOverride() override;
160 
161             void onClicked(MyGUI::Widget* _sender);
162 
163         private:
164 
165             void updateWidgets();
166 
167             int mId;
168             AttributeValue mValue;
169             MyGUI::TextBox* mAttributeNameWidget;
170             MyGUI::TextBox* mAttributeValueWidget;
171         };
172         typedef MWAttribute* MWAttributePtr;
173 
174         /**
175          * @todo remove this class and use MWEffectList instead
176          */
177         class MWSpellEffect;
178         class MWSpell final : public MyGUI::Widget
179         {
180             MYGUI_RTTI_DERIVED( MWSpell )
181         public:
182             MWSpell();
183 
184             typedef MWMechanics::Stat<int> SpellValue;
185 
186             void setSpellId(const std::string &id);
187 
188             /**
189              * @param vector to store the created effect widgets
190              * @param parent widget
191              * @param coordinates to use, will be expanded if more space is needed
192              * @param spell category, if this is 0, this means the spell effects are permanent and won't display e.g. duration
193              * @param various flags, see MWEffectList::EffectFlags
194              */
195             void createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags);
196 
getSpellId() const197             const std::string &getSpellId() const { return mId; }
198 
199         protected:
200             virtual ~MWSpell();
201 
202             void initialiseOverride() override;
203 
204         private:
205             void updateWidgets();
206 
207             std::string mId;
208             MyGUI::TextBox* mSpellNameWidget;
209         };
210         typedef MWSpell* MWSpellPtr;
211 
212         class MWEffectList final : public MyGUI::Widget
213         {
214             MYGUI_RTTI_DERIVED( MWEffectList )
215         public:
216             MWEffectList();
217 
218             typedef MWMechanics::Stat<int> EnchantmentValue;
219 
220             enum EffectFlags
221             {
222                 EF_NoTarget = 0x01, // potions have no target (target is always the player)
223                 EF_Constant = 0x02, // constant effect means that duration will not be displayed
224                 EF_NoMagnitude = 0x04 // ingredients have no magnitude
225 
226             };
227 
228             void setEffectList(const SpellEffectList& list);
229 
230             static SpellEffectList effectListFromESM(const ESM::EffectList* effects);
231 
232             /**
233              * @param vector to store the created effect widgets
234              * @param parent widget
235              * @param coordinates to use, will be expanded if more space is needed
236              * @param center the effect widgets horizontally
237              * @param various flags, see MWEffectList::EffectFlags
238              */
239             void createEffectWidgets(std::vector<MyGUI::Widget*> &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags);
240 
241         protected:
242             virtual ~MWEffectList();
243 
244             void initialiseOverride() override;
245 
246         private:
247             void updateWidgets();
248 
249             SpellEffectList mEffectList;
250         };
251         typedef MWEffectList* MWEffectListPtr;
252 
253         class MWSpellEffect final : public MyGUI::Widget
254         {
255             MYGUI_RTTI_DERIVED( MWSpellEffect )
256         public:
257             MWSpellEffect();
258 
259             typedef ESM::ENAMstruct SpellEffectValue;
260 
261             void setSpellEffect(const SpellEffectParams& params);
262 
getRequestedWidth() const263             int getRequestedWidth() const { return mRequestedWidth; }
264 
265         protected:
266             virtual ~MWSpellEffect();
267 
268             void initialiseOverride() override;
269 
270         private:
271             static constexpr int sIconOffset = 24;
272 
273             void updateWidgets();
274 
275             SpellEffectParams mEffectParams;
276             MyGUI::ImageBox* mImageWidget;
277             MyGUI::TextBox* mTextWidget;
278             int mRequestedWidth;
279         };
280         typedef MWSpellEffect* MWSpellEffectPtr;
281 
282         class MWDynamicStat final : public MyGUI::Widget
283         {
284             MYGUI_RTTI_DERIVED( MWDynamicStat )
285         public:
286             MWDynamicStat();
287 
288             void setValue(int value, int max);
289             void setTitle(const std::string& text);
290 
getValue() const291             int getValue() const { return mValue; }
getMax() const292             int getMax() const { return mMax; }
293 
294         protected:
295             virtual ~MWDynamicStat();
296 
297             void initialiseOverride() override;
298 
299         private:
300 
301             int mValue, mMax;
302             MyGUI::TextBox* mTextWidget;
303             MyGUI::ProgressBar* mBarWidget;
304             MyGUI::TextBox* mBarTextWidget;
305         };
306         typedef MWDynamicStat* MWDynamicStatPtr;
307     }
308 }
309 
310 #endif
311