Files
bullet3/btgui/Gwen/Controls/Base.h
2013-03-12 23:52:31 -07:00

508 lines
15 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 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
};
}
}
// 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