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