Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
511 lines
14 KiB
C++
511 lines
14 KiB
C++
/*
|
|
GWEN
|
|
Copyright (c) 2010 Facepunch Studios
|
|
See license in Gwen.h
|
|
*/
|
|
|
|
#pragma once
|
|
#ifndef GWEN_CONTROLS_BASE_H
|
|
#define GWEN_CONTROLS_BASE_H
|
|
|
|
#include "Gwen/Exports.h"
|
|
#include "Gwen/Structures.h"
|
|
#include "Gwen/BaseRender.h"
|
|
#include "Gwen/Events.h"
|
|
#include <list>
|
|
#include <map>
|
|
|
|
#define GWEN_DECLARE_CAST(T) \
|
|
virtual class T* DynamicCast##T() { return 0; } \
|
|
virtual const class T* DynamicCast##T() const { return 0; }
|
|
|
|
#define GWEN_IMPLEMENT_CAST(T) \
|
|
virtual class T* DynamicCast##T() { return (T*)this; } \
|
|
virtual const class T* DynamicCast##T() const { return (T*)this; }
|
|
|
|
namespace Gwen
|
|
{
|
|
namespace ControlsInternal
|
|
{
|
|
class ColorDisplay;
|
|
class Resizer;
|
|
|
|
}; // namespace ControlsInternal
|
|
|
|
namespace Pos
|
|
{
|
|
enum
|
|
{
|
|
None = 0,
|
|
Left = (1 << 1),
|
|
Right = (1 << 2),
|
|
Top = (1 << 3),
|
|
Bottom = (1 << 4),
|
|
CenterV = (1 << 5),
|
|
CenterH = (1 << 6),
|
|
Fill = (1 << 7),
|
|
Center = CenterV | CenterH,
|
|
};
|
|
}
|
|
|
|
namespace Skin
|
|
{
|
|
class Base;
|
|
}
|
|
|
|
namespace Controls
|
|
{
|
|
class Canvas;
|
|
|
|
namespace Layout
|
|
{
|
|
class TableRow;
|
|
};
|
|
|
|
class GWEN_EXPORT Base : public Event::Handler
|
|
{
|
|
public:
|
|
GWEN_DECLARE_CAST(TabButton)
|
|
GWEN_DECLARE_CAST(DockedTabControl)
|
|
virtual class Layout::TableRow* DynamicCastLayoutTableRow() { return 0; }
|
|
virtual const class Layout::TableRow* DynamicCastLayoutTableRow() const { return 0; }
|
|
|
|
GWEN_DECLARE_CAST(TextBoxNumeric)
|
|
GWEN_DECLARE_CAST(HorizontalSlider)
|
|
GWEN_DECLARE_CAST(DockBase)
|
|
GWEN_DECLARE_CAST(MenuItem)
|
|
GWEN_DECLARE_CAST(PropertyRow)
|
|
GWEN_DECLARE_CAST(WindowControl)
|
|
|
|
GWEN_DECLARE_CAST(TreeControl)
|
|
GWEN_DECLARE_CAST(TreeNode)
|
|
GWEN_DECLARE_CAST(HSVColorPicker)
|
|
GWEN_DECLARE_CAST(TabControl)
|
|
|
|
GWEN_DECLARE_CAST(TabControlInner)
|
|
GWEN_DECLARE_CAST(GroupBox)
|
|
GWEN_DECLARE_CAST(Properties)
|
|
GWEN_DECLARE_CAST(RadioButton)
|
|
GWEN_DECLARE_CAST(LabeledRadioButton)
|
|
|
|
virtual class ::Gwen::ControlsInternal::Resizer* DynamicCastResizer() { return 0; }
|
|
virtual const class ::Gwen::ControlsInternal::Resizer* DynamicCastResizer() const { return 0; }
|
|
|
|
virtual class ::Gwen::ControlsInternal::ColorDisplay* DynamicCastColorDisplay() { return 0; }
|
|
virtual const class ::Gwen::ControlsInternal::ColorDisplay* DynamicCastColorDisplay() const { return 0; }
|
|
|
|
typedef std::list<Base*> List;
|
|
|
|
typedef std::map<Gwen::UnicodeString, Gwen::Event::Caller*> AccelMap;
|
|
|
|
Base(Base* pParent);
|
|
virtual ~Base();
|
|
|
|
virtual void DelayedDelete();
|
|
|
|
virtual void SetParent(Controls::Base* pParent);
|
|
virtual Controls::Base* GetParent() const { return m_Parent; }
|
|
virtual Controls::Canvas* GetCanvas();
|
|
|
|
virtual Base::List& GetChildren()
|
|
{
|
|
if (m_InnerPanel) return m_InnerPanel->GetChildren();
|
|
return Children;
|
|
}
|
|
virtual bool IsChild(Controls::Base* pChild);
|
|
virtual int NumChildren();
|
|
virtual bool SizeToChildren(bool w = true, bool h = true);
|
|
virtual Gwen::Point ChildrenSize();
|
|
virtual Controls::Base* FindChildByName(const Gwen::String& name, bool bRecursive = false);
|
|
|
|
virtual void SetName(Gwen::String name) { m_Name = name; }
|
|
virtual const Gwen::String& GetName() { return m_Name; }
|
|
|
|
virtual void Think() {}
|
|
virtual void ExpandAll() {}
|
|
virtual void SizeToContents() {}
|
|
virtual bool IsActive() { return false; }
|
|
|
|
virtual void AddChild(Controls::Base* pChild);
|
|
|
|
virtual void RemoveChild(Controls::Base* pParent);
|
|
|
|
protected:
|
|
virtual void OnChildAdded(Controls::Base* pChild);
|
|
virtual void OnChildRemoved(Controls::Base* pChild);
|
|
|
|
public:
|
|
virtual void RemoveAllChildren();
|
|
|
|
virtual void SendToBack(void);
|
|
virtual void BringToFront(void);
|
|
virtual void BringNextToControl(Controls::Base* pChild, bool bBehind);
|
|
|
|
virtual Gwen::Point LocalPosToCanvas(const Gwen::Point& in);
|
|
virtual Gwen::Point CanvasPosToLocal(const Gwen::Point& in);
|
|
|
|
virtual void Dock(int iDock);
|
|
virtual int GetDock();
|
|
|
|
virtual void RestrictToParent(bool restrict) { m_bRestrictToParent = restrict; }
|
|
virtual bool ShouldRestrictToParent() { return m_bRestrictToParent; }
|
|
|
|
virtual int X() const
|
|
{
|
|
return m_Bounds.x;
|
|
}
|
|
virtual int Y() const
|
|
{
|
|
return m_Bounds.y;
|
|
}
|
|
virtual int Width() const
|
|
{
|
|
return m_Bounds.w;
|
|
}
|
|
virtual int Height() const
|
|
{
|
|
return m_Bounds.h;
|
|
}
|
|
virtual int Bottom() const
|
|
{
|
|
return m_Bounds.y + m_Bounds.h + m_Margin.bottom;
|
|
}
|
|
virtual int Right() const
|
|
{
|
|
return m_Bounds.x + m_Bounds.w + m_Margin.right;
|
|
}
|
|
|
|
virtual const Margin& GetMargin() const { return m_Margin; }
|
|
virtual const Padding& GetPadding() const { return m_Padding; }
|
|
|
|
virtual void SetPos(int x, int y);
|
|
virtual void SetWidth(int w)
|
|
{
|
|
SetSize(w, Height());
|
|
}
|
|
virtual void SetHeight(int h)
|
|
{
|
|
SetSize(Width(), h);
|
|
}
|
|
virtual bool SetSize(int w, int h);
|
|
virtual bool SetBounds(int x, int y, int w, int h);
|
|
virtual bool SetBounds(const Gwen::Rect& bounds);
|
|
|
|
virtual void SetPadding(const Padding& padding);
|
|
virtual void SetMargin(const Margin& margin);
|
|
|
|
// MoveTo is identical to SetPos except it uses ShouldRestrictToParent()
|
|
virtual void MoveTo(int x, int y);
|
|
virtual void MoveBy(int x, int y);
|
|
|
|
virtual const Gwen::Rect& GetBounds() const
|
|
{
|
|
return m_Bounds;
|
|
}
|
|
|
|
virtual Controls::Base* GetControlAt(int x, int y);
|
|
|
|
protected:
|
|
virtual void OnBoundsChanged(Gwen::Rect oldBounds);
|
|
virtual void OnChildBoundsChanged(Gwen::Rect oldChildBounds, Base* pChild);
|
|
|
|
virtual void OnScaleChanged();
|
|
|
|
public:
|
|
// Innerbounds is the area inside the control that
|
|
// doesn't have child controls docked to it.
|
|
virtual const Gwen::Rect& GetInnerBounds() const { return m_InnerBounds; }
|
|
|
|
protected:
|
|
Gwen::Rect m_InnerBounds;
|
|
|
|
public:
|
|
virtual const Gwen::Rect& GetRenderBounds() const { return m_RenderBounds; }
|
|
|
|
protected:
|
|
virtual void UpdateRenderBounds();
|
|
|
|
public:
|
|
virtual void DoRender(Gwen::Skin::Base* skin);
|
|
virtual void DoCacheRender(Gwen::Skin::Base* skin, Gwen::Controls::Base* pMaster);
|
|
|
|
protected:
|
|
virtual void Render(Gwen::Skin::Base* skin);
|
|
virtual void RenderUnder(Gwen::Skin::Base* /*skin*/){};
|
|
virtual void RenderOver(Gwen::Skin::Base* /*skin*/){};
|
|
virtual void RenderFocus(Gwen::Skin::Base* /*skin*/);
|
|
|
|
public:
|
|
virtual void SetHidden(bool hidden)
|
|
{
|
|
if (m_bHidden == hidden)
|
|
return;
|
|
m_bHidden = hidden;
|
|
Invalidate();
|
|
}
|
|
virtual bool Hidden() const; // Returns true only if this control is hidden
|
|
virtual bool Visible() const; // Returns false if this control or its parents are hidden
|
|
virtual void Hide() { SetHidden(true); }
|
|
virtual void Show() { SetHidden(false); }
|
|
|
|
//Skin
|
|
virtual void SetSkin(Skin::Base* skin, bool doChildren = false);
|
|
virtual Gwen::Skin::Base* GetSkin(void);
|
|
|
|
// Background drawing
|
|
virtual bool ShouldDrawBackground() { return m_bDrawBackground; }
|
|
virtual void SetShouldDrawBackground(bool b) { m_bDrawBackground = b; }
|
|
|
|
protected:
|
|
virtual void OnSkinChanged(Gwen::Skin::Base* newSkin);
|
|
|
|
public:
|
|
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
|
|
virtual bool OnMouseWheeled(int iDelta);
|
|
virtual void OnMouseClickLeft(int /*x*/, int /*y*/, bool /*bDown*/){};
|
|
virtual void OnMouseClickRight(int /*x*/, int /*y*/, bool /*bDown*/) {}
|
|
virtual void OnMouseDoubleClickLeft(int x, int y) { OnMouseClickLeft(x, y, true); };
|
|
virtual void OnMouseDoubleClickRight(int x, int y) { OnMouseClickRight(x, y, true); };
|
|
virtual void OnLostKeyboardFocus() {}
|
|
virtual void OnKeyboardFocus() {}
|
|
|
|
virtual void SetMouseInputEnabled(bool b) { m_bMouseInputEnabled = b; }
|
|
virtual bool GetMouseInputEnabled() { return m_bMouseInputEnabled; }
|
|
|
|
virtual void SetKeyboardInputEnabled(bool b) { m_bKeyboardInputEnabled = b; }
|
|
virtual bool GetKeyboardInputEnabled() const { return m_bKeyboardInputEnabled; }
|
|
virtual bool NeedsInputChars() { return false; }
|
|
|
|
virtual bool OnChar(Gwen::UnicodeChar /*c*/) { return false; }
|
|
|
|
virtual bool OnKeyPress(int iKey, bool bPress = true);
|
|
virtual bool OnKeyRelease(int iKey);
|
|
|
|
virtual void OnPaste(Controls::Base* /*pFrom*/) {}
|
|
virtual void OnCopy(Controls::Base* /*pFrom*/) {}
|
|
virtual void OnCut(Controls::Base* /*pFrom*/) {}
|
|
virtual void OnSelectAll(Controls::Base* /*pFrom*/) {}
|
|
|
|
virtual bool OnKeyTab(bool bDown);
|
|
virtual bool OnKeySpace(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyReturn(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyBackspace(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyDelete(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyRight(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyLeft(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyHome(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyEnd(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyUp(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyDown(bool /*bDown*/) { return false; }
|
|
virtual bool OnKeyEscape(bool /*bDown*/) { return false; }
|
|
|
|
virtual void OnMouseEnter();
|
|
virtual void OnMouseLeave();
|
|
virtual bool IsHovered();
|
|
virtual bool ShouldDrawHover();
|
|
|
|
virtual void Touch();
|
|
virtual void OnChildTouched(Controls::Base* pChild);
|
|
|
|
virtual bool IsOnTop();
|
|
|
|
virtual bool HasFocus();
|
|
virtual void Focus();
|
|
virtual void Blur();
|
|
|
|
//Other
|
|
virtual void SetDisabled(bool active) { m_bDisabled = active; }
|
|
virtual bool IsDisabled() { return m_bDisabled; }
|
|
|
|
virtual void Redraw()
|
|
{
|
|
m_bCacheTextureDirty = true;
|
|
if (m_Parent) m_Parent->Redraw();
|
|
}
|
|
virtual void SetCacheToTexture() { m_bCacheToTexture = true; }
|
|
virtual bool ShouldCacheToTexture() { return m_bCacheToTexture; }
|
|
|
|
virtual void SetCursor(unsigned char c) { m_Cursor = c; }
|
|
virtual void UpdateCursor();
|
|
|
|
virtual Gwen::Point GetMinimumSize() { return Gwen::Point(1, 1); }
|
|
virtual Gwen::Point GetMaximumSize() { return Gwen::Point(4096, 4096); }
|
|
|
|
virtual void SetToolTip(const String& strText);
|
|
virtual void SetToolTip(const UnicodeString& strText);
|
|
virtual void SetToolTip(Base* tooltip)
|
|
{
|
|
m_ToolTip = tooltip;
|
|
if (m_ToolTip)
|
|
{
|
|
m_ToolTip->SetParent(this);
|
|
m_ToolTip->SetHidden(true);
|
|
}
|
|
}
|
|
virtual Base* GetToolTip() { return m_ToolTip; }
|
|
|
|
virtual bool IsMenuComponent();
|
|
virtual void CloseMenus();
|
|
|
|
virtual bool IsTabable() { return m_Tabable; }
|
|
virtual void SetTabable(bool isTabable) { m_Tabable = isTabable; }
|
|
|
|
//Accelerator functionality
|
|
void DefaultAccel(Gwen::Controls::Base* /*pCtrl*/) { AcceleratePressed(); }
|
|
virtual void AcceleratePressed(){};
|
|
virtual bool AccelOnlyFocus() { return false; }
|
|
virtual bool HandleAccelerator(Gwen::UnicodeString& accelerator);
|
|
|
|
template <typename T>
|
|
void AddAccelerator(Gwen::UnicodeString accelerator, T func, Gwen::Event::Handler* handler = NULL)
|
|
{
|
|
if (handler == NULL)
|
|
handler = this;
|
|
Gwen::Event::Caller* caller = new Gwen::Event::Caller();
|
|
caller->Add(handler, func);
|
|
m_Accelerators[accelerator] = caller;
|
|
}
|
|
|
|
void AddAccelerator(Gwen::UnicodeString accelerator)
|
|
{
|
|
AddAccelerator(accelerator, &Base::DefaultAccel, this);
|
|
}
|
|
|
|
AccelMap m_Accelerators;
|
|
|
|
// Default Events
|
|
|
|
Gwen::Event::Caller onHoverEnter;
|
|
Gwen::Event::Caller onHoverLeave;
|
|
|
|
// Childrens List
|
|
|
|
Base::List Children;
|
|
|
|
protected:
|
|
// The logical parent
|
|
// It's usually what you expect, the control you've parented it to.
|
|
Base* m_Parent;
|
|
|
|
// If the innerpanel exists our children will automatically
|
|
// become children of that instead of us - allowing us to move
|
|
// them all around by moving that panel (useful for scrolling etc)
|
|
Base* m_InnerPanel;
|
|
|
|
// This is the panel's actual parent - most likely the logical
|
|
// parent's InnerPanel (if it has one). You should rarely need this.
|
|
Base* m_ActualParent;
|
|
|
|
Base* m_ToolTip;
|
|
|
|
Skin::Base* m_Skin;
|
|
|
|
Gwen::Rect m_Bounds;
|
|
Gwen::Rect m_RenderBounds;
|
|
Padding m_Padding;
|
|
Margin m_Margin;
|
|
|
|
Gwen::String m_Name;
|
|
|
|
bool m_bRestrictToParent;
|
|
bool m_bDisabled;
|
|
bool m_bHidden;
|
|
bool m_bMouseInputEnabled;
|
|
bool m_bKeyboardInputEnabled;
|
|
bool m_bDrawBackground;
|
|
|
|
int m_iDock;
|
|
|
|
unsigned char m_Cursor;
|
|
|
|
bool m_Tabable;
|
|
|
|
public:
|
|
bool NeedsLayout() { return m_bNeedsLayout; }
|
|
void Invalidate();
|
|
void InvalidateParent()
|
|
{
|
|
if (m_Parent)
|
|
{
|
|
m_Parent->Invalidate();
|
|
}
|
|
}
|
|
void InvalidateChildren(bool bRecursive = false);
|
|
void Position(int pos, int xpadding = 0, int ypadding = 0);
|
|
|
|
protected:
|
|
virtual void RecurseLayout(Skin::Base* skin);
|
|
virtual void Layout(Skin::Base* skin);
|
|
virtual void PostLayout(Skin::Base* /*skin*/){};
|
|
|
|
bool m_bNeedsLayout;
|
|
bool m_bCacheTextureDirty;
|
|
bool m_bCacheToTexture;
|
|
|
|
//
|
|
// Drag + Drop
|
|
public:
|
|
// Giver
|
|
|
|
virtual void DragAndDrop_SetPackage(bool bDraggable, const String& strName = "", void* pUserData = NULL);
|
|
virtual bool DragAndDrop_Draggable();
|
|
virtual bool DragAndDrop_ShouldStartDrag() { return true; }
|
|
virtual void DragAndDrop_StartDragging(Gwen::DragAndDrop::Package* pPackage, int x, int y);
|
|
virtual Gwen::DragAndDrop::Package* DragAndDrop_GetPackage(int x, int y);
|
|
virtual void DragAndDrop_EndDragging(bool /*bSuccess*/, int /*x*/, int /*y*/){};
|
|
|
|
protected:
|
|
DragAndDrop::Package* m_DragAndDrop_Package;
|
|
|
|
public:
|
|
// Receiver
|
|
virtual void DragAndDrop_HoverEnter(Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/) {}
|
|
virtual void DragAndDrop_HoverLeave(Gwen::DragAndDrop::Package* /*pPackage*/) {}
|
|
virtual void DragAndDrop_Hover(Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/){};
|
|
virtual bool DragAndDrop_HandleDrop(Gwen::DragAndDrop::Package* pPackage, int x, int y);
|
|
virtual bool DragAndDrop_CanAcceptPackage(Gwen::DragAndDrop::Package* /*pPackage*/) { return false; }
|
|
|
|
//
|
|
// This is to be used by the client implementation
|
|
// NOT HOOKS ETC.
|
|
//
|
|
public:
|
|
void* GetUserData() { return m_pUserData; }
|
|
void SetUserData(void* pData) { m_pUserData = pData; }
|
|
|
|
private:
|
|
void* m_pUserData;
|
|
|
|
//
|
|
// Useful anim shortcuts
|
|
//
|
|
public:
|
|
#ifndef GWEN_NO_ANIMATION
|
|
|
|
virtual void Anim_WidthIn(float fLength, float fDelay = 0.0f, float fEase = 1.0f);
|
|
virtual void Anim_HeightIn(float fLength, float fDelay = 0.0f, float fEase = 1.0f);
|
|
virtual void Anim_WidthOut(float fLength, bool bHide = true, float fDelay = 0.0f, float fEase = 1.0f);
|
|
virtual void Anim_HeightOut(float fLength, bool bHide = true, float fDelay = 0.0f, float fEase = 1.0f);
|
|
|
|
#endif
|
|
};
|
|
|
|
} // namespace Controls
|
|
} // namespace Gwen
|
|
|
|
// To be placed in the controls .h definition.
|
|
#define GWEN_CONTROL(ThisName, BaseName) \
|
|
public: \
|
|
typedef BaseName BaseClass; \
|
|
typedef ThisName ThisClass; \
|
|
GWEN_IMPLEMENT_CAST(ThisName); \
|
|
ThisName(Gwen::Controls::Base* pParent)
|
|
|
|
#define GWEN_CONTROL_INLINE(ThisName, BaseName) \
|
|
GWEN_CONTROL(ThisName, BaseName) : BaseClass(pParent)
|
|
|
|
#define GWEN_CONTROL_CONSTRUCTOR(ThisName) \
|
|
ThisName::ThisName(Gwen::Controls::Base* pParent) : BaseClass(pParent)
|
|
|
|
#endif
|