/
igui.h
346 lines (267 loc) · 8.72 KB
/
igui.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#pragma once
#include <vector>
#include <string>
#include <memory>
#include <map>
#include <sigc++/signal.h>
#include "imodule.h"
#include "math/Vector4.h"
#include "ishaders.h"
namespace gui
{
class IGui;
class IRenderableText
{
public:
virtual ~IRenderableText() {}
// Submits the openGL calls
virtual void render() = 0;
// Re-construct this structure, called when the text in the owning windowDef has been changed
virtual void recompile() = 0;
};
// An expression as encountered in the GUI code
// Evaluates to an instance of a certain type (bool, string, etc.)
template<typename ValueType>
class IGuiExpression
{
public:
// Shared ptr typedef
typedef std::shared_ptr<IGuiExpression<ValueType>> Ptr;
virtual ~IGuiExpression() {}
// Evaluate this expression to retrieve the result
virtual ValueType evaluate() = 0;
};
// An expression representing a constant value
template<typename ValueType>
class ConstantExpression :
public IGuiExpression<ValueType>
{
private:
ValueType _value;
public:
ConstantExpression(const ValueType& value) :
_value(value)
{}
virtual ValueType evaluate() override
{
return _value;
}
template<typename OtherType>
static std::shared_ptr<ConstantExpression<ValueType>> Create(const OtherType& value)
{
return std::make_shared<ConstantExpression<ValueType>>(value);
}
};
// Represents a variable or property of a GuiWindowDef
// e.g. "text", "notime", "forecolor" or a user-defined variable
class IWindowVariable
{
private:
sigc::signal<void> _changedSignal;
public:
virtual ~IWindowVariable() {}
// value-changed signal, to get notified when this value changes
sigc::signal<void>& signal_variableChanged()
{
return _changedSignal;
}
};
// Represents a GUI property carrying a certain type
// e.g. "text" (std::string), "rect" (Vector4), "textscale" (float), ...
template<typename ValueType>
class WindowVariable :
public IWindowVariable
{
protected:
// Types used by this window variable
typedef IGuiExpression<ValueType> ExpressionType;
typedef std::shared_ptr<ExpressionType> ExpressionTypePtr;
// The expression which can be evaluated
ExpressionTypePtr _expression;
public:
typedef ValueType ValueType; // make the ValueType public
typedef std::shared_ptr<WindowVariable<ValueType>> Ptr; // smart ptr typedef
operator ValueType() const
{
return getValue();
}
virtual ValueType getValue() const
{
return _expression ? _expression->evaluate() : ValueType();
}
// Assigns a new Expression to this variable. The expression needs
// to match the ValueType of this variable
virtual void setValue(const ExpressionTypePtr& newExpr)
{
_expression = newExpr;
signal_variableChanged().emit();
}
// Assigns a constant value to this variable
virtual void setValue(const ValueType& constantValue)
{
_expression = ConstantExpression<ValueType>::Create(constantValue);
signal_variableChanged().emit();
}
};
class IGuiWindowDef;
typedef std::shared_ptr<IGuiWindowDef> IGuiWindowDefPtr;
class IGuiWindowDef
{
public:
// Public properties
// The name of this windowDef
std::string name;
// Window size (x,y,width,height)
WindowVariable<Vector4> rect;
// Visible or hidden
WindowVariable<bool> visible;
// The body text of this window
WindowVariable<std::string> text;
// Whether this gui is full screen (use on desktop window)
WindowVariable<bool> menugui;
WindowVariable<Vector4> forecolor;
WindowVariable<Vector4> hovercolor;
WindowVariable<Vector4> backcolor;
WindowVariable<Vector4> bordercolor;
WindowVariable<float> bordersize;
WindowVariable<Vector4> matcolor;
WindowVariable<float> rotate;
// background shader name
WindowVariable<std::string> background;
// background shader (NULL until realised)
MaterialPtr backgroundShader;
// The name of the font
WindowVariable<std::string> font;
// The scale for rendering the font
WindowVariable<float> textscale;
// The text alignment (left, right, center)
WindowVariable<int> textalign;
// Text offsets
WindowVariable<float> textalignx;
WindowVariable<float> textaligny;
// Force a specific aspect ratio
WindowVariable<float> forceaspectwidth;
WindowVariable<float> forceaspectheight;
// No mouse events for this window
WindowVariable<bool> noevents;
// Whether this window forces text to wrap at their borders
WindowVariable<bool> noclip;
// Whether time is running for this windowDef
WindowVariable<bool> notime;
// Don't display the cursor
WindowVariable<bool> nocursor;
// Don't wrap words at rectangle borders
WindowVariable<bool> nowrap;
// The window time (0..infinity)
std::size_t time;
// Each window can define its own set of named variables,
// which can be of type float or Vector4
typedef std::shared_ptr<IWindowVariable> IWindowVariablePtr;
typedef std::map<std::string, IWindowVariablePtr> NamedVariables;
NamedVariables variables;
// All child windowDefs of this window
typedef std::vector<IGuiWindowDefPtr> ChildWindows;
ChildWindows children;
public:
virtual ~IGuiWindowDef() {}
// Returns the owning GUI
virtual IGui& getGui() const = 0;
virtual void addWindow(const IGuiWindowDefPtr& window) = 0;
// Recursively looks for a named child windowDef
// Returns NULL if not found
virtual IGuiWindowDefPtr findWindowDef(const std::string& name) = 0;
// Get the renderable text object containing the OpenGLRenderables
virtual IRenderableText& getRenderableText() = 0;
/**
* greebo: This is some sort of "think" method, giving this windowDef
* a chance to handle timed events.
*
* @updateChildren: recursively updates child windowDef if true
*/
virtual void update(const std::size_t timeStep, bool updateChildren = true) = 0;
// Initialises the time of this windowDef and all children
virtual void initTime(const std::size_t time, bool updateChildren = true) = 0;
// Prepares renderable objects, to be called by the parent Gui only
virtual void pepareRendering(bool prepareChildren = true) = 0;
};
/**
* greebo: This class represents a single D3 GUI. It holds all
* the windowDefs and the source code behind.
*/
class IGui
{
public:
virtual ~IGui() {}
virtual const IGuiWindowDefPtr& getDesktop() const = 0;
virtual void setDesktop(const IGuiWindowDefPtr& newDesktop) = 0;
// Sets the given state variable (gui::<key> = <value>)
virtual void setStateString(const std::string& key, const std::string& value) = 0;
// Returns the state string "gui::<key>" or an empty string if non-existent
virtual std::string getStateString(const std::string& key) = 0;
// Sets up the time of the entire GUI (all windowDefs)
virtual void initTime(const std::size_t time) = 0;
// "Think" routine, advances all active windowDefs (where notime == false)
virtual void update(const std::size_t timestep) = 0;
// Returns a reference to the named windowDef, returns NULL if not found
virtual IGuiWindowDefPtr findWindowDef(const std::string& name) = 0;
// Called by the GuiRenderer to re-compile text VBOs, etc.
virtual void pepareRendering() = 0;
};
typedef std::shared_ptr<IGui> IGuiPtr;
enum GuiType
{
NOT_LOADED_YET, // no attempt to load the GUI has been made
UNDETERMINED, // not checked yet for type
ONE_SIDED_READABLE, // 1-sided
TWO_SIDED_READABLE, // 2-sided
NO_READABLE, // not a readable
IMPORT_FAILURE, // failed to load
FILE_NOT_FOUND, // file doesn't exist
};
/**
* greebo: Interface managing the idTech4 GUI files,
* keeping track of all the loaded GUIs,
* parsing the .gui files on demand.
*/
class IGuiManager :
public RegisterableModule
{
public:
typedef std::vector<std::string> StringList;
// A visitor class used to traverse all known GUIs by path
class Visitor
{
public:
virtual ~Visitor() {}
virtual void visit(const std::string& guiPath, const GuiType& guiType) = 0;
};
public:
virtual ~IGuiManager() {}
// Gets a GUI from the given VFS path, parsing it on demand
// Returns NULL if the GUI couldn't be found or loaded.
virtual IGuiPtr getGui(const std::string& guiPath) = 0;
// Returns the number of known GUIs (or GUI paths)
virtual std::size_t getNumGuis() = 0;
// Traverse all known GUIs using the given Visitor
virtual void foreachGui(Visitor& visitor) = 0;
// Returns the GUI appearance type for the given GUI path
virtual GuiType getGuiType(const std::string& guiPath) = 0;
// Reload the gui
virtual void reloadGui(const std::string& guiPath) = 0;
// Returns the _errorList for use in a GUI.
virtual const StringList& getErrorList() = 0;
// Clears out the GUIs and reloads them
virtual void reloadGuis() = 0;
};
}
const char* const MODULE_GUIMANAGER("GuiManager");
// Application-wide Accessor to the global GUI manager
inline gui::IGuiManager& GlobalGuiManager()
{
// Cache the reference locally
static gui::IGuiManager& _manager(
*std::static_pointer_cast<gui::IGuiManager>(
module::GlobalModuleRegistry().getModule(MODULE_GUIMANAGER))
);
return _manager;
}