1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: ui_widget.h 4084 2009-11-09 22:14:10Z dj_jl $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 
26 struct VClipRect
27 {
28 	float		OriginX;	//	Origin of the widget, in absolute coordinates.
29 	float		OriginY;
30 
31 	float		ScaleX;		//	Accomulative scale.
32 	float		ScaleY;
33 
34 	float		ClipX1;		//	Clipping rectangle, in absolute coordinates.
35 	float		ClipY1;
36 	float		ClipX2;
37 	float		ClipY2;
38 
HasAreaVClipRect39 	bool HasArea() const
40 	{
41 		return ClipX1 < ClipX2 && ClipY1 < ClipY2;
42 	}
43 };
44 
45 class VWidget : public VObject
46 {
47 	DECLARE_CLASS(VWidget, VObject, 0)
48 	NO_DEFAULT_CONSTRUCTOR(VWidget)
49 
50 private:
51 	//	Parent container widget.
52 	VWidget*			ParentWidget;
53 	//	Linked list of child widgets.
54 	VWidget*			FirstChildWidget;
55 	VWidget*			LastChildWidget;
56 	//	Links in the linked list of widgets.
57 	VWidget*			PrevWidget;
58 	VWidget*			NextWidget;
59 
60 	//	Position of the widget in the parent widget.
61 	int					PosX;
62 	int					PosY;
63 	//	Size of the child area of the widget.
64 	int					SizeWidth;
65 	int					SizeHeight;
66 	//	Scaling of the widget.
67 	float				SizeScaleX;
68 	float				SizeScaleY;
69 
70 	VClipRect			ClipRect;
71 
72 	//	Currently focused child widget.
73 	VWidget*			CurrentFocusChild;
74 
75 	VFont*				Font;
76 
77 	//	Text alignements
78 	vuint8				HAlign;
79 	vuint8				VAlign;
80 
81 	//	Text cursor
82 	int					LastX;
83 	int					LastY;
84 
85 	// Booleans
86 	enum
87 	{
88 		//	Is this widget visible?
89 		WF_IsVisible		= 0x0001,
90 		//	A flag that enables or disables Tick event.
91 		WF_TickEnabled		= 0x0002,
92 		//	Is this widget enabled and can receive input.
93 		WF_IsEnabled		= 0x0004,
94 		//	Can this widget be focused?
95 		WF_IsFocusable		= 0x0008,
96 		//	Mouse button state for click events.
97 		WF_LMouseDown		= 0x0010,
98 		WF_MMouseDown		= 0x0020,
99 		WF_RMouseDown		= 0x0040,
100 		//	Shadowed text
101 		WF_TextShadowed		= 0x0080,
102 	};
103 	vuint32				WidgetFlags;
104 
105 	VObjectDelegate 	FocusLost;
106 	VObjectDelegate 	FocusReceived;
107 
108 	VObjectDelegate 	KeyDown;
109 	VObjectDelegate 	KeyUp;
110 
111 	void AddChild(VWidget*);
112 	void RemoveChild(VWidget*);
113 
114 	void ClipTree();
115 	void DrawTree();
116 	void TickTree(float DeltaTime);
117 
118 	void FindNewFocus();
119 
120 	VWidget* GetWidgetAt(float, float);
121 
122 	bool TransferAndClipRect(float&, float&, float&, float&, float&, float&,
123 		float&, float&) const;
124 	void DrawString(int, int, const VStr&, int, int, float);
125 
126 	friend class VRootWidget;
127 
128 public:
129 	//	Destroys all child widgets.
130 	virtual void Init(VWidget*);
131 	void Destroy();
132 	void DestroyAllChildren();
133 
134 	VRootWidget* GetRootWidget();
135 
136 	//	Methods to move widget on top or bottom.
137 	void Lower();
138 	void Raise();
139 	void MoveBefore(VWidget*);
140 	void MoveAfter(VWidget*);
141 
142 	//	Methods to set position, size and scale.
SetPos(int NewX,int NewY)143 	void SetPos(int NewX, int NewY)
144 	{
145 		SetConfiguration(NewX, NewY, SizeWidth, SizeHeight, SizeScaleX,
146 			SizeScaleY);
147 	}
SetX(int NewX)148 	void SetX(int NewX)
149 	{
150 		SetPos(NewX, PosY);
151 	}
SetY(int NewY)152 	void SetY(int NewY)
153 	{
154 		SetPos(PosX, NewY);
155 	}
SetSize(int NewWidth,int NewHeight)156 	void SetSize(int NewWidth, int NewHeight)
157 	{
158 		SetConfiguration(PosX, PosY, NewWidth, NewHeight, SizeScaleX,
159 			SizeScaleY);
160 	}
SetWidth(int NewWidth)161 	void SetWidth(int NewWidth)
162 	{
163 		SetSize(NewWidth, SizeHeight);
164 	}
SetHeight(int NewHeight)165 	void SetHeight(int NewHeight)
166 	{
167 		SetSize(SizeWidth, NewHeight);
168 	}
SetScale(float NewScaleX,float NewScaleY)169 	void SetScale(float NewScaleX, float NewScaleY)
170 	{
171 		SetConfiguration(PosX, PosY, SizeWidth, SizeHeight, NewScaleX,
172 			NewScaleY);
173 	}
174 	void SetConfiguration(int, int, int, int, float = 1.0, float = 1.0);
175 
176 	//	Visibility methods.
177 	void SetVisibility(bool);
Show()178 	void Show()
179 	{
180 		SetVisibility(true);
181 	}
Hide()182 	void Hide()
183 	{
184 		SetVisibility(false);
185 	}
186 	bool IsVisible(bool bRecurse = true) const
187 	{
188 		if (bRecurse)
189 		{
190 			const VWidget* pParent = this;
191 			while (pParent)
192 			{
193 				if (!(pParent->WidgetFlags & WF_IsVisible))
194 				{
195 					break;
196 				}
197 				pParent = pParent->ParentWidget;
198 			}
199 			return (pParent ? false : true);
200 		}
201 		else
202 		{
203 			return !!(WidgetFlags & WF_IsVisible);
204 		}
205 	}
206 
207 	//	Enable state methods
208 	void SetEnabled(bool);
Enable()209 	void Enable()
210 	{
211 		SetEnabled(true);
212 	}
Disable()213 	void Disable()
214 	{
215 		SetEnabled(false);
216 	}
217 	bool IsEnabled(bool bRecurse = true) const
218 	{
219 		if (bRecurse)
220 		{
221 			const VWidget* pParent = this;
222 			while (pParent)
223 			{
224 				if (!(pParent->WidgetFlags & WF_IsEnabled))
225 				{
226 					break;
227 				}
228 				pParent = pParent->ParentWidget;
229 			}
230 			return (pParent ? false : true);
231 		}
232 		else
233 		{
234 			return !!(WidgetFlags & WF_IsEnabled);
235 		}
236 	}
237 
238 	//	Focusable state methods.
239 	void SetFocusable(bool);
IsFocusable()240 	bool IsFocusable() const
241 	{
242 		return !!(WidgetFlags & WF_IsFocusable);
243 	}
244 
245 	//	Focus methods.
246 	void SetCurrentFocusChild(VWidget*);
GetCurrentFocus()247 	VWidget* GetCurrentFocus() const
248 	{
249 		return CurrentFocusChild;
250 	}
251 	bool IsFocus(bool Recurse = true) const;
252 	void SetFocus();
253 
254 	void DrawPic(int, int, int, float = 1.0, int = 0);
255 	void DrawPic(int, int, VTexture*, float = 1.0, int = 0);
256 	void DrawShadowedPic(int, int, int);
257 	void DrawShadowedPic(int, int, VTexture*);
258 	void FillRectWithFlat(int, int, int, int, VName);
259 	void ShadeRect(int, int, int, int, float);
260 
261 	void SetFont(VFont*);
262 	void SetFont(VName);
263 	void SetTextAlign(halign_e, valign_e);
264 	void SetTextShadow(bool);
265 	void DrawText(int, int, const VStr&, int, int, float);
266 	void DrawCursor();
267 	void DrawCursorAt(int, int);
268 
269 	static VWidget *CreateNewWidget(VClass*, VWidget*);
270 
271 	//	Events.
OnCreate()272 	void OnCreate()
273 	{
274 		P_PASS_SELF;
275 		EV_RET_VOID(NAME_OnCreate);
276 	}
OnDestroy()277 	void OnDestroy()
278 	{
279 		P_PASS_SELF;
280 		EV_RET_VOID(NAME_OnDestroy);
281 	}
OnChildAdded(VWidget * Child)282 	virtual void OnChildAdded(VWidget* Child)
283 	{
284 		P_PASS_SELF;
285 		P_PASS_REF(Child);
286 		EV_RET_VOID(NAME_OnChildAdded);
287 	}
OnChildRemoved(VWidget * Child)288 	virtual void OnChildRemoved(VWidget* Child)
289 	{
290 		P_PASS_SELF;
291 		P_PASS_REF(Child);
292 		EV_RET_VOID(NAME_OnChildRemoved);
293 	}
OnConfigurationChanged()294 	virtual void OnConfigurationChanged()
295 	{
296 		P_PASS_SELF;
297 		EV_RET_VOID(NAME_OnConfigurationChanged);
298 	}
OnVisibilityChanged(bool NewVisibility)299 	virtual void OnVisibilityChanged(bool NewVisibility)
300 	{
301 		P_PASS_SELF;
302 		P_PASS_BOOL(NewVisibility);
303 		EV_RET_VOID(NAME_OnVisibilityChanged);
304 	}
OnEnableChanged(bool bNewEnable)305 	virtual void OnEnableChanged(bool bNewEnable)
306 	{
307 		P_PASS_SELF;
308 		P_PASS_BOOL(bNewEnable);
309 		EV_RET_VOID(NAME_OnEnableChanged);
310 	}
OnFocusableChanged(bool bNewFocusable)311 	virtual void OnFocusableChanged(bool bNewFocusable)
312 	{
313 		P_PASS_SELF;
314 		P_PASS_BOOL(bNewFocusable);
315 		EV_RET_VOID(NAME_OnFocusableChanged);
316 	}
OnFocusReceived()317 	virtual void OnFocusReceived()
318 	{
319 		P_PASS_SELF;
320 		EV_RET_VOID(NAME_OnFocusReceived);
321 	}
OnFocusLost()322 	virtual void OnFocusLost()
323 	{
324 		P_PASS_SELF;
325 		EV_RET_VOID(NAME_OnFocusLost);
326 	}
OnDraw()327 	virtual void OnDraw()
328 	{
329 		P_PASS_SELF;
330 		EV_RET_VOID(NAME_OnDraw);
331 	}
OnPostDraw()332 	virtual void OnPostDraw()
333 	{
334 		P_PASS_SELF;
335 		EV_RET_VOID(NAME_OnPostDraw);
336 	}
Tick(float DeltaTime)337 	virtual void Tick(float DeltaTime)
338 	{
339 		P_PASS_SELF;
340 		P_PASS_FLOAT(DeltaTime);
341 		EV_RET_VOID(NAME_Tick);
342 	}
OnKeyDown(int Key)343 	virtual bool OnKeyDown(int Key)
344 	{
345 		P_PASS_SELF;
346 		P_PASS_INT(Key);
347 		EV_RET_BOOL(NAME_OnKeyDown);
348 	}
OnKeyUp(int Key)349 	virtual bool OnKeyUp(int Key)
350 	{
351 		P_PASS_SELF;
352 		P_PASS_INT(Key);
353 		EV_RET_BOOL(NAME_OnKeyUp);
354 	}
OnMouseMove(int OldX,int OldY,int NewX,int NewY)355 	virtual bool OnMouseMove(int OldX, int OldY, int NewX, int NewY)
356 	{
357 		P_PASS_SELF;
358 		P_PASS_INT(OldX);
359 		P_PASS_INT(OldY);
360 		P_PASS_INT(NewX);
361 		P_PASS_INT(NewY);
362 		EV_RET_BOOL(NAME_OnMouseMove);
363 	}
OnMouseEnter()364 	virtual void OnMouseEnter()
365 	{
366 		P_PASS_SELF;
367 		EV_RET_VOID(NAME_OnMouseEnter);
368 	}
OnMouseLeave()369 	virtual void OnMouseLeave()
370 	{
371 		P_PASS_SELF;
372 		EV_RET_VOID(NAME_OnMouseEnter);
373 	}
OnMouseDown(int X,int Y,int Button)374 	virtual bool OnMouseDown(int X, int Y, int Button)
375 	{
376 		P_PASS_SELF;
377 		P_PASS_INT(X);
378 		P_PASS_INT(Y);
379 		P_PASS_INT(Button);
380 		EV_RET_BOOL(NAME_OnMouseDown);
381 	}
OnMouseUp(int X,int Y,int Button)382 	virtual bool OnMouseUp(int X, int Y, int Button)
383 	{
384 		P_PASS_SELF;
385 		P_PASS_INT(X);
386 		P_PASS_INT(Y);
387 		P_PASS_INT(Button);
388 		EV_RET_BOOL(NAME_OnMouseUp);
389 	}
OnMouseClick(int X,int Y)390 	virtual void OnMouseClick(int X, int Y)
391 	{
392 		P_PASS_SELF;
393 		P_PASS_INT(X);
394 		P_PASS_INT(Y);
395 		EV_RET_VOID(NAME_OnMouseClick);
396 	}
OnMMouseClick(int X,int Y)397 	virtual void OnMMouseClick(int X, int Y)
398 	{
399 		P_PASS_SELF;
400 		P_PASS_INT(X);
401 		P_PASS_INT(Y);
402 		EV_RET_VOID(NAME_OnMMouseClick);
403 	}
OnRMouseClick(int X,int Y)404 	virtual void OnRMouseClick(int X, int Y)
405 	{
406 		P_PASS_SELF;
407 		P_PASS_INT(X);
408 		P_PASS_INT(Y);
409 		EV_RET_VOID(NAME_OnRMouseClick);
410 	}
411 
412 	//	Script natives
413 	DECLARE_FUNCTION(NewChild)
414 	DECLARE_FUNCTION(Destroy)
415 	DECLARE_FUNCTION(DestroyAllChildren)
416 
417 	DECLARE_FUNCTION(GetRootWidget)
418 
419 	DECLARE_FUNCTION(Raise)
420 	DECLARE_FUNCTION(Lower)
421 	DECLARE_FUNCTION(MoveBefore)
422 	DECLARE_FUNCTION(MoveAfter)
423 
424 	DECLARE_FUNCTION(SetPos)
425 	DECLARE_FUNCTION(SetX)
426 	DECLARE_FUNCTION(SetY)
427 	DECLARE_FUNCTION(SetSize)
428 	DECLARE_FUNCTION(SetWidth)
429 	DECLARE_FUNCTION(SetHeight)
430 	DECLARE_FUNCTION(SetScale)
431 	DECLARE_FUNCTION(SetConfiguration)
432 
433 	DECLARE_FUNCTION(SetVisibility)
434 	DECLARE_FUNCTION(Show)
435 	DECLARE_FUNCTION(Hide)
436 	DECLARE_FUNCTION(IsVisible)
437 
438 	DECLARE_FUNCTION(SetEnabled)
439 	DECLARE_FUNCTION(Enable)
440 	DECLARE_FUNCTION(Disable)
441 	DECLARE_FUNCTION(IsEnabled)
442 
443 	DECLARE_FUNCTION(SetFocusable)
444 	DECLARE_FUNCTION(IsFocusable)
445 
446 	DECLARE_FUNCTION(SetCurrentFocusChild)
447 	DECLARE_FUNCTION(GetCurrentFocus)
448 	DECLARE_FUNCTION(IsFocus)
449 	DECLARE_FUNCTION(SetFocus)
450 
451 	DECLARE_FUNCTION(DrawPic)
452 	DECLARE_FUNCTION(DrawShadowedPic)
453 	DECLARE_FUNCTION(FillRectWithFlat)
454 	DECLARE_FUNCTION(ShadeRect)
455 
456 	DECLARE_FUNCTION(SetFont)
457 	DECLARE_FUNCTION(SetTextAlign)
458 	DECLARE_FUNCTION(SetTextShadow)
459 	DECLARE_FUNCTION(TextWidth)
460 	DECLARE_FUNCTION(TextHeight)
461 	DECLARE_FUNCTION(SplitText)
462 	DECLARE_FUNCTION(SplitTextWithNewlines)
463 	DECLARE_FUNCTION(DrawText)
464 	DECLARE_FUNCTION(DrawCursor)
465 	DECLARE_FUNCTION(FindTextColour)
466 };
467