1 /*
2 	GWEN
3 	Copyright (c) 2010 Facepunch Studios
4 	See license in Gwen.h
5 */
6 
7 #pragma once
8 #ifndef GWEN_CONTROLS_BASE_H
9 #define GWEN_CONTROLS_BASE_H
10 
11 #include "Gwen/Exports.h"
12 #include "Gwen/Structures.h"
13 #include "Gwen/BaseRender.h"
14 #include "Gwen/Events.h"
15 #include <list>
16 #include <map>
17 
18 #define GWEN_DECLARE_CAST(T)                        \
19 	virtual class T* DynamicCast##T() { return 0; } \
20 	virtual const class T* DynamicCast##T() const { return 0; }
21 
22 #define GWEN_IMPLEMENT_CAST(T)                             \
23 	virtual class T* DynamicCast##T() { return (T*)this; } \
24 	virtual const class T* DynamicCast##T() const { return (T*)this; }
25 
26 namespace Gwen
27 {
28 namespace ControlsInternal
29 {
30 class ColorDisplay;
31 class Resizer;
32 
33 };  // namespace ControlsInternal
34 
35 namespace Pos
36 {
37 enum
38 {
39 	None = 0,
40 	Left = (1 << 1),
41 	Right = (1 << 2),
42 	Top = (1 << 3),
43 	Bottom = (1 << 4),
44 	CenterV = (1 << 5),
45 	CenterH = (1 << 6),
46 	Fill = (1 << 7),
47 	Center = CenterV | CenterH,
48 };
49 }
50 
51 namespace Skin
52 {
53 class Base;
54 }
55 
56 namespace Controls
57 {
58 class Canvas;
59 
60 namespace Layout
61 {
62 class TableRow;
63 };
64 
65 class GWEN_EXPORT Base : public Event::Handler
66 {
67 public:
GWEN_DECLARE_CAST(TabButton)68 	GWEN_DECLARE_CAST(TabButton)
69 	GWEN_DECLARE_CAST(DockedTabControl)
70 	virtual class Layout::TableRow* DynamicCastLayoutTableRow() { return 0; }
DynamicCastLayoutTableRow()71 	virtual const class Layout::TableRow* DynamicCastLayoutTableRow() const { return 0; }
72 
73 	GWEN_DECLARE_CAST(TextBoxNumeric)
GWEN_DECLARE_CAST(HorizontalSlider)74 	GWEN_DECLARE_CAST(HorizontalSlider)
75 	GWEN_DECLARE_CAST(DockBase)
76 	GWEN_DECLARE_CAST(MenuItem)
77 	GWEN_DECLARE_CAST(PropertyRow)
78 	GWEN_DECLARE_CAST(WindowControl)
79 
80 	GWEN_DECLARE_CAST(TreeControl)
81 	GWEN_DECLARE_CAST(TreeNode)
82 	GWEN_DECLARE_CAST(HSVColorPicker)
83 	GWEN_DECLARE_CAST(TabControl)
84 
85 	GWEN_DECLARE_CAST(TabControlInner)
86 	GWEN_DECLARE_CAST(GroupBox)
87 	GWEN_DECLARE_CAST(Properties)
88 	GWEN_DECLARE_CAST(RadioButton)
89 	GWEN_DECLARE_CAST(LabeledRadioButton)
90 
91 	virtual class ::Gwen::ControlsInternal::Resizer* DynamicCastResizer() { return 0; }
DynamicCastResizer()92 	virtual const class ::Gwen::ControlsInternal::Resizer* DynamicCastResizer() const { return 0; }
93 
DynamicCastColorDisplay()94 	virtual class ::Gwen::ControlsInternal::ColorDisplay* DynamicCastColorDisplay() { return 0; }
DynamicCastColorDisplay()95 	virtual const class ::Gwen::ControlsInternal::ColorDisplay* DynamicCastColorDisplay() const { return 0; }
96 
97 	typedef std::list<Base*> List;
98 
99 	typedef std::map<Gwen::UnicodeString, Gwen::Event::Caller*> AccelMap;
100 
101 	Base(Base* pParent);
102 	virtual ~Base();
103 
104 	virtual void DelayedDelete();
105 
106 	virtual void SetParent(Controls::Base* pParent);
GetParent()107 	virtual Controls::Base* GetParent() const { return m_Parent; }
108 	virtual Controls::Canvas* GetCanvas();
109 
GetChildren()110 	virtual Base::List& GetChildren()
111 	{
112 		if (m_InnerPanel) return m_InnerPanel->GetChildren();
113 		return Children;
114 	}
115 	virtual bool IsChild(Controls::Base* pChild);
116 	virtual int NumChildren();
117 	virtual bool SizeToChildren(bool w = true, bool h = true);
118 	virtual Gwen::Point ChildrenSize();
119 	virtual Controls::Base* FindChildByName(const Gwen::String& name, bool bRecursive = false);
120 
SetName(Gwen::String name)121 	virtual void SetName(Gwen::String name) { m_Name = name; }
GetName()122 	virtual const Gwen::String& GetName() { return m_Name; }
123 
Think()124 	virtual void Think() {}
ExpandAll()125 	virtual void ExpandAll() {}
SizeToContents()126 	virtual void SizeToContents() {}
IsActive()127 	virtual bool IsActive() { return false; }
128 
129 	virtual void AddChild(Controls::Base* pChild);
130 
131 	virtual void RemoveChild(Controls::Base* pParent);
132 
133 protected:
134 	virtual void OnChildAdded(Controls::Base* pChild);
135 	virtual void OnChildRemoved(Controls::Base* pChild);
136 
137 public:
138 	virtual void RemoveAllChildren();
139 
140 	virtual void SendToBack(void);
141 	virtual void BringToFront(void);
142 	virtual void BringNextToControl(Controls::Base* pChild, bool bBehind);
143 
144 	virtual Gwen::Point LocalPosToCanvas(const Gwen::Point& in);
145 	virtual Gwen::Point CanvasPosToLocal(const Gwen::Point& in);
146 
147 	virtual void Dock(int iDock);
148 	virtual int GetDock();
149 
RestrictToParent(bool restrict)150 	virtual void RestrictToParent(bool restrict) { m_bRestrictToParent = restrict; }
ShouldRestrictToParent()151 	virtual bool ShouldRestrictToParent() { return m_bRestrictToParent; }
152 
X()153 	virtual int X() const
154 	{
155 		return m_Bounds.x;
156 	}
Y()157 	virtual int Y() const
158 	{
159 		return m_Bounds.y;
160 	}
Width()161 	virtual int Width() const
162 	{
163 		return m_Bounds.w;
164 	}
Height()165 	virtual int Height() const
166 	{
167 		return m_Bounds.h;
168 	}
Bottom()169 	virtual int Bottom() const
170 	{
171 		return m_Bounds.y + m_Bounds.h + m_Margin.bottom;
172 	}
Right()173 	virtual int Right() const
174 	{
175 		return m_Bounds.x + m_Bounds.w + m_Margin.right;
176 	}
177 
GetMargin()178 	virtual const Margin& GetMargin() const { return m_Margin; }
GetPadding()179 	virtual const Padding& GetPadding() const { return m_Padding; }
180 
181 	virtual void SetPos(int x, int y);
SetWidth(int w)182 	virtual void SetWidth(int w)
183 	{
184 		SetSize(w, Height());
185 	}
SetHeight(int h)186 	virtual void SetHeight(int h)
187 	{
188 		SetSize(Width(), h);
189 	}
190 	virtual bool SetSize(int w, int h);
191 	virtual bool SetBounds(int x, int y, int w, int h);
192 	virtual bool SetBounds(const Gwen::Rect& bounds);
193 
194 	virtual void SetPadding(const Padding& padding);
195 	virtual void SetMargin(const Margin& margin);
196 
197 	// MoveTo is identical to SetPos except it uses ShouldRestrictToParent()
198 	virtual void MoveTo(int x, int y);
199 	virtual void MoveBy(int x, int y);
200 
GetBounds()201 	virtual const Gwen::Rect& GetBounds() const
202 	{
203 		return m_Bounds;
204 	}
205 
206 	virtual Controls::Base* GetControlAt(int x, int y);
207 
208 protected:
209 	virtual void OnBoundsChanged(Gwen::Rect oldBounds);
210 	virtual void OnChildBoundsChanged(Gwen::Rect oldChildBounds, Base* pChild);
211 
212 	virtual void OnScaleChanged();
213 
214 public:
215 	// Innerbounds is the area inside the control that
216 	// doesn't have child controls docked to it.
GetInnerBounds()217 	virtual const Gwen::Rect& GetInnerBounds() const { return m_InnerBounds; }
218 
219 protected:
220 	Gwen::Rect m_InnerBounds;
221 
222 public:
GetRenderBounds()223 	virtual const Gwen::Rect& GetRenderBounds() const { return m_RenderBounds; }
224 
225 protected:
226 	virtual void UpdateRenderBounds();
227 
228 public:
229 	virtual void DoRender(Gwen::Skin::Base* skin);
230 	virtual void DoCacheRender(Gwen::Skin::Base* skin, Gwen::Controls::Base* pMaster);
231 
232 protected:
233 	virtual void Render(Gwen::Skin::Base* skin);
RenderUnder(Gwen::Skin::Base *)234 	virtual void RenderUnder(Gwen::Skin::Base* /*skin*/){};
RenderOver(Gwen::Skin::Base *)235 	virtual void RenderOver(Gwen::Skin::Base* /*skin*/){};
236 	virtual void RenderFocus(Gwen::Skin::Base* /*skin*/);
237 
238 public:
SetHidden(bool hidden)239 	virtual void SetHidden(bool hidden)
240 	{
241 		if (m_bHidden == hidden)
242 			return;
243 		m_bHidden = hidden;
244 		Invalidate();
245 	}
246 	virtual bool Hidden() const;   // Returns true only if this control is hidden
247 	virtual bool Visible() const;  // Returns false if this control or its parents are hidden
Hide()248 	virtual void Hide() { SetHidden(true); }
Show()249 	virtual void Show() { SetHidden(false); }
250 
251 	//Skin
252 	virtual void SetSkin(Skin::Base* skin, bool doChildren = false);
253 	virtual Gwen::Skin::Base* GetSkin(void);
254 
255 	// Background drawing
ShouldDrawBackground()256 	virtual bool ShouldDrawBackground() { return m_bDrawBackground; }
SetShouldDrawBackground(bool b)257 	virtual void SetShouldDrawBackground(bool b) { m_bDrawBackground = b; }
258 
259 protected:
260 	virtual void OnSkinChanged(Gwen::Skin::Base* newSkin);
261 
262 public:
263 	virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
264 	virtual bool OnMouseWheeled(int iDelta);
OnMouseClickLeft(int,int,bool)265 	virtual void OnMouseClickLeft(int /*x*/, int /*y*/, bool /*bDown*/){};
OnMouseClickRight(int,int,bool)266 	virtual void OnMouseClickRight(int /*x*/, int /*y*/, bool /*bDown*/) {}
OnMouseDoubleClickLeft(int x,int y)267 	virtual void OnMouseDoubleClickLeft(int x, int y) { OnMouseClickLeft(x, y, true); };
OnMouseDoubleClickRight(int x,int y)268 	virtual void OnMouseDoubleClickRight(int x, int y) { OnMouseClickRight(x, y, true); };
OnLostKeyboardFocus()269 	virtual void OnLostKeyboardFocus() {}
OnKeyboardFocus()270 	virtual void OnKeyboardFocus() {}
271 
SetMouseInputEnabled(bool b)272 	virtual void SetMouseInputEnabled(bool b) { m_bMouseInputEnabled = b; }
GetMouseInputEnabled()273 	virtual bool GetMouseInputEnabled() { return m_bMouseInputEnabled; }
274 
SetKeyboardInputEnabled(bool b)275 	virtual void SetKeyboardInputEnabled(bool b) { m_bKeyboardInputEnabled = b; }
GetKeyboardInputEnabled()276 	virtual bool GetKeyboardInputEnabled() const { return m_bKeyboardInputEnabled; }
NeedsInputChars()277 	virtual bool NeedsInputChars() { return false; }
278 
OnChar(Gwen::UnicodeChar)279 	virtual bool OnChar(Gwen::UnicodeChar /*c*/) { return false; }
280 
281 	virtual bool OnKeyPress(int iKey, bool bPress = true);
282 	virtual bool OnKeyRelease(int iKey);
283 
OnPaste(Controls::Base *)284 	virtual void OnPaste(Controls::Base* /*pFrom*/) {}
OnCopy(Controls::Base *)285 	virtual void OnCopy(Controls::Base* /*pFrom*/) {}
OnCut(Controls::Base *)286 	virtual void OnCut(Controls::Base* /*pFrom*/) {}
OnSelectAll(Controls::Base *)287 	virtual void OnSelectAll(Controls::Base* /*pFrom*/) {}
288 
289 	virtual bool OnKeyTab(bool bDown);
OnKeySpace(bool)290 	virtual bool OnKeySpace(bool /*bDown*/) { return false; }
OnKeyReturn(bool)291 	virtual bool OnKeyReturn(bool /*bDown*/) { return false; }
OnKeyBackspace(bool)292 	virtual bool OnKeyBackspace(bool /*bDown*/) { return false; }
OnKeyDelete(bool)293 	virtual bool OnKeyDelete(bool /*bDown*/) { return false; }
OnKeyRight(bool)294 	virtual bool OnKeyRight(bool /*bDown*/) { return false; }
OnKeyLeft(bool)295 	virtual bool OnKeyLeft(bool /*bDown*/) { return false; }
OnKeyHome(bool)296 	virtual bool OnKeyHome(bool /*bDown*/) { return false; }
OnKeyEnd(bool)297 	virtual bool OnKeyEnd(bool /*bDown*/) { return false; }
OnKeyUp(bool)298 	virtual bool OnKeyUp(bool /*bDown*/) { return false; }
OnKeyDown(bool)299 	virtual bool OnKeyDown(bool /*bDown*/) { return false; }
OnKeyEscape(bool)300 	virtual bool OnKeyEscape(bool /*bDown*/) { return false; }
301 
302 	virtual void OnMouseEnter();
303 	virtual void OnMouseLeave();
304 	virtual bool IsHovered();
305 	virtual bool ShouldDrawHover();
306 
307 	virtual void Touch();
308 	virtual void OnChildTouched(Controls::Base* pChild);
309 
310 	virtual bool IsOnTop();
311 
312 	virtual bool HasFocus();
313 	virtual void Focus();
314 	virtual void Blur();
315 
316 	//Other
SetDisabled(bool active)317 	virtual void SetDisabled(bool active) { m_bDisabled = active; }
IsDisabled()318 	virtual bool IsDisabled() { return m_bDisabled; }
319 
Redraw()320 	virtual void Redraw()
321 	{
322 		m_bCacheTextureDirty = true;
323 		if (m_Parent) m_Parent->Redraw();
324 	}
SetCacheToTexture()325 	virtual void SetCacheToTexture() { m_bCacheToTexture = true; }
ShouldCacheToTexture()326 	virtual bool ShouldCacheToTexture() { return m_bCacheToTexture; }
327 
SetCursor(unsigned char c)328 	virtual void SetCursor(unsigned char c) { m_Cursor = c; }
329 	virtual void UpdateCursor();
330 
GetMinimumSize()331 	virtual Gwen::Point GetMinimumSize() { return Gwen::Point(1, 1); }
GetMaximumSize()332 	virtual Gwen::Point GetMaximumSize() { return Gwen::Point(4096, 4096); }
333 
334 	virtual void SetToolTip(const String& strText);
335 	virtual void SetToolTip(const UnicodeString& strText);
SetToolTip(Base * tooltip)336 	virtual void SetToolTip(Base* tooltip)
337 	{
338 		m_ToolTip = tooltip;
339 		if (m_ToolTip)
340 		{
341 			m_ToolTip->SetParent(this);
342 			m_ToolTip->SetHidden(true);
343 		}
344 	}
GetToolTip()345 	virtual Base* GetToolTip() { return m_ToolTip; }
346 
347 	virtual bool IsMenuComponent();
348 	virtual void CloseMenus();
349 
IsTabable()350 	virtual bool IsTabable() { return m_Tabable; }
SetTabable(bool isTabable)351 	virtual void SetTabable(bool isTabable) { m_Tabable = isTabable; }
352 
353 	//Accelerator functionality
DefaultAccel(Gwen::Controls::Base *)354 	void DefaultAccel(Gwen::Controls::Base* /*pCtrl*/) { AcceleratePressed(); }
AcceleratePressed()355 	virtual void AcceleratePressed(){};
AccelOnlyFocus()356 	virtual bool AccelOnlyFocus() { return false; }
357 	virtual bool HandleAccelerator(Gwen::UnicodeString& accelerator);
358 
359 	template <typename T>
360 	void AddAccelerator(Gwen::UnicodeString accelerator, T func, Gwen::Event::Handler* handler = NULL)
361 	{
362 		if (handler == NULL)
363 			handler = this;
364 		Gwen::Event::Caller* caller = new Gwen::Event::Caller();
365 		caller->Add(handler, func);
366 		m_Accelerators[accelerator] = caller;
367 	}
368 
AddAccelerator(Gwen::UnicodeString accelerator)369 	void AddAccelerator(Gwen::UnicodeString accelerator)
370 	{
371 		AddAccelerator(accelerator, &Base::DefaultAccel, this);
372 	}
373 
374 	AccelMap m_Accelerators;
375 
376 	// Default Events
377 
378 	Gwen::Event::Caller onHoverEnter;
379 	Gwen::Event::Caller onHoverLeave;
380 
381 	// Childrens List
382 
383 	Base::List Children;
384 
385 protected:
386 	// The logical parent
387 	// It's usually what you expect, the control you've parented it to.
388 	Base* m_Parent;
389 
390 	// If the innerpanel exists our children will automatically
391 	//  become children of that instead of us - allowing us to move
392 	//  them all around by moving that panel (useful for scrolling etc)
393 	Base* m_InnerPanel;
394 
395 	// This is the panel's actual parent - most likely the logical
396 	//  parent's InnerPanel (if it has one). You should rarely need this.
397 	Base* m_ActualParent;
398 
399 	Base* m_ToolTip;
400 
401 	Skin::Base* m_Skin;
402 
403 	Gwen::Rect m_Bounds;
404 	Gwen::Rect m_RenderBounds;
405 	Padding m_Padding;
406 	Margin m_Margin;
407 
408 	Gwen::String m_Name;
409 
410 	bool m_bRestrictToParent;
411 	bool m_bDisabled;
412 	bool m_bHidden;
413 	bool m_bMouseInputEnabled;
414 	bool m_bKeyboardInputEnabled;
415 	bool m_bDrawBackground;
416 
417 	int m_iDock;
418 
419 	unsigned char m_Cursor;
420 
421 	bool m_Tabable;
422 
423 public:
NeedsLayout()424 	bool NeedsLayout() { return m_bNeedsLayout; }
425 	void Invalidate();
InvalidateParent()426 	void InvalidateParent()
427 	{
428 		if (m_Parent)
429 		{
430 			m_Parent->Invalidate();
431 		}
432 	}
433 	void InvalidateChildren(bool bRecursive = false);
434 	void Position(int pos, int xpadding = 0, int ypadding = 0);
435 
436 protected:
437 	virtual void RecurseLayout(Skin::Base* skin);
438 	virtual void Layout(Skin::Base* skin);
PostLayout(Skin::Base *)439 	virtual void PostLayout(Skin::Base* /*skin*/){};
440 
441 	bool m_bNeedsLayout;
442 	bool m_bCacheTextureDirty;
443 	bool m_bCacheToTexture;
444 
445 	//
446 	// Drag + Drop
447 public:
448 	// Giver
449 
450 	virtual void DragAndDrop_SetPackage(bool bDraggable, const String& strName = "", void* pUserData = NULL);
451 	virtual bool DragAndDrop_Draggable();
DragAndDrop_ShouldStartDrag()452 	virtual bool DragAndDrop_ShouldStartDrag() { return true; }
453 	virtual void DragAndDrop_StartDragging(Gwen::DragAndDrop::Package* pPackage, int x, int y);
454 	virtual Gwen::DragAndDrop::Package* DragAndDrop_GetPackage(int x, int y);
DragAndDrop_EndDragging(bool,int,int)455 	virtual void DragAndDrop_EndDragging(bool /*bSuccess*/, int /*x*/, int /*y*/){};
456 
457 protected:
458 	DragAndDrop::Package* m_DragAndDrop_Package;
459 
460 public:
461 	// Receiver
DragAndDrop_HoverEnter(Gwen::DragAndDrop::Package *,int,int)462 	virtual void DragAndDrop_HoverEnter(Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/) {}
DragAndDrop_HoverLeave(Gwen::DragAndDrop::Package *)463 	virtual void DragAndDrop_HoverLeave(Gwen::DragAndDrop::Package* /*pPackage*/) {}
DragAndDrop_Hover(Gwen::DragAndDrop::Package *,int,int)464 	virtual void DragAndDrop_Hover(Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/){};
465 	virtual bool DragAndDrop_HandleDrop(Gwen::DragAndDrop::Package* pPackage, int x, int y);
DragAndDrop_CanAcceptPackage(Gwen::DragAndDrop::Package *)466 	virtual bool DragAndDrop_CanAcceptPackage(Gwen::DragAndDrop::Package* /*pPackage*/) { return false; }
467 
468 	//
469 	// This is to be used by the client implementation
470 	// NOT HOOKS ETC.
471 	//
472 public:
GetUserData()473 	void* GetUserData() { return m_pUserData; }
SetUserData(void * pData)474 	void SetUserData(void* pData) { m_pUserData = pData; }
475 
476 private:
477 	void* m_pUserData;
478 
479 	//
480 	// Useful anim shortcuts
481 	//
482 public:
483 #ifndef GWEN_NO_ANIMATION
484 
485 	virtual void Anim_WidthIn(float fLength, float fDelay = 0.0f, float fEase = 1.0f);
486 	virtual void Anim_HeightIn(float fLength, float fDelay = 0.0f, float fEase = 1.0f);
487 	virtual void Anim_WidthOut(float fLength, bool bHide = true, float fDelay = 0.0f, float fEase = 1.0f);
488 	virtual void Anim_HeightOut(float fLength, bool bHide = true, float fDelay = 0.0f, float fEase = 1.0f);
489 
490 #endif
491 };
492 
493 }  // namespace Controls
494 }  // namespace Gwen
495 
496 // To be placed in the controls .h definition.
497 #define GWEN_CONTROL(ThisName, BaseName) \
498 public:                                  \
499 	typedef BaseName BaseClass;          \
500 	typedef ThisName ThisClass;          \
501 	GWEN_IMPLEMENT_CAST(ThisName);       \
502 	ThisName(Gwen::Controls::Base* pParent)
503 
504 #define GWEN_CONTROL_INLINE(ThisName, BaseName) \
505 	GWEN_CONTROL(ThisName, BaseName) : BaseClass(pParent)
506 
507 #define GWEN_CONTROL_CONSTRUCTOR(ThisName) \
508 	ThisName::ThisName(Gwen::Controls::Base* pParent) : BaseClass(pParent)
509 
510 #endif
511