1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __WINDOW_H__
30 #define __WINDOW_H__
31 
32 #include "idlib/math/Interpolate.h"
33 #include "ui/Rectangle.h"
34 #include "ui/DeviceContext.h"
35 #include "ui/RegExp.h"
36 #include "ui/Winvar.h"
37 #include "ui/GuiScript.h"
38 #include "ui/SimpleWindow.h"
39 
40 const int WIN_CHILD			= 0x00000001;
41 const int WIN_CAPTION		= 0x00000002;
42 const int WIN_BORDER		= 0x00000004;
43 const int WIN_SIZABLE		= 0x00000008;
44 const int WIN_MOVABLE		= 0x00000010;
45 const int WIN_FOCUS			= 0x00000020;
46 const int WIN_CAPTURE		= 0x00000040;
47 const int WIN_HCENTER		= 0x00000080;
48 const int WIN_VCENTER		= 0x00000100;
49 const int WIN_MODAL			= 0x00000200;
50 const int WIN_INTRANSITION	= 0x00000400;
51 const int WIN_CANFOCUS		= 0x00000800;
52 const int WIN_SELECTED		= 0x00001000;
53 const int WIN_TRANSFORM		= 0x00002000;
54 const int WIN_HOLDCAPTURE	= 0x00004000;
55 const int WIN_NOWRAP		= 0x00008000;
56 const int WIN_NOCLIP		= 0x00010000;
57 const int WIN_INVERTRECT	= 0x00020000;
58 const int WIN_NATURALMAT	= 0x00040000;
59 const int WIN_NOCURSOR		= 0x00080000;
60 const int WIN_MENUGUI		= 0x00100000;
61 const int WIN_ACTIVE		= 0x00200000;
62 const int WIN_SHOWCOORDS	= 0x00400000;
63 const int WIN_SHOWTIME		= 0x00800000;
64 const int WIN_WANTENTER		= 0x01000000;
65 
66 const int WIN_DESKTOP		= 0x10000000;
67 
68 const int WIN_SCALETO43		= 0x20000000; // DG: for the "scaleto43" window flag (=> scale window to 4:3 with "empty" bars left/right or above/below)
69 
70 const char CAPTION_HEIGHT[] = "16.0";
71 const char SCROLLER_SIZE[] = "16.0";
72 const int SCROLLBAR_SIZE = 16;
73 
74 const int MAX_WINDOW_NAME = 32;
75 const int MAX_LIST_ITEMS = 1024;
76 
77 const int MAX_EXPRESSION_OPS = 4096;
78 const int MAX_EXPRESSION_REGISTERS = 4096;
79 
80 const char DEFAULT_BACKCOLOR[] = "1 1 1 1";
81 const char DEFAULT_FORECOLOR[] = "0 0 0 1";
82 const char DEFAULT_BORDERCOLOR[] = "0 0 0 1";
83 const char DEFAULT_TEXTSCALE[] = "0.4";
84 
85 typedef enum {
86 	WOP_TYPE_ADD,
87 	WOP_TYPE_SUBTRACT,
88 	WOP_TYPE_MULTIPLY,
89 	WOP_TYPE_DIVIDE,
90 	WOP_TYPE_MOD,
91 	WOP_TYPE_TABLE,
92 	WOP_TYPE_GT,
93 	WOP_TYPE_GE,
94 	WOP_TYPE_LT,
95 	WOP_TYPE_LE,
96 	WOP_TYPE_EQ,
97 	WOP_TYPE_NE,
98 	WOP_TYPE_AND,
99 	WOP_TYPE_OR,
100 	WOP_TYPE_VAR,
101 	WOP_TYPE_VARS,
102 	WOP_TYPE_VARF,
103 	WOP_TYPE_VARI,
104 	WOP_TYPE_VARB,
105 	WOP_TYPE_COND
106 } wexpOpType_t;
107 
108 typedef enum {
109 	WEXP_REG_TIME,
110 	WEXP_REG_NUM_PREDEFINED
111 } wexpRegister_t;
112 
113 typedef struct {
114 	wexpOpType_t opType;
115 	intptr_t a, b, c, d;
116 } wexpOp_t;
117 
118 struct idRegEntry {
119 	const char *name;
120 	idRegister::REGTYPE type;
121 	int index;
122 };
123 
124 class rvGEWindowWrapper;
125 class idWindow;
126 
127 struct idTimeLineEvent {
idTimeLineEventidTimeLineEvent128 	idTimeLineEvent() {
129 		event = new idGuiScriptList;
130 	}
~idTimeLineEventidTimeLineEvent131 	~idTimeLineEvent() {
132 		delete event;
133 	}
134 	int time;
135 	idGuiScriptList *event;
136 	bool pending;
SizeidTimeLineEvent137 	size_t Size() {
138 		return sizeof(*this) + event->Size();
139 	}
140 };
141 
142 class rvNamedEvent
143 {
144 public:
145 
rvNamedEvent(const char * name)146 	rvNamedEvent(const char* name)
147 	{
148 		mEvent = new idGuiScriptList;
149 		mName  = name;
150 	}
~rvNamedEvent(void)151 	~rvNamedEvent(void)
152 	{
153 		delete mEvent;
154 	}
Size()155 	size_t Size()
156 	{
157 		return sizeof(*this) + mEvent->Size();
158 	}
159 
160 	idStr				mName;
161 	idGuiScriptList*	mEvent;
162 };
163 
164 struct idTransitionData {
165 	idWinVar *data;
166 	int	offset;
167 	idInterpolateAccelDecelLinear<idVec4> interp;
168 };
169 
170 
171 class idUserInterfaceLocal;
172 class idWindow {
173 public:
174 	idWindow(idUserInterfaceLocal *gui);
175 	idWindow(idDeviceContext *d, idUserInterfaceLocal *gui);
176 	virtual ~idWindow();
177 
178 	enum {
179 		ON_MOUSEENTER = 0,
180 		ON_MOUSEEXIT,
181 		ON_ACTION,
182 		ON_ACTIVATE,
183 		ON_DEACTIVATE,
184 		ON_ESC,
185 		ON_FRAME,
186 		ON_TRIGGER,
187 		ON_ACTIONRELEASE,
188 		ON_ENTER,
189 		ON_ENTERRELEASE,
190 		SCRIPT_COUNT
191 	};
192 
193 	enum {
194 		ADJUST_MOVE = 0,
195 		ADJUST_TOP,
196 		ADJUST_RIGHT,
197 		ADJUST_BOTTOM,
198 		ADJUST_LEFT,
199 		ADJUST_TOPLEFT,
200 		ADJUST_BOTTOMRIGHT,
201 		ADJUST_TOPRIGHT,
202 		ADJUST_BOTTOMLEFT
203 	};
204 
205 	static const char *ScriptNames[SCRIPT_COUNT];
206 
207 	static const idRegEntry RegisterVars[];
208 	static const int		NumRegisterVars;
209 
210 	void SetDC(idDeviceContext *d);
211 
GetDC(void)212 	idDeviceContext*	GetDC ( void ) { return dc; }
213 
214 	idWindow *SetFocus(idWindow *w, bool scripts = true);
215 
216 	idWindow *SetCapture(idWindow *w);
217 	void SetParent(idWindow *w);
218 	void SetFlag(unsigned int f);
219 	void ClearFlag(unsigned int f);
GetFlags()220 	unsigned GetFlags() {return flags;};
221 	void Move(float x, float y);
222 	void BringToTop(idWindow *w);
223 	void Adjust(float xd, float yd);
224 	void SetAdjustMode(idWindow *child);
225 	void Size(float x, float y, float w, float h);
226 	void SetupFromState();
227 	void SetupBackground();
228 	drawWin_t *FindChildByName(const char *name);
229 	idSimpleWindow *FindSimpleWinByName(const char *_name);
GetParent()230 	idWindow *GetParent() { return parent; }
GetGui()231 	idUserInterfaceLocal *GetGui() {return gui;};
232 	bool Contains(float x, float y);
233 	size_t Size();
234 	virtual size_t Allocated();
235 	idStr* GetStrPtrByName(const char *_name);
236 
237 	virtual idWinVar *GetWinVarByName	(const char *_name, bool winLookup = false, drawWin_t** owner = NULL);
238 
239 	intptr_t GetWinVarOffset( idWinVar *wv, drawWin_t *dw );
240 	float GetMaxCharHeight();
241 	float GetMaxCharWidth();
242 	void SetFont();
243 	void SetInitialState(const char *_name);
244 	void AddChild(idWindow *win);
245 	void DebugDraw(int time, float x, float y);
246 	void CalcClientRect(float xofs, float yofs);
247 	void CommonInit();
248 	void CleanUp();
249 	void DrawBorderAndCaption(const idRectangle &drawRect);
250 	void DrawCaption(int time, float x, float y);
251 	void SetupTransforms(float x, float y);
252 	bool Contains(const idRectangle &sr, float x, float y);
GetName()253 	const char *GetName() { return name; };
254 
255 	virtual bool Parse(idParser *src, bool rebuild = true);
256 	virtual const char *HandleEvent(const sysEvent_t *event, bool *updateVisuals);
257 	void	CalcRects(float x, float y);
258 	virtual void Redraw(float x, float y);
259 
260 	virtual void ArchiveToDictionary(idDict *dict, bool useNames = true);
261 	virtual void InitFromDictionary(idDict *dict, bool byName = true);
262 	virtual void PostParse();
263 	virtual void Activate( bool activate, idStr &act );
264 	virtual void Trigger();
265 	virtual void GainFocus();
266 	virtual void LoseFocus();
267 	virtual void GainCapture();
268 	virtual void LoseCapture();
269 	virtual void Sized();
270 	virtual void Moved();
271 	virtual void Draw(int time, float x, float y);
272 	virtual void MouseExit();
273 	virtual void MouseEnter();
274 	virtual void DrawBackground(const idRectangle &drawRect);
275 	virtual const char *RouteMouseCoords(float xd, float yd);
SetBuddy(idWindow * buddy)276 	virtual void SetBuddy(idWindow *buddy) {};
HandleBuddyUpdate(idWindow * buddy)277 	virtual void HandleBuddyUpdate(idWindow *buddy) {};
278 	virtual void StateChanged( bool redraw );
279 	virtual void ReadFromDemoFile( class idDemoFile *f, bool rebuild = true );
280 	virtual void WriteToDemoFile( class idDemoFile *f );
281 
282 	// SaveGame support
283 	void			WriteSaveGameString( const char *string, idFile *savefile );
284 	void			WriteSaveGameTransition( idTransitionData &trans, idFile *savefile );
285 	virtual void	WriteToSaveGame( idFile *savefile );
286 	void			ReadSaveGameString( idStr &string, idFile *savefile );
287 	void			ReadSaveGameTransition( idTransitionData & trans, idFile *savefile );
288 	virtual void	ReadFromSaveGame( idFile *savefile );
289 	void			FixupTransitions();
HasAction()290 	virtual void HasAction(){};
HasScripts()291 	virtual void HasScripts(){};
292 
293 	void FixupParms();
294 	void GetScriptString(const char *name, idStr &out);
295 	void SetScriptParams();
HasOps()296 	bool HasOps() {	return (ops.Num() > 0); };
297 	float EvalRegs(int test = -1, bool force = false);
298 	void StartTransition();
299 	void AddTransition(idWinVar *dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime);
300 	void ResetTime(int time);
301 	void ResetCinematics();
302 
303 	int NumTransitions();
304 
305 	bool ParseScript(idParser *src, idGuiScriptList &list, int *timeParm = NULL, bool allowIf = false);
306 	bool RunScript(int n);
307 	bool RunScriptList(idGuiScriptList *src);
308 	void SetRegs(const char *key, const char *val);
309 	intptr_t ParseExpression( idParser *src, idWinVar *var = NULL, intptr_t component = 0 );
310 	int ExpressionConstant(float f);
RegList()311 	idRegisterList *RegList() { return &regList; }
312 	void AddCommand(const char *cmd);
313 	void AddUpdateVar(idWinVar *var);
314 	bool Interactive();
315 	bool ContainsStateVars();
316 	void SetChildWinVarVal(const char *name, const char *var, const char *val);
317 	idWindow *GetFocusedChild();
318 	idWindow *GetCaptureChild();
GetComment()319 	const char *GetComment() { return comment;  }
SetComment(const char * p)320 	void SetComment( const char * p) { comment = p; }
321 
322 	idStr cmd;
323 
324 	virtual void RunNamedEvent		( const char* eventName );
325 
326 	void		AddDefinedVar		( idWinVar* var );
327 
328 	idWindow*	FindChildByPoint	( float x, float y, idWindow* below = NULL );
329 	int			GetChildIndex		( idWindow* window );
330 	int			GetChildCount		( void );
331 	idWindow*	GetChild			( int index );
332 	void		RemoveChild			( idWindow *win );
333 	bool		InsertChild			( idWindow *win, idWindow* before );
334 
335 	void		ScreenToClient		( idRectangle* rect );
336 	void		ClientToScreen		( idRectangle* rect );
337 
338 	bool		UpdateFromDictionary ( idDict& dict );
339 
340 protected:
341 
342 	friend		class rvGEWindowWrapper;
343 
344 	idWindow*	FindChildByPoint	( float x, float y, idWindow** below );
345 	void		SetDefaults			( void );
346 
347 	friend class idSimpleWindow;
348 	friend class idUserInterfaceLocal;
349 	bool IsSimple();
350 	void UpdateWinVars();
351 	void DisableRegister(const char *_name);
352 	void Transition();
353 	void Time();
354 	bool RunTimeEvents(int time);
355 	void Dump();
356 
357 	int ExpressionTemporary();
358 	wexpOp_t *ExpressionOp();
359 	intptr_t EmitOp( intptr_t a, intptr_t b, wexpOpType_t opType, wexpOp_t **opp = NULL );
360 	intptr_t ParseEmitOp( idParser *src, intptr_t a, wexpOpType_t opType, int priority, wexpOp_t **opp = NULL );
361 	intptr_t ParseTerm( idParser *src, idWinVar *var = NULL, intptr_t component = 0 );
362 	intptr_t ParseExpressionPriority( idParser *src, int priority, idWinVar *var = NULL, intptr_t component = 0 );
363 	void EvaluateRegisters(float *registers);
364 	void SaveExpressionParseState();
365 	void RestoreExpressionParseState();
366 	void ParseBracedExpression(idParser *src);
367 	bool ParseScriptEntry(const char *name, idParser *src);
368 	bool ParseRegEntry(const char *name, idParser *src);
369 	virtual bool ParseInternalVar(const char *name, idParser *src);
370 	void ParseString(idParser *src, idStr &out);
371 	void ParseVec4(idParser *src, idVec4 &out);
372 	void ConvertRegEntry(const char *name, idParser *src, idStr &out, int tabs);
373 
374 	float actualX;					// physical coords
375 	float actualY;					// ''
376 	int	  childID;					// this childs id
377 	unsigned int flags;             // visible, focus, mouseover, cursor, border, etc..
378 	int lastTimeRun;				//
379 	idRectangle drawRect;			// overall rect
380 	idRectangle clientRect;			// client area
381 	idVec2	origin;
382 
383 	int timeLine;					// time stamp used for various fx
384 	float xOffset;
385 	float yOffset;
386 	float forceAspectWidth;
387 	float forceAspectHeight;
388 	float matScalex;
389 	float matScaley;
390 	float borderSize;
391 	float textAlignx;
392 	float textAligny;
393 	idStr	name;
394 	idStr	comment;
395 	idVec2	shear;
396 
397 	signed char	textShadow;
398 	unsigned char fontNum;
399 	unsigned char cursor;					//
400 	signed char	textAlign;
401 
402 	idWinBool	noTime;					//
403 	idWinBool	visible;				//
404 	idWinBool	noEvents;
405 	idWinRectangle rect;				// overall rect
406 	idWinVec4	backColor;
407 	idWinVec4	matColor;
408 	idWinVec4	foreColor;
409 	idWinVec4	hoverColor;
410 	idWinVec4	borderColor;
411 	idWinFloat	textScale;
412 	idWinFloat	rotate;
413 	idWinStr	text;
414 	idWinBackground	backGroundName;			//
415 
416 	idList<idWinVar*> definedVars;
417 	idList<idWinVar*> updateVars;
418 
419 	idRectangle textRect;			// text extented rect
420 	const idMaterial *background;         // background asset
421 
422 	idWindow *parent;				// parent window
423 	idList<idWindow*> children;		// child windows
424 	idList<drawWin_t> drawWindows;
425 
426 	idWindow *focusedChild;			// if a child window has the focus
427 	idWindow *captureChild;			// if a child window has mouse capture
428 	idWindow *overChild;			// if a child window has mouse capture
429 	bool hover;
430 
431 	idDeviceContext *dc;
432 
433 	idUserInterfaceLocal *gui;
434 
435 	static idCVar gui_debug;
436 	static idCVar gui_edit;
437 
438 	idGuiScriptList *scripts[SCRIPT_COUNT];
439 	bool *saveTemps;
440 
441 	idList<idTimeLineEvent*> timeLineEvents;
442 	idList<idTransitionData> transitions;
443 
444 	static bool registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to assist during parsing
445 
446 	idList<wexpOp_t> ops;				// evaluate to make expressionRegisters
447 	idList<float> expressionRegisters;
448 	idList<wexpOp_t> *saveOps;				// evaluate to make expressionRegisters
449 	idList<rvNamedEvent*>		namedEvents;		//  added named events
450 	idList<float> *saveRegs;
451 
452 	idRegisterList regList;
453 
454 	idWinBool	hideCursor;
455 };
456 
AddDefinedVar(idWinVar * var)457 ID_INLINE void idWindow::AddDefinedVar( idWinVar* var ) {
458 	definedVars.AddUnique( var );
459 }
460 
461 #endif /* !__WINDOW_H__ */
462