xoreos  0.0.5
gui.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/endianness.h"
26 #include "src/common/scopedptr.h"
27 #include "src/common/error.h"
28 #include "src/common/util.h"
29 
30 #include "src/aurora/talkman.h"
31 #include "src/aurora/gff3file.h"
32 
34 
48 
50 
51 namespace Engines {
52 
53 namespace NWN {
54 
56  strct = &s;
57 
58  widget = 0;
59  parent = p;
60 
62  if (type == kWidgetTypeInvalid)
63  throw Common::Exception("Widget without a type");
64 
65  tag = strct->getString("Obj_Tag");
66 
67  model = strct->getString("Obj_ResRef");
68 }
69 
70 
71 GUI::GUI(::Engines::Console *console) : ::Engines::GUI(console) {
72 }
73 
75 }
76 
77 void GUI::load(const Common::UString &resref) {
78  _name = resref;
79 
80  try {
82  gff(new Aurora::GFF3File(resref, Aurora::kFileTypeGUI, MKTAG('G', 'U', 'I', ' '), true));
83 
84  loadWidget(gff->getTopLevel(), 0);
85 
86  } catch (Common::Exception &e) {
87  e.add("Can't load GUI \"%s\"", resref.c_str());
88  throw;
89  }
90 }
91 
92 void GUI::loadWidget(const Aurora::GFF3Struct &strct, Widget *parent) {
93  WidgetContext ctx(strct, parent);
94 
95  createWidget(ctx);
96 
97  addWidget(ctx.widget);
98 
99  if (ctx.parent) {
100  if (ctx.strct->getString("Obj_Parent") != ctx.parent->getTag())
101  throw Common::Exception("Parent's tag != Obj_Parent");
102 
103  parent->addChild(*ctx.widget);
104  } else {
105  // We'll ignore these for now, centering the GUI
106  }
107 
108  initWidget(ctx);
109 
110  // Go down to the children
111  if (ctx.strct->hasField("Obj_ChildList")) {
112  const Aurora::GFF3List &children = ctx.strct->getList("Obj_ChildList");
113 
114  for (Aurora::GFF3List::const_iterator c = children.begin(); c != children.end(); ++c)
115  loadWidget(**c, ctx.widget);
116  }
117 }
118 
120  // ...BioWare...
121  fixWidgetType(ctx.tag, ctx.type);
122 
123  if (ctx.type == kWidgetTypeFrame)
124  ctx.widget = new WidgetFrame(*this, ctx.tag, ctx.model);
125  else if (ctx.type == kWidgetTypeCloseButton)
126  ctx.widget = new WidgetClose(*this, ctx.tag, ctx.model);
127  else if (ctx.type == kWidgetTypeCheckBox)
128  ctx.widget = new WidgetCheckBox(*this, ctx.tag, ctx.model);
129  else if (ctx.type == kWidgetTypePanel)
130  ctx.widget = new WidgetPanel(*this, ctx.tag, ctx.model);
131  else if (ctx.type == kWidgetTypeLabel)
132  ctx.widget = new WidgetLabel(*this, ctx.tag);
133  else if (ctx.type == kWidgetTypeSlider)
134  ctx.widget = new WidgetSlider(*this, ctx.tag, ctx.model);
135  else if (ctx.type == kWidgetTypeEditBox)
136  ctx.widget = new WidgetEditBox(*this, ctx.tag, ctx.model);
137  else if (ctx.type == kWidgetTypeButton)
138  ctx.widget = new WidgetButton(*this, ctx.tag, ctx.model);
139  else if (ctx.type == kWidgetTypeListBox)
140  ctx.widget = new WidgetListBox(*this, ctx.tag, ctx.model);
141  else
142  throw Common::Exception("No such widget type %d", ctx.type);
143 
144  WidgetLabel *widgetLabel = dynamic_cast<WidgetLabel *>(ctx.widget);
145  if (widgetLabel)
146  initWidget(ctx, *widgetLabel);
147 
148  ModelWidget *widgetModel = dynamic_cast<ModelWidget *>(ctx.widget);
149  if (widgetModel)
150  initWidget(ctx, *widgetModel);
151 }
152 
154  float width = ctx.strct->getDouble("Obj_Label_Width") * 100.0;
155  float height = ctx.strct->getDouble("Obj_Label_Height") * 100.0;
156 
157  widget.setSize(width, height);
158 
159  float pX, pY, pZ;
160  ctx.parent->getPosition(pX, pY, pZ);
161 
162  float x = ctx.strct->getDouble("Obj_Label_X") * 100.0 + pX;
163  float y = ctx.strct->getDouble("Obj_Label_Y") * 100.0 + pY - height;
164  float z = pZ - ctx.strct->getDouble("Obj_Label_Z") * 100.0;
165 
166  ctx.widget->setPosition(x, y, z);
167 
168  initCaption(ctx, widget);
169 }
170 
172  initCaption(ctx, widget);
173 
174  if (!ctx.parent)
175  return;
176 
177  float pX, pY, pZ;
178  ctx.parent->getPosition(pX, pY, pZ);
179 
180  float x = ctx.strct->getDouble("Obj_X") * 100.0 + pX;
181  float y = ctx.strct->getDouble("Obj_Y") * 100.0 + pY;
182  float z = pZ - ctx.strct->getDouble("Obj_Z") * 100.0;
183 
184  widget.setPosition(x, y, z);
185 }
186 
188  if (!ctx.strct->hasField("Obj_Caption"))
189  return;
190 
191  const Aurora::GFF3Struct &caption = ctx.strct->getStruct("Obj_Caption");
192 
193  Common::UString font = caption.getString("AurString_Font");
194 
195  Common::UString text;
196  uint32 strRef = caption.getUint("Obj_StrRef", Aurora::kStrRefInvalid);
197  if (strRef != Aurora::kStrRefInvalid)
198  text = TalkMan.getString(strRef);
199 
200  float r = caption.getDouble("AurString_ColorR", 1.0);
201  float g = caption.getDouble("AurString_ColorG", 1.0);
202  float b = caption.getDouble("AurString_ColorB", 1.0);
203  float a = caption.getDouble("AurString_ColorA", 1.0);
204 
205  float halign = caption.getDouble("AurString_AlignH", Graphics::Aurora::kHAlignLeft);
206  float valign = caption.getDouble("AurString_AlignV", Graphics::Aurora::kVAlignTop);
207 
208  widget.initCaption(font, text, r, g, b, a, halign, valign);
209 }
210 
212 
213  initWidget(*ctx.widget);
214 }
215 
217 }
218 
219 void GUI::initWidget(Widget &UNUSED(widget)) {
220 }
221 
222 WidgetFrame *GUI::getFrame(const Common::UString &tag, bool vital) {
223  Widget *widget = getWidget(tag, vital);
224  if (!widget)
225  return 0;
226 
227  WidgetFrame *frame = dynamic_cast<WidgetFrame *>(widget);
228  if (!frame && vital)
229  throw Common::Exception("Vital frame widget \"%s\" doesn't exist", tag.c_str());
230 
231  return frame;
232 }
233 
234 WidgetClose *GUI::getClose(const Common::UString &tag, bool vital) {
235  Widget *widget = getWidget(tag, vital);
236  if (!widget)
237  return 0;
238 
239  WidgetClose *closeButton = dynamic_cast<WidgetClose *>(widget);
240  if (!closeButton && vital)
241  throw Common::Exception("Vital close button widget \"%s\" doesn't exist", tag.c_str());
242 
243  return closeButton;
244 }
245 
247  Widget *widget = getWidget(tag, vital);
248  if (!widget)
249  return 0;
250 
251  WidgetCheckBox *checkBox = dynamic_cast<WidgetCheckBox *>(widget);
252  if (!checkBox && vital)
253  throw Common::Exception("Vital check box widget \"%s\" doesn't exist", tag.c_str());
254 
255  return checkBox;
256 }
257 
258 WidgetPanel *GUI::getPanel(const Common::UString &tag, bool vital) {
259  Widget *widget = getWidget(tag, vital);
260  if (!widget)
261  return 0;
262 
263  WidgetPanel *panel = dynamic_cast<WidgetPanel *>(widget);
264  if (!panel && vital)
265  throw Common::Exception("Vital panel widget \"%s\" doesn't exist", tag.c_str());
266 
267  return panel;
268 }
269 
270 WidgetLabel *GUI::getLabel(const Common::UString &tag, bool vital) {
271  Widget *widget = getWidget(tag, vital);
272  if (!widget)
273  return 0;
274 
275  WidgetLabel *label = dynamic_cast<WidgetLabel *>(widget);
276  if (!label && vital)
277  throw Common::Exception("Vital label widget \"%s\" doesn't exist", tag.c_str());
278 
279  return label;
280 }
281 
282 WidgetSlider *GUI::getSlider(const Common::UString &tag, bool vital) {
283  Widget *widget = getWidget(tag, vital);
284  if (!widget)
285  return 0;
286 
287  WidgetSlider *slider = dynamic_cast<WidgetSlider *>(widget);
288  if (!slider && vital)
289  throw Common::Exception("Vital slider widget \"%s\" doesn't exist", tag.c_str());
290 
291  return slider;
292 }
293 
295  Widget *widget = getWidget(tag, vital);
296  if (!widget)
297  return 0;
298 
299  WidgetEditBox *editBox = dynamic_cast<WidgetEditBox *>(widget);
300  if (!editBox && vital)
301  throw Common::Exception("Vital edit box widget \"%s\" doesn't exist", tag.c_str());
302 
303  return editBox;
304 }
305 
306 WidgetButton *GUI::getButton(const Common::UString &tag, bool vital) {
307  Widget *widget = getWidget(tag, vital);
308  if (!widget)
309  return 0;
310 
311  WidgetButton *button = dynamic_cast<WidgetButton *>(widget);
312  if (!button && vital)
313  throw Common::Exception("Vital button widget \"%s\" doesn't exist", tag.c_str());
314 
315  return button;
316 }
317 
319  Widget *widget = getWidget(tag, vital);
320  if (!widget)
321  return 0;
322 
323  WidgetListBox *listBox = dynamic_cast<WidgetListBox *>(widget);
324  if (!listBox && vital)
325  throw Common::Exception("Vital listBox widget \"%s\" doesn't exist", tag.c_str());
326 
327  return listBox;
328 }
329 
331  Widget *widget = getWidget(tag, vital);
332  if (!widget)
333  return 0;
334 
335  WidgetScrollbar *scrollbar = dynamic_cast<WidgetScrollbar *>(widget);
336  if (!scrollbar && vital)
337  throw Common::Exception("Vital scrollbar widget \"%s\" doesn't exist", tag.c_str());
338 
339  return scrollbar;
340 }
341 
342 } // End of namespace NWN
343 
344 } // End of namespace Engines
Handling version V3.2/V3.3 of BioWare&#39;s GFFs (generic file format).
A NWN panel widget.
Definition: panel.h:41
Widget * getWidget(const Common::UString &tag, bool vital=false)
Return a widget in the GUI.
Definition: gui.cpp:314
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
A NWN checkbox widget.
Definition: checkbox.h:41
A NWN editbox widget.
void add(const char *s,...) GCC_PRINTF(2
Definition: error.cpp:58
#define TalkMan
Shortcut for accessing the talk manager.
Definition: talkman.h:111
A NWN button widget.
A class holding an UTF-8 string.
Definition: ustring.h:48
A NWN scrollbar widget.
Definition: scrollbar.h:95
virtual void fixWidgetType(const Common::UString &tag, WidgetType &type)
Definition: gui.cpp:216
WidgetListBox * getListBox(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:318
A NWN slider widget.
A NWN close button widget.
A NWN frame widget.
Definition: frame.h:41
WidgetFrame * getFrame(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:222
const float kVAlignTop
Definition: types.h:46
void initCaption(WidgetContext &ctx, NWNWidgetWithCaption &widget)
Definition: gui.cpp:187
virtual void setPosition(float x, float y, float z)
Set the widget&#39;s position.
Definition: widget.cpp:119
const Aurora::GFF3Struct * strct
Definition: gui.h:93
bool hasField(const Common::UString &field) const
Does this specific field exist?
Definition: gff3file.cpp:400
A NWN slider widget.
Definition: slider.h:41
Low-level macros and functions to handle different endianness portably.
virtual void getPosition(float &x, float &y, float &z) const
Get the widget&#39;s position.
Definition: widget.cpp:140
WidgetCheckBox * getCheckBox(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:246
WidgetContext(const Aurora::GFF3Struct &s, Widget *p)
Definition: gui.cpp:55
uint64 getUint(const Common::UString &field, uint64 def=0) const
Definition: gff3file.cpp:436
A NWN checkbox widget.
Exception that provides a stack of explanations.
Definition: error.h:36
A simple scoped smart pointer template.
A NWN listbox widget.
A NWN button widget.
Definition: button.h:39
WidgetButton * getButton(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:306
Basic exceptions to throw.
WidgetClose * getClose(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:234
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
A NWN quad widget.
A NWN model widget.
WidgetLabel * getLabel(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:270
A NWN close button widget.
Definition: close.h:41
#define UNUSED(x)
Definition: system.h:170
A NWN GUI.
Definition: gui.h:54
Utility templates and functions.
const Common::UString & getTag() const
Get the widget&#39;s tag.
Definition: widget.cpp:45
A NWN frame widget.
double getDouble(const Common::UString &field, double def=0.0) const
Definition: gff3file.cpp:514
const float kHAlignLeft
Definition: types.h:42
A GFF (generic file format) V3.2/V3.3 file, found in all Aurora games except Sonic Chronicles: The Da...
Definition: gff3file.h:85
virtual void initCaption(const Common::UString &font, const Common::UString &text, float r=1.0f, float g=1.0f, float b=1.0f, float a=1.0f, float halign=Graphics::Aurora::kHAlignLeft, float valign=Graphics::Aurora::kVAlignTop)
WidgetSlider * getSlider(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:282
WidgetPanel * getPanel(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:258
static const uint32 kStrRefInvalid
Definition: types.h:444
void load(const Common::UString &resref)
Definition: gui.cpp:77
A NWN listbox widget.
Definition: listbox.h:116
StackException Exception
Definition: error.h:59
virtual void addChild(Widget &widget)
Add a child to the widget.
Definition: widget.cpp:215
Common::UString _name
Definition: gui.h:107
std::vector< const GFF3Struct * > GFF3List
Definition: types.h:449
WidgetEditBox * getEditBox(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:294
A NWN label widget.
Definition: label.h:41
A NWN widget with a text caption.
const GFF3List & getList(const Common::UString &field) const
Definition: gff3file.cpp:741
Common::UString model
Definition: gui.h:102
A widget in a GUI.
Definition: widget.h:40
void setPosition(float x, float y, float z)
Set the widget&#39;s position.
Definition: modelwidget.cpp:71
A NWN model widget.
Definition: modelwidget.h:45
A NWN scrollbar model and widget.
A struct within a GFF3.
Definition: gff3file.h:164
uint32_t uint32
Definition: types.h:204
const GFF3Struct & getStruct(const Common::UString &field) const
Definition: gff3file.cpp:728
The global talk manager for Aurora strings.
GUI(::Engines::Console *console=0)
Definition: gui.cpp:71
virtual void initWidget(Widget &widget)
Definition: gui.cpp:219
A NWN editbox widget.
Definition: editbox.h:43
GUI definition, GFF.
Definition: types.h:113
WidgetScrollbar * getScrollbar(const Common::UString &tag, bool vital=false)
Definition: gui.cpp:330
void loadWidget(const Aurora::GFF3Struct &strct, Widget *parent)
Definition: gui.cpp:92
Common::UString getString(const Common::UString &field, const Common::UString &def="") const
Definition: gff3file.cpp:527
Generic Aurora engines utility functions.
A NWN widget with a text caption.
void addWidget(Widget *widget)
Add a widget.
Definition: gui.cpp:250
Common::UString tag
Definition: gui.h:97
A NWN panel widget.
A NWN GUI.
A NWN label widget.
void setSize(float width, float height)
Definition: label.cpp:92
void createWidget(WidgetContext &ctx)
Definition: gui.cpp:119