mirror of
https://github.com/bulletphysics/bullet3
synced 2025-01-18 21:10:05 +00:00
reorganize files and add btgui
This commit is contained in:
parent
9612c2cd3d
commit
e4a7b6f487
BIN
btgui/FontFiles/DroidSansJapanese.ttf
Normal file
BIN
btgui/FontFiles/DroidSansJapanese.ttf
Normal file
Binary file not shown.
BIN
btgui/FontFiles/DroidSerif-Bold.ttf
Normal file
BIN
btgui/FontFiles/DroidSerif-Bold.ttf
Normal file
Binary file not shown.
BIN
btgui/FontFiles/DroidSerif-Italic.ttf
Normal file
BIN
btgui/FontFiles/DroidSerif-Italic.ttf
Normal file
Binary file not shown.
BIN
btgui/FontFiles/DroidSerif-Regular.ttf
Normal file
BIN
btgui/FontFiles/DroidSerif-Regular.ttf
Normal file
Binary file not shown.
21738
btgui/FontFiles/OpenSans.cpp
Normal file
21738
btgui/FontFiles/OpenSans.cpp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
btgui/FontFiles/OpenSans.ttf
Normal file
BIN
btgui/FontFiles/OpenSans.ttf
Normal file
Binary file not shown.
79
btgui/Gwen/Align.h
Normal file
79
btgui/Gwen/Align.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_ALIGN_H
|
||||
#define GWEN_ALIGN_H
|
||||
#include "Gwen/Controls/Base.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Align
|
||||
{
|
||||
inline void Center( Controls::Base* ctrl )
|
||||
{
|
||||
Controls::Base* parent = ctrl->GetParent();
|
||||
if ( !parent ) return;
|
||||
|
||||
ctrl->SetPos( parent->GetPadding().left + (((parent->Width()-parent->GetPadding().left-parent->GetPadding().right) - ctrl->Width()) / 2),
|
||||
(parent->Height() - ctrl->Height()) / 2 );
|
||||
}
|
||||
|
||||
inline void AlignLeft( Controls::Base* ctrl )
|
||||
{
|
||||
Controls::Base* parent = ctrl->GetParent();
|
||||
if ( !parent ) return;
|
||||
|
||||
ctrl->SetPos( parent->GetPadding().left, ctrl->Y() );
|
||||
}
|
||||
|
||||
inline void CenterHorizontally( Controls::Base* ctrl )
|
||||
{
|
||||
Controls::Base* parent = ctrl->GetParent();
|
||||
if ( !parent ) return;
|
||||
|
||||
|
||||
ctrl->SetPos( parent->GetPadding().left + (((parent->Width()-parent->GetPadding().left-parent->GetPadding().right) - ctrl->Width()) / 2), ctrl->Y() );
|
||||
}
|
||||
|
||||
inline void AlignRight( Controls::Base* ctrl )
|
||||
{
|
||||
Controls::Base* parent = ctrl->GetParent();
|
||||
if ( !parent ) return;
|
||||
|
||||
|
||||
ctrl->SetPos( parent->Width() - ctrl->Width() - parent->GetPadding().right, ctrl->Y() );
|
||||
}
|
||||
|
||||
inline void AlignTop( Controls::Base* ctrl )
|
||||
{
|
||||
ctrl->SetPos( ctrl->X(), 0 );
|
||||
}
|
||||
|
||||
inline void CenterVertically( Controls::Base* ctrl )
|
||||
{
|
||||
Controls::Base* parent = ctrl->GetParent();
|
||||
if ( !parent ) return;
|
||||
|
||||
ctrl->SetPos( ctrl->X(), (parent->Height() - ctrl->Height()) / 2 );
|
||||
}
|
||||
|
||||
inline void AlignBottom( Controls::Base* ctrl )
|
||||
{
|
||||
Controls::Base* parent = ctrl->GetParent();
|
||||
if ( !parent ) return;
|
||||
|
||||
ctrl->SetPos( ctrl->X(), parent->Height() - ctrl->Height() );
|
||||
}
|
||||
|
||||
inline void PlaceBelow( Controls::Base* ctrl, Controls::Base* below, int iBorder = 0 )
|
||||
{
|
||||
ctrl->SetPos( ctrl->X(), below->Bottom() + iBorder );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
142
btgui/Gwen/Anim.cpp
Normal file
142
btgui/Gwen/Anim.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Anim.h"
|
||||
#include "Gwen/Utility.h"
|
||||
#include <math.h>
|
||||
|
||||
using namespace Gwen;
|
||||
|
||||
#ifndef GWEN_NO_ANIMATION
|
||||
|
||||
static Gwen::Anim::Animation::List g_Animations;
|
||||
static Gwen::Anim::Animation::ChildList g_AnimationsListed;
|
||||
|
||||
void Gwen::Anim::Add( Gwen::Controls::Base* control, Animation* animation )
|
||||
{
|
||||
animation->m_Control = control;
|
||||
|
||||
g_Animations[control].push_back( animation );
|
||||
}
|
||||
|
||||
void Gwen::Anim::Cancel( Gwen::Controls::Base* control )
|
||||
{
|
||||
/* cannot use std::list iterator with algoryhtmns based on pointers
|
||||
struct AnimDeletePredicate
|
||||
{
|
||||
AnimDeletePredicate( Gwen::Controls::Base* control )
|
||||
{
|
||||
this->control = control;
|
||||
}
|
||||
|
||||
bool operator() ( Gwen::Anim::Animation* anim )
|
||||
{
|
||||
return anim->m_Control == control;
|
||||
}
|
||||
|
||||
Gwen::Controls::Base* control;
|
||||
};
|
||||
|
||||
std::remove_if ( g_Animations.begin(), g_Animations.end(), AnimDeletePredicate( control ) );
|
||||
*/
|
||||
Gwen::Anim::Animation::List::iterator iAnimations;
|
||||
if ((iAnimations = g_Animations.find(control)) != g_Animations.end())
|
||||
{
|
||||
Gwen::Anim::Animation::ChildList &ChildAnimationsForControl = iAnimations->second;
|
||||
Gwen::Anim::Animation::ChildList::iterator iAnimationChild = ChildAnimationsForControl.begin();
|
||||
if (iAnimationChild != ChildAnimationsForControl.end())
|
||||
{
|
||||
do
|
||||
{
|
||||
delete (*iAnimationChild);
|
||||
}while(++iAnimationChild != ChildAnimationsForControl.end());
|
||||
}
|
||||
g_Animations.erase(iAnimations);
|
||||
}
|
||||
}
|
||||
|
||||
void Gwen::Anim::Think()
|
||||
{
|
||||
Gwen::Anim::Animation::List::iterator it = g_Animations.begin();
|
||||
|
||||
if ( it != g_Animations.end() )
|
||||
{
|
||||
Gwen::Anim::Animation::ChildList::iterator itChild;
|
||||
|
||||
Gwen::Anim::Animation* anim;
|
||||
|
||||
do
|
||||
{
|
||||
if ((itChild = it->second.begin()) != it->second.end())
|
||||
{
|
||||
do
|
||||
{
|
||||
anim = *itChild;
|
||||
|
||||
anim->Think();
|
||||
|
||||
if ( anim->Finished() )
|
||||
{
|
||||
itChild = it->second.erase( itChild );
|
||||
|
||||
delete anim;
|
||||
}
|
||||
else
|
||||
{
|
||||
++itChild;
|
||||
}
|
||||
|
||||
}while(itChild != it->second.end());
|
||||
}
|
||||
|
||||
}while(++it != g_Animations.end());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Gwen::Anim::TimedAnimation::TimedAnimation( float fLength, float fDelay, float fEase )
|
||||
{
|
||||
m_fStart = Platform::GetTimeInSeconds() + fDelay;
|
||||
m_fEnd = m_fStart + fLength;
|
||||
m_fEase = fEase;
|
||||
m_bStarted = false;
|
||||
m_bFinished = false;
|
||||
}
|
||||
|
||||
void Gwen::Anim::TimedAnimation::Think()
|
||||
{
|
||||
if ( m_bFinished ) return;
|
||||
|
||||
float fCurrent = Platform::GetTimeInSeconds();
|
||||
float fSecondsIn = fCurrent - m_fStart;
|
||||
if ( fSecondsIn < 0.0f ) return;
|
||||
|
||||
if ( !m_bStarted )
|
||||
{
|
||||
m_bStarted = true;
|
||||
OnStart();
|
||||
}
|
||||
|
||||
float fDelta = fSecondsIn / ( m_fEnd - m_fStart );
|
||||
if ( fDelta < 0.0f ) fDelta = 0.0f;
|
||||
if ( fDelta > 1.0f ) fDelta = 1.0f;
|
||||
|
||||
Run( pow( fDelta, m_fEase ) );
|
||||
|
||||
if ( fDelta == 1.0f )
|
||||
{
|
||||
m_bFinished = true;
|
||||
OnFinish();
|
||||
}
|
||||
}
|
||||
|
||||
bool Gwen::Anim::TimedAnimation::Finished()
|
||||
{
|
||||
return m_bFinished;
|
||||
}
|
||||
|
||||
#endif
|
130
btgui/Gwen/Anim.h
Normal file
130
btgui/Gwen/Anim.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_ANIM_H
|
||||
#define GWEN_ANIM_H
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Platform.h"
|
||||
|
||||
#ifndef GWEN_NO_ANIMATION
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Anim
|
||||
{
|
||||
class GWEN_EXPORT Animation
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::list<Animation*> ChildList;
|
||||
typedef std::map< Gwen::Controls::Base *, ChildList > List;
|
||||
|
||||
virtual void Think() = 0;
|
||||
virtual bool Finished() = 0;
|
||||
|
||||
virtual ~Animation() {}
|
||||
|
||||
Gwen::Controls::Base* m_Control;
|
||||
};
|
||||
|
||||
GWEN_EXPORT void Add( Gwen::Controls::Base* control, Animation* animation );
|
||||
GWEN_EXPORT void Cancel( Gwen::Controls::Base* control );
|
||||
GWEN_EXPORT void Think();
|
||||
|
||||
//
|
||||
// Timed animation. Provides a useful base for animations.
|
||||
//
|
||||
class GWEN_EXPORT TimedAnimation : public Animation
|
||||
{
|
||||
public:
|
||||
|
||||
TimedAnimation( float fLength, float fDelay = 0.0f, float fEase = 1.0f );
|
||||
|
||||
virtual void Think();
|
||||
virtual bool Finished();
|
||||
|
||||
//
|
||||
// These are the magic functions you should be overriding
|
||||
//
|
||||
virtual void OnStart(){}
|
||||
virtual void Run( float /*delta*/ ){}
|
||||
virtual void OnFinish(){}
|
||||
|
||||
protected:
|
||||
|
||||
bool m_bStarted;
|
||||
bool m_bFinished;
|
||||
float m_fStart;
|
||||
float m_fEnd;
|
||||
float m_fEase;
|
||||
};
|
||||
|
||||
namespace Size
|
||||
{
|
||||
class GWEN_EXPORT Height : public TimedAnimation
|
||||
{
|
||||
public:
|
||||
|
||||
Height( int iStartSize, int iEndSize, float fLength, bool bHide = false, float fDelay = 0.0f, float fEase = 1.0f ) : TimedAnimation( fLength, fDelay, fEase )
|
||||
{
|
||||
m_iStartSize = iStartSize;
|
||||
m_iDelta = iEndSize - m_iStartSize;
|
||||
m_bHide = bHide;
|
||||
}
|
||||
|
||||
virtual void OnStart(){ m_Control->SetHeight( m_iStartSize ); }
|
||||
virtual void Run( float delta ){ m_Control->SetHeight( m_iStartSize + (((float)m_iDelta) * delta) ); }
|
||||
virtual void OnFinish(){ m_Control->SetHeight( m_iStartSize + m_iDelta ); m_Control->SetHidden( m_bHide ); }
|
||||
|
||||
protected:
|
||||
|
||||
int m_iStartSize;
|
||||
int m_iDelta;
|
||||
bool m_bHide;
|
||||
};
|
||||
|
||||
class Width : public TimedAnimation
|
||||
{
|
||||
public:
|
||||
|
||||
Width( int iStartSize, int iEndSize, float fLength, bool bHide = false, float fDelay = 0.0f, float fEase = 1.0f ) : TimedAnimation( fLength, fDelay, fEase )
|
||||
{
|
||||
m_iStartSize = iStartSize;
|
||||
m_iDelta = iEndSize - m_iStartSize;
|
||||
m_bHide = bHide;
|
||||
}
|
||||
|
||||
virtual void OnStart(){ m_Control->SetWidth( m_iStartSize ); }
|
||||
virtual void Run( float delta ){ m_Control->SetWidth( m_iStartSize + (((float)m_iDelta) * delta) ); }
|
||||
virtual void OnFinish(){ m_Control->SetWidth( m_iStartSize + m_iDelta ); m_Control->SetHidden( m_bHide ); }
|
||||
|
||||
protected:
|
||||
|
||||
int m_iStartSize;
|
||||
int m_iDelta;
|
||||
bool m_bHide;
|
||||
};
|
||||
}
|
||||
|
||||
namespace Tools
|
||||
{
|
||||
class Remove : public TimedAnimation
|
||||
{
|
||||
public:
|
||||
|
||||
Remove( float fDelay = 0.0f ) : TimedAnimation( 0.0f, fDelay ){}
|
||||
virtual void OnFinish(){ m_Control->DelayedDelete(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
221
btgui/Gwen/BaseRender.cpp
Normal file
221
btgui/Gwen/BaseRender.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Utility.h"
|
||||
#include "Gwen/Platform.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Renderer
|
||||
{
|
||||
|
||||
Base::Base()
|
||||
{
|
||||
m_RenderOffset = Gwen::Point( 0, 0 );
|
||||
m_fScale = 1.0f;
|
||||
}
|
||||
|
||||
Base::~Base()
|
||||
{
|
||||
if ( GetCTT() )
|
||||
GetCTT()->ShutDown();
|
||||
}
|
||||
|
||||
void Base::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text )
|
||||
{
|
||||
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode( text );
|
||||
RenderText( pFont, pos, str );
|
||||
}
|
||||
|
||||
Gwen::Point Base::MeasureText( Gwen::Font* pFont, const Gwen::String& text )
|
||||
{
|
||||
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode( text );
|
||||
return MeasureText( pFont, str );
|
||||
}
|
||||
|
||||
void Base::DrawLinedRect( Gwen::Rect rect )
|
||||
{
|
||||
DrawFilledRect( Gwen::Rect( rect.x, rect.y, rect.w, 1 ) );
|
||||
DrawFilledRect( Gwen::Rect( rect.x, rect.y + rect.h-1, rect.w, 1 ) );
|
||||
|
||||
DrawFilledRect( Gwen::Rect( rect.x, rect.y, 1, rect.h ) );
|
||||
DrawFilledRect( Gwen::Rect( rect.x + rect.w-1, rect.y, 1, rect.h ) );
|
||||
};
|
||||
|
||||
void Base::DrawPixel( int x, int y )
|
||||
{
|
||||
DrawFilledRect( Gwen::Rect( x, y, 1, 1 ) );
|
||||
}
|
||||
|
||||
void Base::DrawShavedCornerRect( Gwen::Rect rect, bool bSlight )
|
||||
{
|
||||
// Draw INSIDE the w/h.
|
||||
rect.w -= 1;
|
||||
rect.h -= 1;
|
||||
|
||||
if ( bSlight )
|
||||
{
|
||||
DrawFilledRect( Gwen::Rect( rect.x+1, rect.y, rect.w-1, 1 ) );
|
||||
DrawFilledRect( Gwen::Rect( rect.x+1, rect.y + rect.h, rect.w-1, 1 ) );
|
||||
|
||||
DrawFilledRect( Gwen::Rect( rect.x, rect.y+1, 1, rect.h-1 ) );
|
||||
DrawFilledRect( Gwen::Rect( rect.x + rect.w, rect.y+1, 1, rect.h-1 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
DrawPixel( rect.x+1, rect.y+1 );
|
||||
DrawPixel( rect.x+rect.w-1, rect.y+1 );
|
||||
|
||||
DrawPixel( rect.x+1, rect.y+rect.h-1 );
|
||||
DrawPixel( rect.x+rect.w-1, rect.y+rect.h-1 );
|
||||
|
||||
DrawFilledRect( Gwen::Rect( rect.x+2, rect.y, rect.w-3, 1 ) );
|
||||
DrawFilledRect( Gwen::Rect( rect.x+2, rect.y + rect.h, rect.w-3, 1 ) );
|
||||
|
||||
DrawFilledRect( Gwen::Rect( rect.x, rect.y+2, 1, rect.h-3 ) );
|
||||
DrawFilledRect( Gwen::Rect( rect.x + rect.w, rect.y+2, 1, rect.h-3 ) );
|
||||
}
|
||||
|
||||
void Base::Translate( int& x, int& y )
|
||||
{
|
||||
x += m_RenderOffset.x;
|
||||
y += m_RenderOffset.y;
|
||||
|
||||
x = ceil( ((float) x ) * m_fScale );
|
||||
y = ceil( ((float) y ) * m_fScale );
|
||||
}
|
||||
|
||||
void Base::Translate( Gwen::Rect& rect )
|
||||
{
|
||||
Translate( rect.x, rect.y );
|
||||
|
||||
rect.w = ceil(((float) rect.w ) * m_fScale);
|
||||
rect.h = ceil(((float) rect.h ) * m_fScale);
|
||||
}
|
||||
|
||||
void Gwen::Renderer::Base::SetClipRegion( Gwen::Rect rect )
|
||||
{
|
||||
m_rectClipRegion = rect;
|
||||
}
|
||||
|
||||
void Base::AddClipRegion( Gwen::Rect rect )
|
||||
{
|
||||
rect.x = m_RenderOffset.x;
|
||||
rect.y = m_RenderOffset.y;
|
||||
|
||||
Gwen::Rect out = rect;
|
||||
if ( rect.x < m_rectClipRegion.x )
|
||||
{
|
||||
out.w -= ( m_rectClipRegion.x - out.x );
|
||||
out.x = m_rectClipRegion.x;
|
||||
}
|
||||
|
||||
if ( rect.y < m_rectClipRegion.y )
|
||||
{
|
||||
out.h -= ( m_rectClipRegion.y - out.y );
|
||||
out.y = m_rectClipRegion.y;
|
||||
}
|
||||
|
||||
if ( rect.x + rect.w > m_rectClipRegion.x + m_rectClipRegion.w )
|
||||
{
|
||||
out.w = (m_rectClipRegion.x + m_rectClipRegion.w) - out.x;
|
||||
}
|
||||
|
||||
if ( rect.y + rect.h > m_rectClipRegion.y + m_rectClipRegion.h )
|
||||
{
|
||||
out.h = (m_rectClipRegion.y + m_rectClipRegion.h) - out.y;
|
||||
}
|
||||
|
||||
m_rectClipRegion = out;
|
||||
}
|
||||
|
||||
const Gwen::Rect& Base::ClipRegion() const
|
||||
{
|
||||
return m_rectClipRegion;
|
||||
}
|
||||
|
||||
bool Base::ClipRegionVisible()
|
||||
{
|
||||
if ( m_rectClipRegion.w <= 0 || m_rectClipRegion.h <= 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Base::DrawMissingImage( Gwen::Rect pTargetRect )
|
||||
{
|
||||
SetDrawColor( Colors::Red );
|
||||
DrawFilledRect( pTargetRect );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If they haven't defined these font functions in their renderer code
|
||||
we just draw some rects where the letters would be to give them an idea.
|
||||
*/
|
||||
|
||||
void Base::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text )
|
||||
{
|
||||
float fSize = pFont->size * Scale();
|
||||
|
||||
for ( float i=0; i<text.length(); i++ )
|
||||
{
|
||||
wchar_t chr = text[i];
|
||||
|
||||
if ( chr == ' ' ) continue;
|
||||
|
||||
Gwen::Rect r( pos.x + i * fSize * 0.4, pos.y, fSize * 0.4 -1, fSize );
|
||||
|
||||
/*
|
||||
This isn't important, it's just me messing around changing the
|
||||
shape of the rect based on the letter.. just for fun.
|
||||
*/
|
||||
if ( chr == 'l' || chr == 'i' || chr == '!' || chr == 't' )
|
||||
{
|
||||
r.w = 1;
|
||||
}
|
||||
else if ( chr >= 'a' && chr <= 'z' )
|
||||
{
|
||||
r.y += fSize * 0.5f;
|
||||
r.h -= fSize * 0.4f;
|
||||
}
|
||||
else if ( chr == '.' || chr == ',' )
|
||||
{
|
||||
r.x += 2;
|
||||
r.y += r.h - 2;
|
||||
r.w = 2;
|
||||
r.h = 2;
|
||||
}
|
||||
else if ( chr == '\'' || chr == '`' || chr == '"' )
|
||||
{
|
||||
r.x += 3;
|
||||
r.w = 2;
|
||||
r.h = 2;
|
||||
}
|
||||
|
||||
|
||||
if ( chr == 'o' || chr == 'O' || chr == '0' )
|
||||
DrawLinedRect( r );
|
||||
else
|
||||
DrawFilledRect( r );
|
||||
}
|
||||
}
|
||||
|
||||
Gwen::Point Base::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text )
|
||||
{
|
||||
Gwen::Point p;
|
||||
p.x = pFont->size * Scale() * (float)text.length() * 0.4;
|
||||
p.y = pFont->size * Scale();
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
119
btgui/Gwen/BaseRender.h
Normal file
119
btgui/Gwen/BaseRender.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_BASERENDER_H
|
||||
#define GWEN_BASERENDER_H
|
||||
|
||||
#include "Gwen/Structures.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
struct Font;
|
||||
struct Texture;
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
class Base;
|
||||
|
||||
class ICacheToTexture
|
||||
{
|
||||
|
||||
public:
|
||||
virtual void Initialize() = 0;
|
||||
virtual void ShutDown() = 0;
|
||||
virtual void SetupCacheTexture( Gwen::Controls::Base* control ) = 0;
|
||||
virtual void FinishCacheTexture( Gwen::Controls::Base* control ) = 0;
|
||||
virtual void DrawCachedControlTexture( Gwen::Controls::Base* control ) = 0;
|
||||
virtual void CreateControlCacheTexture( Gwen::Controls::Base* control ) = 0;
|
||||
virtual void UpdateControlCacheTexture( Gwen::Controls::Base* control ) = 0;
|
||||
virtual void SetRenderer( Gwen::Renderer::Base* renderer ) = 0;
|
||||
|
||||
};
|
||||
|
||||
class GWEN_EXPORT Base
|
||||
{
|
||||
public:
|
||||
|
||||
Base();
|
||||
virtual ~Base();
|
||||
|
||||
virtual void Begin(){};
|
||||
virtual void End(){};
|
||||
|
||||
virtual void SetDrawColor( Color color ){};
|
||||
|
||||
virtual void DrawLine( int x, int y, int a, int b ){};
|
||||
virtual void DrawFilledRect( Gwen::Rect rect ){};;
|
||||
|
||||
virtual void StartClip(){};
|
||||
virtual void EndClip(){};
|
||||
|
||||
virtual void LoadTexture( Gwen::Texture* pTexture ){};
|
||||
virtual void FreeTexture( Gwen::Texture* pTexture ){};
|
||||
virtual void DrawTexturedRect( Gwen::Texture* pTexture, Gwen::Rect pTargetRect, float u1=0.0f, float v1=0.0f, float u2=1.0f, float v2=1.0f ){};
|
||||
virtual void DrawMissingImage( Gwen::Rect pTargetRect );
|
||||
|
||||
virtual ICacheToTexture* GetCTT() { return NULL; }
|
||||
|
||||
virtual void LoadFont( Gwen::Font* pFont ){};
|
||||
virtual void FreeFont( Gwen::Font* pFont ){};
|
||||
virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text );
|
||||
virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text );
|
||||
|
||||
//
|
||||
// No need to implement these functions in your derived class, but if
|
||||
// you can do them faster than the default implementation it's a good idea to.
|
||||
//
|
||||
virtual void DrawLinedRect( Gwen::Rect rect );
|
||||
virtual void DrawPixel( int x, int y );
|
||||
virtual void DrawShavedCornerRect( Gwen::Rect rect, bool bSlight = false );
|
||||
virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::String& text );
|
||||
virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text );
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
// Translate a panel's local drawing coordinate
|
||||
// into view space, taking Offset's into account.
|
||||
//
|
||||
void Translate( int& x, int& y );
|
||||
void Translate( Gwen::Rect& rect );
|
||||
|
||||
//
|
||||
// Set the rendering offset. You shouldn't have to
|
||||
// touch these, ever.
|
||||
//
|
||||
void SetRenderOffset( const Gwen::Point& offset ){ m_RenderOffset = offset; }
|
||||
void AddRenderOffset( const Gwen::Rect& offset ){ m_RenderOffset.x += offset.x; m_RenderOffset.y += offset.y; }
|
||||
const Gwen::Point& GetRenderOffset() const { return m_RenderOffset; }
|
||||
|
||||
private:
|
||||
|
||||
Gwen::Point m_RenderOffset;
|
||||
|
||||
public:
|
||||
|
||||
void SetClipRegion( Gwen::Rect rect );
|
||||
void AddClipRegion( Gwen::Rect rect );
|
||||
bool ClipRegionVisible();
|
||||
const Gwen::Rect& ClipRegion() const;
|
||||
|
||||
private:
|
||||
|
||||
Gwen::Rect m_rectClipRegion;
|
||||
ICacheToTexture* m_RTT;
|
||||
|
||||
public:
|
||||
|
||||
void SetScale( float fScale ){ m_fScale = fScale; }
|
||||
float Scale() const { return m_fScale; }
|
||||
|
||||
float m_fScale;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
16
btgui/Gwen/Config.h
Normal file
16
btgui/Gwen/Config.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONFIG_H
|
||||
#define GWEN_CONFIG_H
|
||||
|
||||
//
|
||||
// Disables animation functions.
|
||||
//
|
||||
//#define GWEN_NO_ANIMATION
|
||||
|
||||
#endif
|
10
btgui/Gwen/Controls.h
Normal file
10
btgui/Gwen/Controls.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_H
|
||||
#define GWEN_CONTROLS_H
|
||||
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Controls/TextBox.h"
|
||||
|
||||
#include "Gwen/Anim.h"
|
||||
|
||||
#endif
|
1082
btgui/Gwen/Controls/Base.cpp
Normal file
1082
btgui/Gwen/Controls/Base.cpp
Normal file
File diff suppressed because it is too large
Load Diff
507
btgui/Gwen/Controls/Base.h
Normal file
507
btgui/Gwen/Controls/Base.h
Normal file
@ -0,0 +1,507 @@
|
||||
/*
|
||||
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
|
169
btgui/Gwen/Controls/Button.cpp
Normal file
169
btgui/Gwen/Controls/Button.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Controls/ImagePanel.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( Button )
|
||||
{
|
||||
m_Image = NULL;
|
||||
m_bDepressed = false;
|
||||
m_bCenterImage = false;
|
||||
|
||||
SetSize( 100, 20 );
|
||||
SetMouseInputEnabled( true );
|
||||
SetIsToggle( false );
|
||||
SetAlignment( Gwen::Pos::Center );
|
||||
SetTextPadding( Padding( 3, 0, 3, 0 ) );
|
||||
m_bToggleStatus = false;
|
||||
SetKeyboardInputEnabled( false );
|
||||
SetTabable( false );
|
||||
}
|
||||
|
||||
void Button::Render( Skin::Base* skin )
|
||||
{
|
||||
if ( ShouldDrawBackground() )
|
||||
{
|
||||
bool bDrawDepressed = IsDepressed() && IsHovered();
|
||||
if ( IsToggle() ) bDrawDepressed = bDrawDepressed || GetToggleState();
|
||||
|
||||
bool bDrawHovered = IsHovered() && ShouldDrawHover();
|
||||
|
||||
skin->DrawButton( this, bDrawDepressed, bDrawHovered );
|
||||
}
|
||||
}
|
||||
|
||||
void Button::OnMouseClickLeft( int /*x*/, int /*y*/, bool bDown )
|
||||
{
|
||||
if ( bDown )
|
||||
{
|
||||
m_bDepressed = true;
|
||||
Gwen::MouseFocus = this;
|
||||
onDown.Call( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( IsHovered() && m_bDepressed )
|
||||
{
|
||||
OnPress();
|
||||
}
|
||||
|
||||
m_bDepressed = false;
|
||||
Gwen::MouseFocus = NULL;
|
||||
onUp.Call( this );
|
||||
}
|
||||
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void Button::OnPress()
|
||||
{
|
||||
if ( IsToggle() )
|
||||
{
|
||||
SetToggleState( !GetToggleState() );
|
||||
}
|
||||
|
||||
onPress.Call( this );
|
||||
}
|
||||
|
||||
|
||||
void Button::SetImage( const TextObject& strName, bool bCenter )
|
||||
{
|
||||
if ( strName.GetUnicode() == L"" )
|
||||
{
|
||||
if ( m_Image )
|
||||
{
|
||||
delete m_Image;
|
||||
m_Image= NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !m_Image )
|
||||
{
|
||||
m_Image = new ImagePanel( this );
|
||||
}
|
||||
|
||||
m_Image->SetImage( strName );
|
||||
m_Image->SizeToContents();
|
||||
m_Image->SetPos( m_Padding.left, 2 );
|
||||
m_bCenterImage = bCenter;
|
||||
|
||||
int IdealTextPadding = m_Image->Right() + m_Padding.left + 4;
|
||||
if ( m_rTextPadding.left < IdealTextPadding )
|
||||
{
|
||||
m_rTextPadding.left = IdealTextPadding;
|
||||
}
|
||||
}
|
||||
|
||||
void Button::SetToggleState( bool b )
|
||||
{
|
||||
if ( m_bToggleStatus == b ) return;
|
||||
|
||||
m_bToggleStatus = b;
|
||||
|
||||
onToggle.Call( this );
|
||||
|
||||
if ( m_bToggleStatus )
|
||||
{
|
||||
onToggleOn.Call( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
onToggleOff.Call( this );
|
||||
}
|
||||
}
|
||||
|
||||
void Button::SizeToContents()
|
||||
{
|
||||
BaseClass::SizeToContents();
|
||||
|
||||
if ( m_Image )
|
||||
{
|
||||
int height = m_Image->Height() + 4;
|
||||
if ( Height() < height )
|
||||
{
|
||||
SetHeight( height );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Button::OnKeySpace( bool bDown )
|
||||
{
|
||||
OnMouseClickLeft( 0, 0, bDown );
|
||||
return true;
|
||||
}
|
||||
|
||||
void Button::AcceleratePressed()
|
||||
{
|
||||
OnPress();
|
||||
}
|
||||
|
||||
void Button::Layout( Skin::Base* pSkin )
|
||||
{
|
||||
BaseClass::Layout( pSkin );
|
||||
if ( m_Image )
|
||||
{
|
||||
Gwen::Align::CenterVertically( m_Image );
|
||||
|
||||
if ( m_bCenterImage )
|
||||
Gwen::Align::CenterHorizontally( m_Image );
|
||||
}
|
||||
}
|
||||
|
||||
void Button::OnMouseDoubleClickLeft( int x, int y )
|
||||
{
|
||||
OnMouseClickLeft( x, y, true );
|
||||
onDoubleClick.Call( this );
|
||||
};
|
79
btgui/Gwen/Controls/Button.h
Normal file
79
btgui/Gwen/Controls/Button.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_BUTTON_H
|
||||
#define GWEN_CONTROLS_BUTTON_H
|
||||
|
||||
#include "Gwen/TextObject.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class ImagePanel;
|
||||
|
||||
class GWEN_EXPORT Button : public Label
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( Button, Label );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void OnMouseClickLeft( int x, int y, bool bDown );
|
||||
virtual void OnMouseDoubleClickLeft( int x, int y );
|
||||
virtual bool OnKeySpace( bool bDown );
|
||||
|
||||
virtual void OnPress();
|
||||
|
||||
virtual void AcceleratePressed();
|
||||
|
||||
virtual bool IsDepressed() const { return m_bDepressed; }
|
||||
|
||||
//
|
||||
// Buttons can be toggle type, which means that it is
|
||||
// toggled on and off. Its toggle status is in IsDepressed.
|
||||
//
|
||||
virtual void SetIsToggle( bool b ){ m_bToggle = b; }
|
||||
virtual bool IsToggle() const { return m_bToggle; }
|
||||
virtual bool GetToggleState() const { return m_bToggleStatus; }
|
||||
virtual void SetToggleState( bool b );
|
||||
virtual void Toggle(){ SetToggleState( !GetToggleState() ); }
|
||||
|
||||
|
||||
virtual void SetImage( const TextObject& strName, bool bCenter = false );
|
||||
|
||||
// You can use this to trigger OnPress directly from other controls using GWEN_CALL_EX
|
||||
virtual void ReceiveEventPress( Base* /*pControl*/ ){ OnPress(); }
|
||||
|
||||
virtual void SizeToContents();
|
||||
virtual void Layout( Skin::Base* pSkin );
|
||||
|
||||
public:
|
||||
|
||||
Gwen::Event::Caller onPress;
|
||||
Gwen::Event::Caller onDown;
|
||||
Gwen::Event::Caller onUp;
|
||||
Gwen::Event::Caller onDoubleClick;
|
||||
Gwen::Event::Caller onToggle;
|
||||
Gwen::Event::Caller onToggleOn;
|
||||
Gwen::Event::Caller onToggleOff;
|
||||
|
||||
protected:
|
||||
|
||||
ImagePanel* m_Image;
|
||||
|
||||
bool m_bDepressed;
|
||||
bool m_bToggle;
|
||||
bool m_bToggleStatus;
|
||||
|
||||
bool m_bCenterImage;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
233
btgui/Gwen/Controls/Canvas.cpp
Normal file
233
btgui/Gwen/Controls/Canvas.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Canvas.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/Menu.h"
|
||||
#include "Gwen/DragAndDrop.h"
|
||||
#include "Gwen/ToolTip.h"
|
||||
|
||||
#ifndef GWEN_NO_ANIMATION
|
||||
#include "Gwen/Anim.h"
|
||||
#endif
|
||||
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
Canvas::Canvas( Gwen::Skin::Base* pSkin ) : BaseClass( NULL ), m_bAnyDelete( false )
|
||||
{
|
||||
SetBounds( 0, 0, 10000, 10000 );
|
||||
SetSkin( pSkin );
|
||||
SetScale( 1.0f );
|
||||
SetBackgroundColor( Color( 255, 255, 255, 255 ) );
|
||||
SetDrawBackground( false );
|
||||
}
|
||||
|
||||
void Canvas::RenderCanvas()
|
||||
{
|
||||
DoThink();
|
||||
|
||||
Gwen::Renderer::Base* render = m_Skin->GetRender();
|
||||
render->Begin();
|
||||
|
||||
|
||||
RecurseLayout( m_Skin );
|
||||
|
||||
render->SetClipRegion( GetBounds() );
|
||||
render->SetRenderOffset( Gwen::Point( 0, 0 ) );
|
||||
render->SetScale( Scale() );
|
||||
|
||||
if ( m_bDrawBackground )
|
||||
{
|
||||
render->SetDrawColor( m_BackgroundColor );
|
||||
render->DrawFilledRect( GetRenderBounds() );
|
||||
}
|
||||
|
||||
DoRender( m_Skin );
|
||||
|
||||
DragAndDrop::RenderOverlay( this, m_Skin );
|
||||
|
||||
ToolTip::RenderToolTip( m_Skin );
|
||||
|
||||
render->EndClip();
|
||||
|
||||
render->End();
|
||||
ProcessDelayedDeletes();
|
||||
|
||||
}
|
||||
|
||||
void Canvas::Render( Gwen::Skin::Base* /*pRender*/ )
|
||||
{
|
||||
m_bNeedsRedraw = false;
|
||||
}
|
||||
|
||||
void Canvas::OnBoundsChanged( Gwen::Rect oldBounds )
|
||||
{
|
||||
BaseClass::OnBoundsChanged( oldBounds );
|
||||
InvalidateChildren( true );
|
||||
}
|
||||
|
||||
|
||||
void Canvas::DoThink()
|
||||
{
|
||||
if ( Hidden() ) return;
|
||||
|
||||
#ifndef GWEN_NO_ANIMATION
|
||||
Gwen::Anim::Think();
|
||||
#endif
|
||||
|
||||
// Reset tabbing
|
||||
{
|
||||
NextTab = NULL;
|
||||
FirstTab = NULL;
|
||||
}
|
||||
|
||||
ProcessDelayedDeletes();
|
||||
// Check has focus etc..
|
||||
RecurseLayout( m_Skin );
|
||||
|
||||
// If we didn't have a next tab, cycle to the start.
|
||||
if ( NextTab == NULL )
|
||||
NextTab = FirstTab;
|
||||
|
||||
Gwen::Input::OnCanvasThink( this );
|
||||
|
||||
}
|
||||
|
||||
void Canvas::SetScale( float f )
|
||||
{
|
||||
if ( m_fScale == f ) return;
|
||||
|
||||
m_fScale = f;
|
||||
|
||||
if ( m_Skin && m_Skin->GetRender() )
|
||||
m_Skin->GetRender()->SetScale( m_fScale );
|
||||
|
||||
OnScaleChanged();
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void Canvas::AddDelayedDelete( Gwen::Controls::Base* pControl )
|
||||
{
|
||||
if ( !m_bAnyDelete || m_DeleteSet.find( pControl ) == m_DeleteSet.end() )
|
||||
{
|
||||
m_bAnyDelete = true;
|
||||
m_DeleteSet.insert( pControl );
|
||||
m_DeleteList.push_back( pControl );
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::PreDelete( Controls::Base * pControl )
|
||||
{
|
||||
if ( m_bAnyDelete )
|
||||
{
|
||||
std::set< Controls::Base * >::iterator itFind;
|
||||
if ( ( itFind = m_DeleteSet.find( pControl ) ) != m_DeleteSet.end() )
|
||||
{
|
||||
m_DeleteList.remove( pControl );
|
||||
m_DeleteSet.erase( pControl );
|
||||
m_bAnyDelete = !m_DeleteSet.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::ProcessDelayedDeletes()
|
||||
{
|
||||
while( m_bAnyDelete )
|
||||
{
|
||||
m_bAnyDelete = false;
|
||||
|
||||
Controls::Base::List deleteList = m_DeleteList;
|
||||
|
||||
m_DeleteList.clear();
|
||||
m_DeleteSet.clear();
|
||||
|
||||
for ( Gwen::Controls::Base::List::iterator it = deleteList.begin(); it != deleteList.end(); ++it )
|
||||
{
|
||||
Gwen::Controls::Base* pControl = *it;
|
||||
delete pControl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::Release()
|
||||
{
|
||||
Base::List::iterator iter = Children.begin();
|
||||
while ( iter != Children.end() )
|
||||
{
|
||||
Base* pChild = *iter;
|
||||
iter = Children.erase( iter );
|
||||
delete pChild;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool Canvas::InputMouseMoved( int x, int y, int deltaX, int deltaY )
|
||||
{
|
||||
if ( Hidden() ) return false;
|
||||
|
||||
// Todo: Handle scaling here..
|
||||
//float fScale = 1.0f / Scale();
|
||||
|
||||
Gwen::Input::OnMouseMoved( this, x, y, deltaX, deltaY );
|
||||
|
||||
if ( !Gwen::HoveredControl ) return false;
|
||||
if ( Gwen::HoveredControl == this ) return false;
|
||||
if ( Gwen::HoveredControl->GetCanvas() != this ) return false;
|
||||
|
||||
Gwen::HoveredControl->OnMouseMoved( x, y, deltaX, deltaY );
|
||||
Gwen::HoveredControl->UpdateCursor();
|
||||
|
||||
DragAndDrop::OnMouseMoved( Gwen::HoveredControl, x, y );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Canvas::InputMouseButton( int iButton, bool bDown )
|
||||
{
|
||||
if ( Hidden() ) return false;
|
||||
|
||||
return Gwen::Input::OnMouseClicked( this, iButton, bDown );
|
||||
}
|
||||
|
||||
bool Canvas::InputKey( int iKey, bool bDown )
|
||||
{
|
||||
if ( Hidden() ) return false;
|
||||
if ( iKey <= Gwen::Key::Invalid ) return false;
|
||||
if ( iKey >= Gwen::Key::Count ) return false;
|
||||
|
||||
return Gwen::Input::OnKeyEvent( this, iKey, bDown );
|
||||
}
|
||||
|
||||
bool Canvas::InputCharacter( Gwen::UnicodeChar chr )
|
||||
{
|
||||
if ( Hidden() ) return false;
|
||||
if ( !iswprint( chr ) ) return false;
|
||||
|
||||
//Handle Accelerators
|
||||
if ( Gwen::Input::HandleAccelerator( this, chr ) )
|
||||
return true;
|
||||
|
||||
//Handle characters
|
||||
if ( !Gwen::KeyboardFocus ) return false;
|
||||
if ( Gwen::KeyboardFocus->GetCanvas() != this ) return false;
|
||||
if ( !Gwen::KeyboardFocus->Visible() ) return false;
|
||||
if ( Gwen::Input::IsControlDown() ) return false;
|
||||
|
||||
return KeyboardFocus->OnChar( chr );
|
||||
}
|
||||
|
||||
bool Canvas::InputMouseWheel( int val )
|
||||
{
|
||||
if ( Hidden() ) return false;
|
||||
if ( !Gwen::HoveredControl ) return false;
|
||||
if ( Gwen::HoveredControl == this ) return false;
|
||||
if ( Gwen::HoveredControl->GetCanvas() != this ) return false;
|
||||
|
||||
return Gwen::HoveredControl->OnMouseWheeled( val );
|
||||
}
|
107
btgui/Gwen/Controls/Canvas.h
Normal file
107
btgui/Gwen/Controls/Canvas.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_CANVAS_H
|
||||
#define GWEN_CONTROLS_CANVAS_H
|
||||
|
||||
#include <set>
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/InputHandler.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT Canvas : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Controls::Base BaseClass;
|
||||
|
||||
Canvas( Skin::Base* pSkin );
|
||||
|
||||
//
|
||||
// For additional initialization
|
||||
// (which is sometimes not appropriate in the constructor)
|
||||
//
|
||||
virtual void Initialize(){};
|
||||
|
||||
//
|
||||
// You should call this to render your canvas.
|
||||
//
|
||||
virtual void RenderCanvas();
|
||||
|
||||
//
|
||||
// Call this whenever you want to process input. This
|
||||
// is usually once a frame..
|
||||
//
|
||||
virtual void DoThink();
|
||||
|
||||
//
|
||||
// In most situations you will be rendering the canvas
|
||||
// every frame. But in some situations you will only want
|
||||
// to render when there have been changes. You can do this
|
||||
// by checking NeedsRedraw().
|
||||
//
|
||||
virtual bool NeedsRedraw(){ return m_bNeedsRedraw; }
|
||||
virtual void Redraw(){ m_bNeedsRedraw = true; }
|
||||
|
||||
// Internal. Do not call directly.
|
||||
virtual void Render( Skin::Base* pRender );
|
||||
|
||||
// Childpanels call parent->GetCanvas() until they get to
|
||||
// this top level function.
|
||||
virtual Controls::Canvas* GetCanvas(){ return this; }
|
||||
|
||||
virtual void SetScale( float f );
|
||||
virtual float Scale() const { return m_fScale; }
|
||||
|
||||
virtual void OnBoundsChanged( Gwen::Rect oldBounds );
|
||||
|
||||
//
|
||||
// Call this to delete the canvas, and its children
|
||||
// in the right order.
|
||||
//
|
||||
virtual void Release();
|
||||
|
||||
// Delayed deletes
|
||||
virtual void AddDelayedDelete( Controls::Base* pControl );
|
||||
virtual void ProcessDelayedDeletes();
|
||||
|
||||
Controls::Base* FirstTab;
|
||||
Controls::Base* NextTab;
|
||||
|
||||
// Input
|
||||
virtual bool InputMouseMoved( int x, int y, int deltaX, int deltaY );
|
||||
virtual bool InputMouseButton( int iButton, bool bDown );
|
||||
virtual bool InputKey( int iKey, bool bDown );
|
||||
virtual bool InputCharacter( Gwen::UnicodeChar chr );
|
||||
virtual bool InputMouseWheel( int val );
|
||||
|
||||
// Background
|
||||
virtual void SetBackgroundColor( const Gwen::Color& color ){ m_BackgroundColor = color; }
|
||||
virtual void SetDrawBackground( bool bShouldDraw ){ m_bDrawBackground = bShouldDraw; }
|
||||
|
||||
private:
|
||||
|
||||
bool m_bNeedsRedraw;
|
||||
bool m_bAnyDelete;
|
||||
float m_fScale;
|
||||
|
||||
Controls::Base::List m_DeleteList;
|
||||
std::set< Controls::Base* > m_DeleteSet;
|
||||
friend class Controls::Base;
|
||||
void PreDelete( Controls::Base * );
|
||||
|
||||
bool m_bDrawBackground;
|
||||
Gwen::Color m_BackgroundColor;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
57
btgui/Gwen/Controls/CheckBox.cpp
Normal file
57
btgui/Gwen/Controls/CheckBox.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/CheckBox.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( CheckBox )
|
||||
{
|
||||
SetSize( 13, 13 );
|
||||
|
||||
m_bChecked = true;
|
||||
Toggle();
|
||||
}
|
||||
|
||||
|
||||
void CheckBox::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawCheckBox( this, m_bChecked, IsDepressed() );
|
||||
}
|
||||
|
||||
void CheckBox::OnPress()
|
||||
{
|
||||
if ( IsChecked() && !AllowUncheck() )
|
||||
return;
|
||||
|
||||
Toggle();
|
||||
}
|
||||
|
||||
void CheckBox::OnCheckStatusChanged()
|
||||
{
|
||||
if ( IsChecked() )
|
||||
{
|
||||
onChecked.Call( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
onUnChecked.Call( this );
|
||||
}
|
||||
|
||||
onCheckChanged.Call( this );
|
||||
}
|
||||
|
||||
void CheckBox::SetChecked( bool bChecked )
|
||||
{
|
||||
if ( m_bChecked == bChecked ) return;
|
||||
|
||||
m_bChecked = bChecked;
|
||||
OnCheckStatusChanged();
|
||||
}
|
82
btgui/Gwen/Controls/CheckBox.h
Normal file
82
btgui/Gwen/Controls/CheckBox.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_CHECKBOX_H
|
||||
#define GWEN_CONTROLS_CHECKBOX_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/Symbol.h"
|
||||
#include "Gwen/Controls/LabelClickable.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
|
||||
class GWEN_EXPORT CheckBox : public Button
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( CheckBox, Button );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void OnPress();
|
||||
|
||||
virtual void SetChecked( bool Checked );
|
||||
virtual void Toggle() { SetChecked( !IsChecked() ); }
|
||||
virtual bool IsChecked() { return m_bChecked; }
|
||||
|
||||
Gwen::Event::Caller onChecked;
|
||||
Gwen::Event::Caller onUnChecked;
|
||||
Gwen::Event::Caller onCheckChanged;
|
||||
|
||||
private:
|
||||
|
||||
// For derived controls
|
||||
virtual bool AllowUncheck(){ return true; }
|
||||
|
||||
void OnCheckStatusChanged();
|
||||
|
||||
bool m_bChecked;
|
||||
};
|
||||
|
||||
class GWEN_EXPORT CheckBoxWithLabel : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( CheckBoxWithLabel, Base )
|
||||
{
|
||||
SetSize( 200, 19 );
|
||||
|
||||
m_Checkbox = new CheckBox( this );
|
||||
m_Checkbox->Dock( Pos::Left );
|
||||
m_Checkbox->SetMargin( Margin( 0, 3, 3, 3 ) );
|
||||
m_Checkbox->SetTabable( false );
|
||||
|
||||
m_Label = new LabelClickable( this );
|
||||
m_Label->Dock( Pos::Fill );
|
||||
m_Label->onPress.Add( m_Checkbox, &CheckBox::ReceiveEventPress );
|
||||
m_Label->SetTabable( false );
|
||||
|
||||
SetTabable( false );
|
||||
}
|
||||
|
||||
virtual CheckBox* Checkbox() { return m_Checkbox; }
|
||||
virtual LabelClickable* Label() { return m_Label; }
|
||||
virtual bool OnKeySpace( bool bDown ) { if ( bDown ) m_Checkbox->SetChecked( !m_Checkbox->IsChecked() ); return true; }
|
||||
|
||||
private:
|
||||
|
||||
CheckBox* m_Checkbox;
|
||||
LabelClickable* m_Label;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
326
btgui/Gwen/Controls/ColorControls.cpp
Normal file
326
btgui/Gwen/Controls/ColorControls.cpp
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Utility.h"
|
||||
#include "Gwen/Controls/ColorControls.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
//Find a place to put these...
|
||||
Color HSVToColor( float h, float s, float v )
|
||||
{
|
||||
if (h < 0.0f) h += 360.0f;
|
||||
if (h > 360.0f) h -= 360.0f;
|
||||
|
||||
s *= 255.0f;
|
||||
v *= 255.0f;
|
||||
|
||||
float r, g, b;
|
||||
|
||||
if (!h && !s)
|
||||
{
|
||||
r = g = b = v;
|
||||
}
|
||||
double min,max,delta,hue;
|
||||
|
||||
max = v;
|
||||
delta = (max * s)/255.0;
|
||||
min = max - delta;
|
||||
|
||||
hue = h;
|
||||
if (h > 300 || h <= 60)
|
||||
{
|
||||
r = (int)max;
|
||||
if (h > 300)
|
||||
{
|
||||
g = (int)min;
|
||||
hue = (hue - 360.0)/60.0;
|
||||
b = (int)((hue * delta - min) * -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
b = (int)min;
|
||||
hue = hue / 60.0;
|
||||
g = (int)(hue * delta + min);
|
||||
}
|
||||
}
|
||||
else if (h > 60 && h < 180)
|
||||
{
|
||||
g = (int)max;
|
||||
if (h < 120)
|
||||
{
|
||||
b = (int)min;
|
||||
hue = (hue/60.0 - 2.0 ) * delta;
|
||||
r = (int)(min - hue);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (int)min;
|
||||
hue = (hue/60 - 2.0) * delta;
|
||||
b = (int)(min + hue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = (int)max;
|
||||
if (h < 240)
|
||||
{
|
||||
r = (int)min;
|
||||
hue = (hue/60.0 - 4.0 ) * delta;
|
||||
g = (int)(min - hue);
|
||||
}
|
||||
else
|
||||
{
|
||||
g = (int)min;
|
||||
hue = (hue/60 - 4.0) * delta;
|
||||
r = (int)(min + hue);
|
||||
}
|
||||
}
|
||||
|
||||
return Color( r, g, b, 255);
|
||||
}
|
||||
|
||||
HSV RGBtoHSV( int r, int g, int b )
|
||||
{
|
||||
double min,max,delta,temp;
|
||||
min = GwenUtil_Min(r,GwenUtil_Min(g,b));
|
||||
max = GwenUtil_Max(r,GwenUtil_Max(g,b));
|
||||
delta = max - min;
|
||||
|
||||
HSV hsv;
|
||||
hsv.v = (int)max;
|
||||
if (!delta)
|
||||
{
|
||||
hsv.h = hsv.s = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = delta/max;
|
||||
hsv.s = (int)(temp*255);
|
||||
|
||||
if (r == (int)max)
|
||||
{
|
||||
temp = (double)(g-b)/delta;
|
||||
}
|
||||
else
|
||||
if (g == (int)max)
|
||||
{
|
||||
temp = 2.0 + ((double)(b-r)/delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = 4.0 + ((double)(r-g)/delta);
|
||||
}
|
||||
temp *= 60;
|
||||
if (temp < 0)
|
||||
{
|
||||
temp+=360;
|
||||
}
|
||||
if (temp == 360)
|
||||
{
|
||||
temp = 0;
|
||||
}
|
||||
hsv.h = (int)temp;
|
||||
}
|
||||
|
||||
|
||||
hsv.s /= 255.0f;
|
||||
hsv.v /= 255.0f;
|
||||
|
||||
return hsv;
|
||||
}
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ColorLerpBox )
|
||||
{
|
||||
SetColor( Gwen::Color(255, 128, 0, 255) );
|
||||
SetSize( 128, 128 );
|
||||
SetMouseInputEnabled( true );
|
||||
m_bDepressed = false;
|
||||
}
|
||||
|
||||
//Find a place to put this? color member?
|
||||
Gwen::Color LerpColor( Gwen::Color &toColor, Gwen::Color &fromColor, float amount )
|
||||
{
|
||||
Gwen::Color colorDelta = toColor - fromColor;
|
||||
|
||||
colorDelta.r *= amount;
|
||||
colorDelta.g *= amount;
|
||||
colorDelta.b *= amount;
|
||||
|
||||
Gwen::Color newColor = fromColor + colorDelta;
|
||||
return newColor;
|
||||
}
|
||||
|
||||
Gwen::Color ColorLerpBox::GetSelectedColor()
|
||||
{
|
||||
return GetColorAtPos( cursorPos.x, cursorPos.y );
|
||||
}
|
||||
|
||||
void ColorLerpBox::SetColor( Gwen::Color color, bool onlyHue )
|
||||
{
|
||||
HSV hsv = RGBtoHSV(color.r, color.g, color.b);
|
||||
m_Hue = hsv.h;
|
||||
if ( !onlyHue )
|
||||
{
|
||||
cursorPos.x = hsv.s * Width();
|
||||
cursorPos.y = (1 - hsv.v) * Height();
|
||||
}
|
||||
|
||||
onSelectionChanged.Call( this );
|
||||
}
|
||||
|
||||
void ColorLerpBox::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
|
||||
{
|
||||
if ( m_bDepressed )
|
||||
{
|
||||
cursorPos = CanvasPosToLocal( Gwen::Point( x, y ) );
|
||||
//Do we have clamp?
|
||||
if ( cursorPos.x < 0)
|
||||
cursorPos.x = 0;
|
||||
if (cursorPos.x > Width())
|
||||
cursorPos.x = Width();
|
||||
|
||||
if (cursorPos.y < 0)
|
||||
cursorPos.y = 0;
|
||||
if (cursorPos.y > Height())
|
||||
cursorPos.y = Height();
|
||||
|
||||
onSelectionChanged.Call( this );
|
||||
}
|
||||
}
|
||||
|
||||
void ColorLerpBox::OnMouseClickLeft( int x, int y, bool bDown )
|
||||
{
|
||||
m_bDepressed = bDown;
|
||||
if ( bDown )
|
||||
Gwen::MouseFocus = this;
|
||||
else
|
||||
Gwen::MouseFocus = NULL;
|
||||
|
||||
OnMouseMoved( x, y, 0, 0);
|
||||
}
|
||||
|
||||
Gwen::Color ColorLerpBox::GetColorAtPos( int x, int y )
|
||||
{
|
||||
float xPercent = ( (float)x / (float)Width() );
|
||||
float yPercent = 1 - ( (float)y / (float)Height() );
|
||||
|
||||
Gwen::Color result = HSVToColor( m_Hue, xPercent, yPercent );
|
||||
|
||||
result.a = 255;
|
||||
|
||||
return result;
|
||||
}
|
||||
void ColorLerpBox::Render( Gwen::Skin::Base* skin )
|
||||
{
|
||||
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
|
||||
BaseClass::Render( skin );
|
||||
for ( int x = 0; x<Width(); x++)
|
||||
{
|
||||
for ( int y = 0; y<Height(); y++)
|
||||
{
|
||||
skin->GetRender()->SetDrawColor( GetColorAtPos( x, y ) );
|
||||
skin->GetRender()->DrawPixel( x, y );
|
||||
}
|
||||
}
|
||||
|
||||
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ) );
|
||||
skin->GetRender()->DrawLinedRect( GetRenderBounds() );
|
||||
|
||||
Gwen::Color selected = GetSelectedColor();
|
||||
if ( (selected.r + selected.g + selected.b) / 3 < 170 )
|
||||
skin->GetRender()->SetDrawColor( Gwen::Color( 255, 255, 255, 255 ) );
|
||||
else
|
||||
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ) );
|
||||
|
||||
Gwen::Rect testRect = Gwen::Rect( cursorPos.x -3, cursorPos.y -3, 6, 6);
|
||||
|
||||
skin->GetRender()->DrawShavedCornerRect( testRect );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ColorSlider )
|
||||
{
|
||||
SetSize( 32, 128 );
|
||||
SetMouseInputEnabled( true );
|
||||
m_bDepressed = false;
|
||||
}
|
||||
|
||||
void ColorSlider::Render( Gwen::Skin::Base* skin )
|
||||
{
|
||||
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
|
||||
int y = 0;
|
||||
for ( y = 0; y < Height(); y++)
|
||||
{
|
||||
float yPercent = (float)y / (float)Height();
|
||||
skin->GetRender()->SetDrawColor( HSVToColor( yPercent * 360, 1, 1 ) );
|
||||
skin->GetRender()->DrawFilledRect( Gwen::Rect( 5, y, Width() - 10, 1 ) );
|
||||
}
|
||||
|
||||
int drawHeight = m_iSelectedDist - 3;
|
||||
|
||||
//Draw our selectors
|
||||
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ));
|
||||
skin->GetRender()->DrawFilledRect( Gwen::Rect( 0, drawHeight + 2, Width(), 1));
|
||||
skin->GetRender()->DrawFilledRect( Gwen::Rect( 0, drawHeight, 5, 5) );
|
||||
skin->GetRender()->DrawFilledRect( Gwen::Rect( Width() - 5, drawHeight, 5, 5) );
|
||||
skin->GetRender()->SetDrawColor( Gwen::Color( 255, 255, 255, 255 ) );
|
||||
skin->GetRender()->DrawFilledRect( Gwen::Rect( 1, drawHeight + 1, 3, 3 ) );
|
||||
skin->GetRender()->DrawFilledRect( Gwen::Rect( Width() - 4, drawHeight + 1, 3, 3 ) );
|
||||
}
|
||||
|
||||
void ColorSlider::OnMouseClickLeft( int x, int y, bool bDown )
|
||||
{
|
||||
m_bDepressed = bDown;
|
||||
if ( bDown)
|
||||
Gwen::MouseFocus = this;
|
||||
else
|
||||
Gwen::MouseFocus = NULL;
|
||||
|
||||
OnMouseMoved(x, y, 0, 0);
|
||||
}
|
||||
|
||||
Gwen::Color ColorSlider::GetColorAtHeight( int y )
|
||||
{
|
||||
float yPercent = (float)y / (float)Height();
|
||||
return HSVToColor( yPercent * 360, 1, 1);
|
||||
|
||||
}
|
||||
void ColorSlider::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
|
||||
{
|
||||
if ( m_bDepressed )
|
||||
{
|
||||
Gwen::Point cursorPos = CanvasPosToLocal( Gwen::Point( x, y ) );
|
||||
|
||||
if (cursorPos.y < 0)
|
||||
cursorPos.y = 0;
|
||||
if (cursorPos.y > Height())
|
||||
cursorPos.y = Height();
|
||||
|
||||
m_iSelectedDist = cursorPos.y;
|
||||
onSelectionChanged.Call( this );
|
||||
}
|
||||
}
|
||||
|
||||
void ColorSlider::SetColor( Gwen::Color color)
|
||||
{
|
||||
HSV hsv = RGBtoHSV( color.r, color.g, color.b );
|
||||
|
||||
m_iSelectedDist = hsv.h / 360 * Height();
|
||||
|
||||
onSelectionChanged.Call( this );
|
||||
}
|
||||
|
||||
Gwen::Color ColorSlider::GetSelectedColor()
|
||||
{
|
||||
return GetColorAtHeight( m_iSelectedDist );
|
||||
}
|
61
btgui/Gwen/Controls/ColorControls.h
Normal file
61
btgui/Gwen/Controls/ColorControls.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_COLORCONTROLS_H
|
||||
#define GWEN_CONTROLS_COLORCONTROLS_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
|
||||
class GWEN_EXPORT ColorLerpBox : public Controls::Base
|
||||
{
|
||||
public:
|
||||
GWEN_CONTROL( ColorLerpBox, Controls::Base );
|
||||
virtual void Render( Gwen::Skin::Base* skin );
|
||||
Gwen::Color GetColorAtPos(int x, int y );
|
||||
void SetColor( Gwen::Color color, bool onlyHue = true );
|
||||
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
|
||||
virtual void OnMouseClickLeft( int x, int y, bool bDown );
|
||||
Gwen::Color GetSelectedColor();
|
||||
|
||||
Event::Caller onSelectionChanged;
|
||||
protected:
|
||||
Gwen::Point cursorPos;
|
||||
bool m_bDepressed;
|
||||
int m_Hue;
|
||||
|
||||
};
|
||||
|
||||
class GWEN_EXPORT ColorSlider : public Controls::Base
|
||||
{
|
||||
public:
|
||||
GWEN_CONTROL( ColorSlider, Controls::Base );
|
||||
virtual void Render( Gwen::Skin::Base* skin );
|
||||
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
|
||||
virtual void OnMouseClickLeft( int x, int y, bool bDown );
|
||||
Gwen::Color GetSelectedColor();
|
||||
Gwen::Color GetColorAtHeight(int y );
|
||||
void SetColor( Gwen::Color color );
|
||||
|
||||
Event::Caller onSelectionChanged;
|
||||
|
||||
protected:
|
||||
int m_iSelectedDist;
|
||||
bool m_bDepressed;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
222
btgui/Gwen/Controls/ColorPicker.cpp
Normal file
222
btgui/Gwen/Controls/ColorPicker.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ColorPicker.h"
|
||||
#include "Gwen/Controls/HorizontalSlider.h"
|
||||
#include "Gwen/Controls/GroupBox.h"
|
||||
#include "Gwen/Controls/TextBox.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ColorPicker )
|
||||
{
|
||||
SetMouseInputEnabled( true );
|
||||
|
||||
SetSize( 256, 150 );
|
||||
CreateControls();
|
||||
SetColor( Gwen::Color( 50, 60, 70, 255 ) );
|
||||
}
|
||||
|
||||
void ColorPicker::CreateColorControl( Gwen::String name, int y )
|
||||
{
|
||||
int colorSize = 12;
|
||||
|
||||
GroupBox* colorGroup = new GroupBox( this );
|
||||
colorGroup->SetPos( 10, y );
|
||||
colorGroup->SetText( name );
|
||||
colorGroup->SetSize( 160, 35 );
|
||||
colorGroup->SetName( name + "groupbox" );
|
||||
|
||||
ColorDisplay* disp = new ColorDisplay( colorGroup );
|
||||
disp->SetName(name);
|
||||
disp->SetBounds( 0 , 10, colorSize, colorSize );
|
||||
|
||||
TextBoxNumeric* numeric = new TextBoxNumeric( colorGroup );
|
||||
numeric->SetName( name + "Box" );
|
||||
numeric->SetPos( 105, 7 );
|
||||
numeric->SetSize( 26, 16 );
|
||||
numeric->SetSelectAllOnFocus( true );
|
||||
numeric->onTextChanged.Add( this, &ColorPicker::NumericTyped );
|
||||
|
||||
HorizontalSlider* slider = new HorizontalSlider( colorGroup );
|
||||
slider->SetPos( colorSize + 5 , 10 );
|
||||
slider->SetRange( 0, 255 );
|
||||
slider->SetSize( 80, colorSize );
|
||||
slider->SetName( name + "Slider");
|
||||
slider->onValueChanged.Add( this, &ColorPicker::SlidersMoved );
|
||||
}
|
||||
|
||||
void ColorPicker::NumericTyped( Gwen::Controls::Base* control )
|
||||
{
|
||||
if (!control)
|
||||
return;
|
||||
|
||||
TextBoxNumeric* box = control->DynamicCastTextBoxNumeric();
|
||||
if (!box)
|
||||
return;
|
||||
|
||||
if ( box->GetText() == L"")
|
||||
return;
|
||||
|
||||
int textValue = atoi( Utility::UnicodeToString( box->GetText()).c_str() );
|
||||
if ( textValue < 0) textValue = 0;
|
||||
if ( textValue > 255) textValue = 255;
|
||||
|
||||
if ( box->GetName().find("Red") != Gwen::String::npos )
|
||||
SetRed( textValue );
|
||||
|
||||
if ( box->GetName().find("Green") != Gwen::String::npos )
|
||||
SetGreen( textValue );
|
||||
|
||||
if ( box->GetName().find("Blue") != Gwen::String::npos )
|
||||
SetBlue( textValue );
|
||||
|
||||
if ( box->GetName().find("Alpha") != Gwen::String::npos )
|
||||
SetAlpha( textValue );
|
||||
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
void ColorPicker::SetColor( Gwen::Color color )
|
||||
{
|
||||
m_Color = color;
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
void ColorPicker::CreateControls()
|
||||
{
|
||||
int startY = 5;
|
||||
int height = 35;
|
||||
|
||||
CreateColorControl( "Red", startY );
|
||||
CreateColorControl( "Green", startY + height );
|
||||
CreateColorControl( "Blue", startY + height * 2 );
|
||||
CreateColorControl( "Alpha", startY + height * 3 );
|
||||
|
||||
GroupBox* finalGroup = new GroupBox( this );
|
||||
finalGroup->SetPos( 180, 40 );
|
||||
finalGroup->SetSize( 60, 60 );
|
||||
finalGroup->SetText( "Result" );
|
||||
finalGroup->SetName( "ResultGroupBox" );
|
||||
|
||||
|
||||
ColorDisplay* disp = new ColorDisplay( finalGroup );
|
||||
disp->SetName( "Result" );
|
||||
disp->SetBounds( 0 , 10, 32, 32 );
|
||||
disp->SetDrawCheckers( true );
|
||||
|
||||
//UpdateControls();
|
||||
}
|
||||
|
||||
void ColorPicker::UpdateColorControls( Gwen::String name, Gwen::Color col, int sliderVal )
|
||||
{
|
||||
Base* el = FindChildByName( name, true );
|
||||
|
||||
ColorDisplay* disp = el ? el->DynamicCastColorDisplay() : 0;
|
||||
disp->SetColor( col );
|
||||
|
||||
HorizontalSlider* slider = FindChildByName( name + "Slider", true )->DynamicCastHorizontalSlider();
|
||||
slider->SetValue( sliderVal );
|
||||
|
||||
TextBoxNumeric* box = FindChildByName( name + "Box", true )->DynamicCastTextBoxNumeric();
|
||||
box->SetText( Gwen::Utility::ToString( sliderVal ) );
|
||||
}
|
||||
|
||||
void ColorPicker::UpdateControls()
|
||||
{
|
||||
|
||||
//This is a little weird, but whatever for now
|
||||
UpdateColorControls( "Red", Color( GetColor().r, 0, 0, 255 ), GetColor().r );
|
||||
UpdateColorControls( "Green", Color( 0, GetColor().g, 0, 255 ), GetColor().g );
|
||||
UpdateColorControls( "Blue", Color( 0, 0, GetColor().b, 255 ), GetColor().b );
|
||||
UpdateColorControls( "Alpha", Color( 255, 255, 255, GetColor().a ), GetColor().a );
|
||||
|
||||
ColorDisplay* disp = FindChildByName( "Result", true )->DynamicCastColorDisplay();
|
||||
disp->SetColor( Color( GetColor().r, GetColor().g, GetColor().b, GetColor().a ) );
|
||||
|
||||
onColorChanged.Call( this );
|
||||
}
|
||||
void ColorPicker::SlidersMoved( Gwen::Controls::Base* control )
|
||||
{
|
||||
|
||||
HorizontalSlider* slider = control->DynamicCastHorizontalSlider();
|
||||
if (slider)
|
||||
SetColorByName( GetColorFromName( slider->GetName() ), slider->GetValue() );
|
||||
|
||||
UpdateControls();
|
||||
//SetColor( Gwen::Color( redSlider->GetValue(), greenSlider->GetValue(), blueSlider->GetValue(), alphaSlider->GetValue() ) );
|
||||
}
|
||||
|
||||
void ColorPicker::Layout( Skin::Base* skin )
|
||||
{
|
||||
BaseClass::Layout( skin );
|
||||
|
||||
SizeToChildren( false, true );
|
||||
SetSize( Width(), Height() + 5 );
|
||||
|
||||
GroupBox* groupBox = FindChildByName( "ResultGroupBox", true )->DynamicCastGroupBox();
|
||||
if ( groupBox )
|
||||
groupBox->SetPos( groupBox->X(), Height() * 0.5f - groupBox->Height() * 0.5f );
|
||||
|
||||
UpdateControls();
|
||||
}
|
||||
|
||||
|
||||
void ColorPicker::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawBackground( this );
|
||||
}
|
||||
|
||||
int ColorPicker::GetColorByName( Gwen::String colorName )
|
||||
{
|
||||
if ( colorName == "Red")
|
||||
return GetColor().r;
|
||||
else if ( colorName == "Green")
|
||||
return GetColor().g;
|
||||
else if ( colorName == "Blue")
|
||||
return GetColor().b;
|
||||
else if ( colorName == "Alpha")
|
||||
return GetColor().a;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Gwen::String ColorPicker::GetColorFromName( Gwen::String name )
|
||||
{
|
||||
if ( name.find("Red") != Gwen::String::npos )
|
||||
return "Red";
|
||||
if ( name.find("Green") != Gwen::String::npos )
|
||||
return "Green";
|
||||
if ( name.find("Blue") != Gwen::String::npos )
|
||||
return "Blue";
|
||||
if ( name.find("Alpha") != Gwen::String::npos )
|
||||
return "Alpha";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
void ColorPicker::SetColorByName( Gwen::String colorName, int colorValue )
|
||||
{
|
||||
if ( colorName == "Red")
|
||||
SetRed( colorValue );
|
||||
else if ( colorName == "Green")
|
||||
SetGreen( colorValue );
|
||||
else if ( colorName == "Blue")
|
||||
SetBlue( colorValue );
|
||||
else if ( colorName == "Alpha")
|
||||
SetAlpha( colorValue );
|
||||
}
|
||||
|
||||
void ColorPicker::SetAlphaVisible( bool visible )
|
||||
{
|
||||
GroupBox* groupBox = FindChildByName( "Alphagroupbox", true )->DynamicCastGroupBox();
|
||||
groupBox->SetHidden( !visible );
|
||||
Invalidate();
|
||||
}
|
89
btgui/Gwen/Controls/ColorPicker.h
Normal file
89
btgui/Gwen/Controls/ColorPicker.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_COLORPICKER_H
|
||||
#define GWEN_CONTROLS_COLORPICKER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace ControlsInternal
|
||||
{
|
||||
class GWEN_EXPORT ColorDisplay : public Controls::Base
|
||||
{
|
||||
public:
|
||||
GWEN_CONTROL_INLINE( ColorDisplay, Controls::Base )
|
||||
{
|
||||
SetSize( 32, 32 );
|
||||
m_Color = Color( 255, 0, 0, 255 );
|
||||
m_DrawCheckers = true;
|
||||
}
|
||||
|
||||
virtual void Render( Gwen::Skin::Base* skin )
|
||||
{
|
||||
skin->DrawColorDisplay( this, m_Color );
|
||||
}
|
||||
|
||||
virtual void SetColor( Gwen::Color color ) { m_Color = color; }
|
||||
virtual Gwen::Color GetColor() { return m_Color; }
|
||||
|
||||
virtual void SetRed( int red ) { m_Color.r = red; }
|
||||
virtual void SetGreen( int green ) { m_Color.g = green;}
|
||||
virtual void SetBlue( int blue ) { m_Color.b = blue; }
|
||||
virtual void SetAlpha( int alpha ) { m_Color.a = alpha;}
|
||||
|
||||
virtual void SetDrawCheckers( bool should ) { m_DrawCheckers = should; }
|
||||
|
||||
protected:
|
||||
Gwen::Color m_Color;
|
||||
bool m_DrawCheckers;
|
||||
};
|
||||
}
|
||||
namespace Controls
|
||||
{
|
||||
|
||||
class GWEN_EXPORT ColorPicker : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( ColorPicker, Base );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
virtual void CreateControls();
|
||||
virtual void SlidersMoved( Gwen::Controls::Base* control );
|
||||
virtual void NumericTyped( Gwen::Controls::Base* control );
|
||||
virtual void UpdateControls();
|
||||
virtual void UpdateColorControls( Gwen::String name, Gwen::Color col, int sliderVal );
|
||||
virtual void CreateColorControl( Gwen::String name, int y );
|
||||
|
||||
virtual void SetColor( Gwen::Color color );
|
||||
virtual Gwen::Color GetColor() { return m_Color; }
|
||||
|
||||
int GetColorByName( Gwen::String colorName );
|
||||
void SetColorByName( Gwen::String colorName, int colorValue );
|
||||
Gwen::String GetColorFromName( Gwen::String name );
|
||||
virtual void SetAlphaVisible( bool visible );
|
||||
|
||||
virtual void SetRed( int red ) { m_Color.r = red; }
|
||||
virtual void SetGreen( int green ) { m_Color.g = green;}
|
||||
virtual void SetBlue( int blue ) { m_Color.b = blue; }
|
||||
virtual void SetAlpha( int alpha ) { m_Color.a = alpha;}
|
||||
|
||||
Event::Caller onColorChanged;
|
||||
|
||||
protected:
|
||||
Gwen::Color m_Color;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
204
btgui/Gwen/Controls/ComboBox.cpp
Normal file
204
btgui/Gwen/Controls/ComboBox.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ComboBox.h"
|
||||
#include "Gwen/Controls/Menu.h"
|
||||
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
class GWEN_EXPORT DownArrow : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( DownArrow, Controls::Base )
|
||||
{
|
||||
SetMouseInputEnabled( true );
|
||||
SetSize( 15, 15 );
|
||||
|
||||
}
|
||||
|
||||
void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawArrowDown(this->m_Bounds);
|
||||
}
|
||||
|
||||
void SetComboBox( ComboBox* p ){ m_ComboBox = p; }
|
||||
|
||||
protected:
|
||||
|
||||
ComboBox* m_ComboBox;
|
||||
};
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ComboBox )
|
||||
{
|
||||
SetSize( 100, 20 );
|
||||
SetMouseInputEnabled( true );
|
||||
|
||||
m_Menu = new Menu( this );
|
||||
m_Menu->SetHidden( true );
|
||||
m_Menu->SetDisableIconMargin( true );
|
||||
m_Menu->SetTabable( false );
|
||||
|
||||
ComboBoxButton* m_OpenButton = new ComboBoxButton( this );
|
||||
|
||||
m_OpenButton->onDown.Add( this, &ComboBox::OpenButtonPressed );
|
||||
|
||||
m_OpenButton->Dock( Pos::Right );
|
||||
m_OpenButton->SetMargin( Margin( 2, 2, 2, 2 ) );
|
||||
m_OpenButton->SetWidth( 16 );
|
||||
m_OpenButton->SetTabable( false );
|
||||
|
||||
|
||||
m_SelectedItem = NULL;
|
||||
|
||||
SetAlignment( Gwen::Pos::Left | Gwen::Pos::CenterV );
|
||||
SetText( L"" );
|
||||
SetMargin( Margin( 3, 0, 0, 0 ) );
|
||||
|
||||
SetTabable( true );
|
||||
|
||||
}
|
||||
|
||||
MenuItem* ComboBox::AddItem( const UnicodeString& strLabel, const String& strName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn )
|
||||
{
|
||||
MenuItem* pItem = m_Menu->AddItem( strLabel, L"", pHandler, fn );
|
||||
pItem->SetName( strName );
|
||||
|
||||
pItem->onMenuItemSelected.Add( this, &ComboBox::OnItemSelected );
|
||||
|
||||
//Default
|
||||
if ( m_SelectedItem == NULL )
|
||||
OnItemSelected( pItem );
|
||||
|
||||
return pItem;
|
||||
}
|
||||
|
||||
void ComboBox::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawComboBox( this );
|
||||
}
|
||||
|
||||
|
||||
void ComboBox::OpenButtonPressed( Controls::Base* /*pControl*/ )
|
||||
{
|
||||
OnPress();
|
||||
}
|
||||
|
||||
void ComboBox::OnPress()
|
||||
{
|
||||
bool bWasMenuHidden = m_Menu->Hidden();
|
||||
|
||||
GetCanvas()->CloseMenus();
|
||||
|
||||
if ( bWasMenuHidden )
|
||||
{
|
||||
OpenList();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Menu->SetHidden( true );
|
||||
}
|
||||
}
|
||||
|
||||
void ComboBox::ClearItems()
|
||||
{
|
||||
if ( m_Menu )
|
||||
{
|
||||
m_Menu->ClearItems();
|
||||
}
|
||||
}
|
||||
void ComboBox::OnItemSelected( Controls::Base* pControl )
|
||||
{
|
||||
//Convert selected to a menu item
|
||||
MenuItem* pItem = pControl->DynamicCastMenuItem();
|
||||
if ( !pItem ) return;
|
||||
|
||||
m_SelectedItem = pItem;
|
||||
SetText( m_SelectedItem->GetText() );
|
||||
m_Menu->SetHidden( true );
|
||||
|
||||
onSelection.Call( this );
|
||||
|
||||
Focus();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ComboBox::OnLostKeyboardFocus()
|
||||
{
|
||||
SetTextColor( Color( 0, 0, 0, 255 ) );
|
||||
}
|
||||
|
||||
|
||||
void ComboBox::OnKeyboardFocus()
|
||||
{
|
||||
//Until we add the blue highlighting again
|
||||
SetTextColor( Color( 0, 0, 0, 255 ) );
|
||||
//m_SelectedText->SetTextColor( Color( 255, 255, 255, 255 ) );
|
||||
}
|
||||
|
||||
Gwen::Controls::Label* ComboBox::GetSelectedItem()
|
||||
{
|
||||
return m_SelectedItem;
|
||||
}
|
||||
|
||||
bool ComboBox::IsMenuOpen()
|
||||
{
|
||||
return m_Menu && !m_Menu->Hidden();
|
||||
}
|
||||
|
||||
void ComboBox::OpenList()
|
||||
{
|
||||
if ( !m_Menu ) return;
|
||||
|
||||
m_Menu->SetParent( GetCanvas() );
|
||||
m_Menu->SetHidden( false );
|
||||
m_Menu->BringToFront();
|
||||
|
||||
Gwen::Point p = LocalPosToCanvas( Gwen::Point( 0, 0 ) );
|
||||
|
||||
m_Menu->SetBounds( Gwen::Rect ( p.x, p.y + Height(), Width(), m_Menu->Height()) );
|
||||
}
|
||||
|
||||
void ComboBox::CloseList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ComboBox::OnKeyUp( bool bDown )
|
||||
{
|
||||
if ( bDown )
|
||||
{
|
||||
Base::List::reverse_iterator it = std::find( m_Menu->Children.rbegin(), m_Menu->Children.rend(), m_SelectedItem );
|
||||
if ( it != m_Menu->Children.rend() && ( ++it != m_Menu->Children.rend() ) )
|
||||
{
|
||||
Base* pUpElement = *it;
|
||||
OnItemSelected(pUpElement);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool ComboBox::OnKeyDown( bool bDown )
|
||||
{
|
||||
if ( bDown )
|
||||
{
|
||||
Base::List::iterator it = std::find( m_Menu->Children.begin(), m_Menu->Children.end(), m_SelectedItem );
|
||||
if ( it != m_Menu->Children.end() && ( ++it != m_Menu->Children.end() ) )
|
||||
{
|
||||
Base* pDownElement = *it;
|
||||
OnItemSelected(pDownElement);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ComboBox::RenderFocus( Gwen::Skin::Base* /*skin*/ )
|
||||
{
|
||||
}
|
87
btgui/Gwen/Controls/ComboBox.h
Normal file
87
btgui/Gwen/Controls/ComboBox.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_COMBOBOX_H
|
||||
#define GWEN_CONTROLS_COMBOBOX_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/TextBox.h"
|
||||
#include "Gwen/Controls/Menu.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT ComboBoxButton : public Button
|
||||
{
|
||||
GWEN_CONTROL_INLINE( ComboBoxButton, Button ){}
|
||||
|
||||
virtual void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawComboBoxButton( this, m_bDepressed );
|
||||
}
|
||||
};
|
||||
|
||||
class GWEN_EXPORT ComboBox : public Button
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( ComboBox, Button );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
|
||||
virtual Gwen::Controls::Label* GetSelectedItem();
|
||||
|
||||
virtual void OnPress();
|
||||
void OpenButtonPressed( Controls::Base* /*pControl*/ );
|
||||
|
||||
virtual void OnItemSelected( Controls::Base* pControl );
|
||||
virtual void OpenList();
|
||||
virtual void CloseList();
|
||||
|
||||
virtual Controls::Base* GetControlAt( int x, int y )
|
||||
{
|
||||
if ( x < 0 || y < 0 || x >= Width() || y >= Height() )
|
||||
return NULL;
|
||||
|
||||
return this;
|
||||
}
|
||||
virtual bool IsMenuComponent()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void ClearItems();
|
||||
|
||||
virtual MenuItem* AddItem( const UnicodeString& strLabel, const String& strName = "", Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL );
|
||||
virtual bool OnKeyUp( bool bDown );
|
||||
virtual bool OnKeyDown( bool bDown );
|
||||
|
||||
virtual void RenderFocus( Gwen::Skin::Base* skin );
|
||||
virtual void OnLostKeyboardFocus();
|
||||
virtual void OnKeyboardFocus();
|
||||
|
||||
virtual bool IsMenuOpen();
|
||||
|
||||
Gwen::Event::Caller onSelection;
|
||||
|
||||
protected:
|
||||
|
||||
Menu* m_Menu;
|
||||
MenuItem* m_SelectedItem;
|
||||
|
||||
Controls::Base* m_Button;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
183
btgui/Gwen/Controls/CrossSplitter.cpp
Normal file
183
btgui/Gwen/Controls/CrossSplitter.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/CrossSplitter.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( CrossSplitter )
|
||||
{
|
||||
m_VSplitter = new SplitterBar( this );
|
||||
m_VSplitter->SetPos( 0, 128 );
|
||||
m_VSplitter->onDragged.Add( this, &CrossSplitter::OnVerticalMoved );
|
||||
m_VSplitter->SetCursor( Gwen::CursorType::SizeNS );
|
||||
|
||||
m_HSplitter = new SplitterBar( this );
|
||||
m_HSplitter->SetPos( 128, 0 );
|
||||
m_HSplitter->onDragged.Add( this, &CrossSplitter::OnHorizontalMoved );
|
||||
m_HSplitter->SetCursor( Gwen::CursorType::SizeWE );
|
||||
|
||||
m_CSplitter = new SplitterBar( this );
|
||||
m_CSplitter->SetPos( 128, 128 );
|
||||
m_CSplitter->onDragged.Add( this, &CrossSplitter::OnCenterMoved );
|
||||
m_CSplitter->SetCursor( Gwen::CursorType::SizeAll );
|
||||
|
||||
m_fHVal = 0.5f;
|
||||
m_fVVal = 0.5f;
|
||||
|
||||
SetPanel( 0, NULL );
|
||||
SetPanel( 1, NULL );
|
||||
SetPanel( 2, NULL );
|
||||
SetPanel( 3, NULL );
|
||||
|
||||
SetSplitterSize( 5 );
|
||||
SetSplittersVisible( false );
|
||||
|
||||
m_iZoomedSection = -1;
|
||||
}
|
||||
|
||||
void CrossSplitter::UpdateVSplitter()
|
||||
{
|
||||
m_VSplitter->MoveTo( m_VSplitter->X(), ( Height() - m_VSplitter->Height() ) * ( m_fVVal ));
|
||||
}
|
||||
void CrossSplitter::UpdateHSplitter()
|
||||
{
|
||||
m_HSplitter->MoveTo( ( Width() - m_HSplitter->Width() ) * ( m_fHVal ), m_HSplitter->Y() );
|
||||
}
|
||||
|
||||
void CrossSplitter::OnCenterMoved( Controls::Base * /*control*/ )
|
||||
{
|
||||
//Move the other two bars into position
|
||||
CalculateValueCenter();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CrossSplitter::UpdateCSplitter()
|
||||
{
|
||||
m_CSplitter->MoveTo( ( Width() - m_CSplitter->Width() ) * ( m_fHVal ), ( Height() - m_CSplitter->Height() ) * ( m_fVVal ));
|
||||
}
|
||||
|
||||
void CrossSplitter::OnHorizontalMoved( Controls::Base * /*control*/ )
|
||||
{
|
||||
m_fHVal = CalculateValueHorizontal();
|
||||
Invalidate();
|
||||
}
|
||||
void CrossSplitter::OnVerticalMoved( Controls::Base * /*control*/ )
|
||||
{
|
||||
m_fVVal = CalculateValueVertical();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CrossSplitter::CalculateValueCenter()
|
||||
{
|
||||
m_fHVal = (float)m_CSplitter->X() / (float)( Width() - m_CSplitter->Width() );
|
||||
m_fVVal = (float)m_CSplitter->Y() / (float)( Height() - m_CSplitter->Height() );
|
||||
}
|
||||
|
||||
float CrossSplitter::CalculateValueHorizontal()
|
||||
{
|
||||
return (float)m_HSplitter->X() / (float)( Width() - m_HSplitter->Width() );
|
||||
}
|
||||
|
||||
float CrossSplitter::CalculateValueVertical()
|
||||
{
|
||||
return (float)m_VSplitter->Y() / (float)( Height() - m_VSplitter->Height() );
|
||||
}
|
||||
|
||||
void CrossSplitter::Layout( Skin::Base* /*skin*/ )
|
||||
{
|
||||
m_VSplitter->SetSize( Width(), m_fBarSize );
|
||||
m_HSplitter->SetSize( m_fBarSize, Height() );
|
||||
m_CSplitter->SetSize( m_fBarSize, m_fBarSize );
|
||||
|
||||
UpdateVSplitter();
|
||||
UpdateHSplitter();
|
||||
UpdateCSplitter();
|
||||
|
||||
if ( m_iZoomedSection == -1 )
|
||||
{
|
||||
if ( m_Sections[0] )
|
||||
m_Sections[0]->SetBounds( 0, 0, m_HSplitter->X(), m_VSplitter->Y() );
|
||||
|
||||
if ( m_Sections[1] )
|
||||
m_Sections[1]->SetBounds( m_HSplitter->X() + m_fBarSize, 0, Width() - ( m_HSplitter->X() + m_fBarSize ), m_VSplitter->Y() );
|
||||
|
||||
if ( m_Sections[2] )
|
||||
m_Sections[2]->SetBounds( 0, m_VSplitter->Y() + m_fBarSize, m_HSplitter->X(), Height() - ( m_VSplitter->Y() + m_fBarSize ) );
|
||||
|
||||
if ( m_Sections[3] )
|
||||
m_Sections[3]->SetBounds( m_HSplitter->X() + m_fBarSize, m_VSplitter->Y() + m_fBarSize, Width() - ( m_HSplitter->X() + m_fBarSize ), Height() - ( m_VSplitter->Y() + m_fBarSize ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
//This should probably use Fill docking instead
|
||||
m_Sections[m_iZoomedSection]->SetBounds( 0, 0, Width(), Height() );
|
||||
}
|
||||
}
|
||||
|
||||
void CrossSplitter::SetPanel( int index, Controls::Base* pPanel)
|
||||
{
|
||||
Debug::AssertCheck( index >= 0 && index <= 3, "CrossSplitter::SetPanel out of range" );
|
||||
|
||||
m_Sections[index] = pPanel;
|
||||
|
||||
if ( pPanel )
|
||||
{
|
||||
pPanel->Dock( Pos::None );
|
||||
pPanel->SetParent( this );
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
Controls::Base* CrossSplitter::GetPanel( int i )
|
||||
{
|
||||
return m_Sections[i];
|
||||
}
|
||||
|
||||
|
||||
void CrossSplitter::ZoomChanged()
|
||||
{
|
||||
onZoomChange.Call( this );
|
||||
if ( m_iZoomedSection == -1 )
|
||||
{
|
||||
onUnZoomed.Call( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
onZoomed.Call( this );
|
||||
}
|
||||
}
|
||||
|
||||
void CrossSplitter::Zoom( int section )
|
||||
{
|
||||
UnZoom();
|
||||
|
||||
if ( m_Sections[section] )
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ( i != section && m_Sections[i] )
|
||||
m_Sections[i]->SetHidden( true );
|
||||
}
|
||||
m_iZoomedSection = section;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
ZoomChanged();
|
||||
}
|
||||
|
||||
void CrossSplitter::UnZoom()
|
||||
{
|
||||
m_iZoomedSection = -1;
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( m_Sections[i] )
|
||||
m_Sections[i]->SetHidden( false );
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
ZoomChanged();
|
||||
}
|
63
btgui/Gwen/Controls/CrossSplitter.h
Normal file
63
btgui/Gwen/Controls/CrossSplitter.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_CROSSSPLITTER_H
|
||||
#define GWEN_CONTROLS_CROSSSPLITTER_H
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/SplitterBar.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT CrossSplitter : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( CrossSplitter, Controls::Base );
|
||||
|
||||
void Layout( Skin::Base* skin );
|
||||
|
||||
virtual float CalculateValueVertical();
|
||||
virtual float CalculateValueHorizontal();
|
||||
virtual void CalculateValueCenter();
|
||||
virtual void UpdateHSplitter();
|
||||
virtual void UpdateVSplitter();
|
||||
virtual void UpdateCSplitter();
|
||||
virtual void OnVerticalMoved( Controls::Base * control );
|
||||
virtual void OnHorizontalMoved( Controls::Base * control );
|
||||
virtual void OnCenterMoved( Controls::Base * control );
|
||||
|
||||
virtual void SetPanel( int i, Controls::Base* pPanel );
|
||||
virtual Controls::Base* GetPanel( int i );
|
||||
|
||||
virtual bool IsZoomed(){ return m_iZoomedSection != -1; }
|
||||
virtual void Zoom( int section );
|
||||
virtual void UnZoom();
|
||||
virtual void ZoomChanged();
|
||||
virtual void CenterPanels() { m_fHVal = 0.5f; m_fVVal = 0.5f; Invalidate(); }
|
||||
|
||||
virtual void SetSplittersVisible( bool b ){ m_VSplitter->SetShouldDrawBackground( b ); m_HSplitter->SetShouldDrawBackground( b ); m_CSplitter->SetShouldDrawBackground( b ); }
|
||||
virtual void SetSplitterSize( int size ) { m_fBarSize = size; }
|
||||
|
||||
private:
|
||||
|
||||
SplitterBar* m_VSplitter;
|
||||
SplitterBar* m_HSplitter;
|
||||
SplitterBar* m_CSplitter;
|
||||
|
||||
Controls::Base* m_Sections[4];
|
||||
|
||||
float m_fHVal;
|
||||
float m_fVVal;
|
||||
int m_fBarSize;
|
||||
|
||||
char m_iZoomedSection;
|
||||
|
||||
Gwen::Event::Caller onZoomed;
|
||||
Gwen::Event::Caller onUnZoomed;
|
||||
Gwen::Event::Caller onZoomChange;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
24
btgui/Gwen/Controls/Dialog/FileOpen.cpp
Normal file
24
btgui/Gwen/Controls/Dialog/FileOpen.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Platform.h"
|
||||
#include "Gwen/Controls/Dialogs/FileOpen.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Dialogs;
|
||||
|
||||
void Gwen::Dialogs::FileOpenEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::FunctionStr fnCallback )
|
||||
{
|
||||
if ( bUseSystem && Gwen::Platform::FileOpen( Name, StartPath, Extension, pHandler, fnCallback ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: SHOW GWEN FILE SELECTION DIALOG
|
||||
//
|
||||
}
|
24
btgui/Gwen/Controls/Dialog/FileSave.cpp
Normal file
24
btgui/Gwen/Controls/Dialog/FileSave.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Platform.h"
|
||||
#include "Gwen/Controls/Dialogs/FileSave.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Dialogs;
|
||||
|
||||
void Gwen::Dialogs::FileSaveEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::FunctionStr fnCallback )
|
||||
{
|
||||
if ( bUseSystem && Gwen::Platform::FileSave( Name, StartPath, Extension, pHandler, fnCallback ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: SHOW GWEN FILE SELECTION DIALOG
|
||||
//
|
||||
}
|
12
btgui/Gwen/Controls/Dialog/Query.cpp
Normal file
12
btgui/Gwen/Controls/Dialog/Query.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Dialogs/Query.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
35
btgui/Gwen/Controls/Dialogs/FileOpen.h
Normal file
35
btgui/Gwen/Controls/Dialogs/FileOpen.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_DIALOGS_FILEOPEN_H
|
||||
#define GWEN_CONTROLS_DIALOGS_FILEOPEN_H
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Dialogs
|
||||
{
|
||||
// Usage:
|
||||
//
|
||||
// Gwen::Dialogs::FileOpen( true, "Open Map", "C:\my\folder\", "My Map Format|*.bmf", this, &MyClass::OpenFilename );
|
||||
//
|
||||
|
||||
//
|
||||
// The REAL function.
|
||||
// If bUseSystem is used, it may use the system's modal dialog - which
|
||||
// will steal focus and pause the rest of GWEN until it's continued.
|
||||
//
|
||||
void GWEN_EXPORT FileOpenEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::FunctionStr fnCallback = NULL );
|
||||
|
||||
//
|
||||
// Templated function simply to avoid having to manually cast the callback function.
|
||||
//
|
||||
template< typename A>
|
||||
void FileOpen( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, A fnCallback = NULL )
|
||||
{
|
||||
FileOpenEx( bUseSystem, Name, StartPath, Extension, pHandler, (Gwen::Event::Handler::FunctionStr)fnCallback );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
40
btgui/Gwen/Controls/Dialogs/FileSave.h
Normal file
40
btgui/Gwen/Controls/Dialogs/FileSave.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_DIALOGS_FILESAVE_H
|
||||
#define GWEN_CONTROLS_DIALOGS_FILESAVE_H
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Dialogs
|
||||
{
|
||||
// Usage:
|
||||
//
|
||||
// Gwen::Dialogs::FileOpen( true, "Open Map", "C:\my\folder\", "My Map Format|*.bmf", this, &MyClass::OpenFilename );
|
||||
//
|
||||
|
||||
//
|
||||
// Callback function, for success
|
||||
//
|
||||
typedef void (Event::Handler::*FileSaveSuccessCallback)( const String& filename );
|
||||
|
||||
//
|
||||
// The REAL function.
|
||||
// If bUseSystem is used, it may use the system's modal dialog - which
|
||||
// will steal focus and pause the rest of GWEN until it's continued.
|
||||
//
|
||||
void GWEN_EXPORT FileSaveEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::FunctionStr fnCallback = NULL );
|
||||
|
||||
//
|
||||
// Templated function simply to avoid having to manually cast the callback function.
|
||||
//
|
||||
template< typename A>
|
||||
void FileSave( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, A fnCallback = NULL )
|
||||
{
|
||||
FileSaveEx( bUseSystem, Name, StartPath, Extension, pHandler, (Gwen::Event::Handler::FunctionStr)fnCallback );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
14
btgui/Gwen/Controls/Dialogs/Query.h
Normal file
14
btgui/Gwen/Controls/Dialogs/Query.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_DIALOGS_QUERY_H
|
||||
#define GWEN_CONTROLS_DIALOGS_QUERY_H
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Dialogs
|
||||
{
|
||||
//TODO. YesNo, Ok etc
|
||||
}
|
||||
}
|
||||
#endif
|
343
btgui/Gwen/Controls/DockBase.cpp
Normal file
343
btgui/Gwen/Controls/DockBase.cpp
Normal file
@ -0,0 +1,343 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/DockBase.h"
|
||||
#include "Gwen/Controls/DockedTabControl.h"
|
||||
#include "Gwen/Controls/Highlight.h"
|
||||
#include "Gwen/DragAndDrop.h"
|
||||
#include "Gwen/Controls/Resizer.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( DockBase )
|
||||
{
|
||||
SetPadding( Padding( 1, 1, 1, 1 ) );
|
||||
SetSize( 200, 200 );
|
||||
|
||||
m_DockedTabControl = NULL;
|
||||
m_Left = NULL;
|
||||
m_Right = NULL;
|
||||
m_Top = NULL;
|
||||
m_Bottom = NULL;
|
||||
|
||||
m_bDrawHover = false;
|
||||
}
|
||||
|
||||
TabControl* DockBase::GetTabControl()
|
||||
{
|
||||
return m_DockedTabControl;
|
||||
}
|
||||
|
||||
void DockBase::SetupChildDock( int iPos )
|
||||
{
|
||||
if ( !m_DockedTabControl )
|
||||
{
|
||||
m_DockedTabControl = new DockedTabControl( this );
|
||||
m_DockedTabControl->onLoseTab.Add( this, &DockBase::OnTabRemoved );
|
||||
m_DockedTabControl->SetTabStripPosition( Pos::Bottom );
|
||||
m_DockedTabControl->SetShowTitlebar( true );
|
||||
}
|
||||
|
||||
Dock( iPos );
|
||||
|
||||
int iSizeDirection = Pos::Left;
|
||||
if ( iPos == Pos::Left ) iSizeDirection = Pos::Right;
|
||||
if ( iPos == Pos::Top ) iSizeDirection = Pos::Bottom;
|
||||
if ( iPos == Pos::Bottom ) iSizeDirection = Pos::Top;
|
||||
|
||||
ControlsInternal::Resizer* sizer = new ControlsInternal::Resizer( this );
|
||||
sizer->Dock( iSizeDirection );
|
||||
sizer->SetResizeDir( iSizeDirection );
|
||||
sizer->SetSize( 2, 2 );
|
||||
sizer->SetTarget( this );
|
||||
}
|
||||
|
||||
void DockBase::Render( Skin::Base* /*skin*/ )
|
||||
{
|
||||
//Gwen::Render->SetDrawColor( Colors::Black );
|
||||
//Gwen::Render->DrawLinedRect( GetRenderBounds() );
|
||||
}
|
||||
|
||||
DockBase** DockBase::GetChildDockPtr( int iPos )
|
||||
{
|
||||
if ( iPos == Pos::Left ) return &m_Left;
|
||||
if ( iPos == Pos::Right ) return &m_Right;
|
||||
if ( iPos == Pos::Top ) return &m_Top;
|
||||
if ( iPos == Pos::Bottom ) return &m_Bottom;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DockBase* DockBase::GetChildDock( int iPos )
|
||||
{
|
||||
DockBase** pDock = GetChildDockPtr( iPos );
|
||||
|
||||
if ( !(*pDock) )
|
||||
{
|
||||
(*pDock) = new DockBase( this );
|
||||
(*pDock)->SetupChildDock( iPos );
|
||||
}
|
||||
else
|
||||
{
|
||||
(*pDock)->SetHidden( false );
|
||||
}
|
||||
|
||||
return *pDock;
|
||||
}
|
||||
|
||||
int DockBase::GetDroppedTabDirection( int x, int y )
|
||||
{
|
||||
int w = Width();
|
||||
int h = Height();
|
||||
|
||||
float top = (float)y / (float) h;
|
||||
float left = (float)x / (float) w;
|
||||
float right = (float)(w - x) /(float) w;
|
||||
float bottom = (float)(h - y) / (float) h;
|
||||
|
||||
float minimum = GwenUtil_Min( GwenUtil_Min( GwenUtil_Min( top, left ), right ), bottom );
|
||||
m_bDropFar = ( minimum < 0.2f );
|
||||
if ( minimum > 0.3 ) return Pos::Fill;
|
||||
|
||||
if ( top == minimum && (!m_Top || m_Top->Hidden()) ) return Pos::Top;
|
||||
if ( left == minimum && (!m_Left || m_Left->Hidden()) ) return Pos::Left;
|
||||
if ( right == minimum && (!m_Right || m_Right->Hidden()) ) return Pos::Right;
|
||||
if ( bottom == minimum && (!m_Bottom || m_Bottom->Hidden()) ) return Pos::Bottom;
|
||||
|
||||
return Pos::Fill;
|
||||
}
|
||||
|
||||
bool DockBase::DragAndDrop_CanAcceptPackage( Gwen::DragAndDrop::Package* pPackage )
|
||||
{
|
||||
// A TAB button dropped
|
||||
if ( pPackage->name == "TabButtonMove" )
|
||||
return true;
|
||||
|
||||
// a TAB window dropped
|
||||
if ( pPackage->name == "TabWindowMove" )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddTabToDock( TabButton* pTabButton, DockedTabControl* pControl )
|
||||
{
|
||||
pControl->AddPage( pTabButton );
|
||||
}
|
||||
|
||||
bool DockBase::DragAndDrop_HandleDrop( Gwen::DragAndDrop::Package* pPackage, int x, int y )
|
||||
{
|
||||
Gwen::Point pPos = CanvasPosToLocal( Gwen::Point( x, y ) );
|
||||
int dir = GetDroppedTabDirection( pPos.x, pPos.y );
|
||||
|
||||
DockedTabControl* pAddTo = m_DockedTabControl;
|
||||
if ( dir == Pos::Fill && pAddTo == NULL ) return false;
|
||||
|
||||
if ( dir != Pos::Fill )
|
||||
{
|
||||
DockBase* pDock = GetChildDock( dir );
|
||||
pAddTo = pDock->m_DockedTabControl;
|
||||
|
||||
if ( !m_bDropFar ) pDock->BringToFront();
|
||||
else pDock->SendToBack();
|
||||
}
|
||||
|
||||
if ( pPackage->name == "TabButtonMove" )
|
||||
{
|
||||
TabButton* pTabButton = DragAndDrop::SourceControl->DynamicCastTabButton();
|
||||
if ( !pTabButton ) return false;
|
||||
|
||||
AddTabToDock( pTabButton, pAddTo );
|
||||
}
|
||||
|
||||
if ( pPackage->name == "TabWindowMove" )
|
||||
{
|
||||
DockedTabControl* pTabControl = DragAndDrop::SourceControl->DynamicCastDockedTabControl();
|
||||
if ( !pTabControl ) return false;
|
||||
if ( pTabControl == pAddTo ) return false;
|
||||
|
||||
pTabControl->MoveTabsTo( pAddTo );
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DockBase::IsEmpty()
|
||||
{
|
||||
if ( m_DockedTabControl && m_DockedTabControl->TabCount() > 0 ) return false;
|
||||
|
||||
if ( m_Left && !m_Left->IsEmpty() ) return false;
|
||||
if ( m_Right && !m_Right->IsEmpty() ) return false;
|
||||
if ( m_Top && !m_Top->IsEmpty() ) return false;
|
||||
if ( m_Bottom && !m_Bottom->IsEmpty() ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DockBase::OnTabRemoved( Gwen::Controls::Base* /*pControl*/ )
|
||||
{
|
||||
DoRedundancyCheck();
|
||||
DoConsolidateCheck();
|
||||
}
|
||||
|
||||
void DockBase::DoRedundancyCheck()
|
||||
{
|
||||
if ( !IsEmpty() ) return;
|
||||
|
||||
DockBase* pDockParent = GetParent()->DynamicCastDockBase();
|
||||
if ( !pDockParent ) return;
|
||||
|
||||
pDockParent->OnRedundantChildDock( this );
|
||||
}
|
||||
|
||||
void DockBase::DoConsolidateCheck()
|
||||
{
|
||||
if ( IsEmpty() ) return;
|
||||
if ( !m_DockedTabControl ) return;
|
||||
if ( m_DockedTabControl->TabCount() > 0 ) return;
|
||||
|
||||
if ( m_Bottom && !m_Bottom->IsEmpty() )
|
||||
{
|
||||
m_Bottom->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_Top && !m_Top->IsEmpty() )
|
||||
{
|
||||
m_Top->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_Left && !m_Left->IsEmpty() )
|
||||
{
|
||||
m_Left->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_Right && !m_Right->IsEmpty() )
|
||||
{
|
||||
m_Right->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DockBase::OnRedundantChildDock( DockBase* pDockBase )
|
||||
{
|
||||
pDockBase->SetHidden( true );
|
||||
DoRedundancyCheck();
|
||||
DoConsolidateCheck();
|
||||
}
|
||||
|
||||
void DockBase::DragAndDrop_HoverEnter( Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/ )
|
||||
{
|
||||
m_bDrawHover = true;
|
||||
}
|
||||
|
||||
void DockBase::DragAndDrop_HoverLeave( Gwen::DragAndDrop::Package* /*pPackage*/ )
|
||||
{
|
||||
m_bDrawHover = false;
|
||||
}
|
||||
|
||||
void DockBase::DragAndDrop_Hover( Gwen::DragAndDrop::Package* /*pPackage*/, int x, int y )
|
||||
{
|
||||
Gwen::Point pPos = CanvasPosToLocal( Gwen::Point( x, y ) );
|
||||
int dir = GetDroppedTabDirection( pPos.x, pPos.y );
|
||||
|
||||
if ( dir == Pos::Fill )
|
||||
{
|
||||
if ( !m_DockedTabControl )
|
||||
{
|
||||
m_HoverRect = Gwen::Rect( 0, 0, 0, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
m_HoverRect = GetInnerBounds();
|
||||
return;
|
||||
}
|
||||
|
||||
m_HoverRect = GetRenderBounds();
|
||||
|
||||
int HelpBarWidth = 0;
|
||||
|
||||
if ( dir == Pos::Left )
|
||||
{
|
||||
HelpBarWidth = m_HoverRect.w * 0.25f;
|
||||
m_HoverRect.w = HelpBarWidth;
|
||||
}
|
||||
|
||||
if ( dir == Pos::Right )
|
||||
{
|
||||
HelpBarWidth = m_HoverRect.w * 0.25f;
|
||||
m_HoverRect.x = m_HoverRect.w - HelpBarWidth;
|
||||
m_HoverRect.w = HelpBarWidth;
|
||||
}
|
||||
|
||||
if ( dir == Pos::Top )
|
||||
{
|
||||
HelpBarWidth = m_HoverRect.h * 0.25f;
|
||||
m_HoverRect.h = HelpBarWidth;
|
||||
}
|
||||
|
||||
if ( dir == Pos::Bottom )
|
||||
{
|
||||
HelpBarWidth = m_HoverRect.h * 0.25f;
|
||||
m_HoverRect.y = m_HoverRect.h - HelpBarWidth;
|
||||
m_HoverRect.h = HelpBarWidth;
|
||||
}
|
||||
|
||||
if ( (dir == Pos::Top || dir == Pos::Bottom ) && !m_bDropFar )
|
||||
{
|
||||
if ( m_Left && m_Left->Visible() )
|
||||
{
|
||||
m_HoverRect.x += m_Left->Width();
|
||||
m_HoverRect.w -= m_Left->Width();
|
||||
}
|
||||
|
||||
if ( m_Right && m_Right->Visible() )
|
||||
{
|
||||
m_HoverRect.w -= m_Right->Width();
|
||||
}
|
||||
}
|
||||
|
||||
if ( (dir == Pos::Left || dir == Pos::Right ) && !m_bDropFar )
|
||||
{
|
||||
if ( m_Top && m_Top->Visible() )
|
||||
{
|
||||
m_HoverRect.y += m_Top->Height();
|
||||
m_HoverRect.h -= m_Top->Height();
|
||||
}
|
||||
|
||||
if ( m_Bottom && m_Bottom->Visible() )
|
||||
{
|
||||
m_HoverRect.h -= m_Bottom->Height();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DockBase::RenderOver( Skin::Base* skin )
|
||||
{
|
||||
if ( !m_bDrawHover ) return;
|
||||
|
||||
Gwen::Renderer::Base* render = skin->GetRender();
|
||||
|
||||
render->SetDrawColor( Gwen::Color( 255, 100, 255, 20 ) );
|
||||
render->DrawFilledRect( GetRenderBounds() );
|
||||
|
||||
if ( m_HoverRect.w == 0 ) return;
|
||||
|
||||
render->SetDrawColor( Gwen::Color( 255, 100, 255, 100 ) );
|
||||
render->DrawFilledRect( m_HoverRect );
|
||||
|
||||
render->SetDrawColor( Gwen::Color( 255, 100, 255, 200 ) );
|
||||
render->DrawLinedRect( m_HoverRect );
|
||||
}
|
77
btgui/Gwen/Controls/DockBase.h
Normal file
77
btgui/Gwen/Controls/DockBase.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_DOCKBASE_H
|
||||
#define GWEN_CONTROLS_DOCKBASE_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class DockedTabControl;
|
||||
class TabControl;
|
||||
|
||||
class GWEN_EXPORT DockBase : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( DockBase, Base );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void RenderOver( Skin::Base* skin );
|
||||
virtual bool IsEmpty();
|
||||
|
||||
virtual TabControl* GetTabControl();
|
||||
|
||||
virtual DockBase* GetRight(){ return GetChildDock( Pos::Right ); }
|
||||
virtual DockBase* GetLeft(){ return GetChildDock( Pos::Left ); }
|
||||
virtual DockBase* GetTop(){ return GetChildDock( Pos::Top ); }
|
||||
virtual DockBase* GetBottom(){ return GetChildDock( Pos::Bottom ); }
|
||||
|
||||
// No action on space (default button action is to press)
|
||||
virtual bool OnKeySpace( bool /*bDown*/ ){ return false; }
|
||||
|
||||
private:
|
||||
|
||||
// Drag n Drop
|
||||
virtual bool DragAndDrop_HandleDrop( Gwen::DragAndDrop::Package* pPackage, int x, int y );
|
||||
virtual bool DragAndDrop_CanAcceptPackage( Gwen::DragAndDrop::Package* pPackage );
|
||||
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 void SetupChildDock( int iPos );
|
||||
|
||||
virtual void DoRedundancyCheck();
|
||||
virtual void DoConsolidateCheck();
|
||||
virtual void OnRedundantChildDock( DockBase* pDockBase );
|
||||
|
||||
virtual int GetDroppedTabDirection( int x, int y );
|
||||
virtual void OnTabRemoved( Gwen::Controls::Base* pControl );
|
||||
|
||||
DockBase* GetChildDock( int iPos );
|
||||
DockBase** GetChildDockPtr( int iPos );
|
||||
|
||||
DockBase* m_Left;
|
||||
DockBase* m_Right;
|
||||
DockBase* m_Top;
|
||||
DockBase* m_Bottom;
|
||||
|
||||
// Only CHILD dockpanels have a tabcontrol.
|
||||
DockedTabControl* m_DockedTabControl;
|
||||
|
||||
bool m_bDrawHover;
|
||||
bool m_bDropFar;
|
||||
Gwen::Rect m_HoverRect;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
92
btgui/Gwen/Controls/DockedTabControl.cpp
Normal file
92
btgui/Gwen/Controls/DockedTabControl.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/DockedTabControl.h"
|
||||
#include "Gwen/Controls/Highlight.h"
|
||||
#include "Gwen/DragAndDrop.h"
|
||||
#include "Gwen/Controls/WindowControl.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( DockedTabControl )
|
||||
{
|
||||
m_WindowControl = NULL;
|
||||
|
||||
Dock( Pos::Fill );
|
||||
|
||||
m_pTitleBar = new TabTitleBar( this );
|
||||
m_pTitleBar->Dock( Pos::Top );
|
||||
m_pTitleBar->SetHidden( true );
|
||||
|
||||
}
|
||||
|
||||
void DockedTabControl::Layout( Skin::Base* skin )
|
||||
{
|
||||
GetTabStrip()->SetHidden( TabCount() <= 1 );
|
||||
UpdateTitleBar();
|
||||
BaseClass::Layout( skin );
|
||||
}
|
||||
|
||||
void DockedTabControl::UpdateTitleBar()
|
||||
{
|
||||
if ( !GetCurrentButton() ) return;
|
||||
|
||||
m_pTitleBar->UpdateFromTab( GetCurrentButton() );
|
||||
}
|
||||
|
||||
void DockedTabControl::DragAndDrop_StartDragging( Gwen::DragAndDrop::Package* pPackage, int x, int y )
|
||||
{
|
||||
BaseClass::DragAndDrop_StartDragging( pPackage, x, y );
|
||||
|
||||
SetHidden( true );
|
||||
// This hiding our parent thing is kind of lousy.
|
||||
GetParent()->SetHidden( true );
|
||||
}
|
||||
|
||||
void DockedTabControl::DragAndDrop_EndDragging( bool bSuccess, int /*x*/, int /*y*/ )
|
||||
{
|
||||
SetHidden( false );
|
||||
|
||||
if ( !bSuccess )
|
||||
{
|
||||
GetParent()->SetHidden( false );
|
||||
}
|
||||
|
||||
/*
|
||||
if ( !bSuccess )
|
||||
{
|
||||
// Create our window control
|
||||
if ( !m_WindowControl )
|
||||
{
|
||||
m_WindowControl = new WindowControl( GetCanvas() );
|
||||
m_WindowControl->SetBounds( x, y, Width(), Height() );
|
||||
}
|
||||
|
||||
m_WindowControl->SetPosition( x, y );
|
||||
SetParent( m_WindowControl );
|
||||
SetPosition( 0, 0 );
|
||||
Dock( Pos::Fill );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void DockedTabControl::MoveTabsTo( DockedTabControl* pTarget )
|
||||
{
|
||||
Base::List Children = GetTabStrip()->Children;
|
||||
for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
|
||||
{
|
||||
TabButton* pButton = (*iter)->DynamicCastTabButton();
|
||||
if ( !pButton ) continue;
|
||||
|
||||
pTarget->AddPage( pButton );
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
42
btgui/Gwen/Controls/DockedTabControl.h
Normal file
42
btgui/Gwen/Controls/DockedTabControl.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_DOCKEDTABCONTROL_H
|
||||
#define GWEN_CONTROLS_DOCKEDTABCONTROL_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/TabControl.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT DockedTabControl : public TabControl
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( DockedTabControl, TabControl );
|
||||
|
||||
void SetShowTitlebar( bool bShow ){ m_pTitleBar->SetHidden( !bShow ); }
|
||||
|
||||
void Layout( Skin::Base* skin );
|
||||
void UpdateTitleBar();
|
||||
|
||||
virtual void DragAndDrop_StartDragging( Gwen::DragAndDrop::Package* pPackage, int x, int y );
|
||||
virtual void DragAndDrop_EndDragging( bool bSuccess, int x, int y );
|
||||
|
||||
void MoveTabsTo( DockedTabControl* pTarget );
|
||||
|
||||
private:
|
||||
|
||||
TabTitleBar* m_pTitleBar;
|
||||
Base* m_WindowControl;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
59
btgui/Gwen/Controls/Dragger.cpp
Normal file
59
btgui/Gwen/Controls/Dragger.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/Dragger.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( Dragger )
|
||||
{
|
||||
m_pTarget = NULL;
|
||||
SetMouseInputEnabled( true );
|
||||
m_bDepressed = false;
|
||||
}
|
||||
|
||||
void Dragger::OnMouseClickLeft( int x, int y, bool bDown )
|
||||
{
|
||||
if ( !m_pTarget ) return;
|
||||
|
||||
if ( bDown )
|
||||
{
|
||||
m_bDepressed = true;
|
||||
m_HoldPos = m_pTarget->CanvasPosToLocal( Gwen::Point( x, y ) );
|
||||
Gwen::MouseFocus = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bDepressed = false;
|
||||
|
||||
Gwen::MouseFocus = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Dragger::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
|
||||
{
|
||||
if ( !m_pTarget ) return;
|
||||
if ( !m_bDepressed ) return;
|
||||
|
||||
Gwen::Point p = Gwen::Point( x - m_HoldPos.x, y - m_HoldPos.y );
|
||||
|
||||
// Translate to parent
|
||||
if ( m_pTarget->GetParent() )
|
||||
p = m_pTarget->GetParent()->CanvasPosToLocal( p );
|
||||
|
||||
//m_pTarget->SetPosition( p.x, p.y );
|
||||
m_pTarget->MoveTo( p.x, p.y );
|
||||
onDragged.Call( this );
|
||||
}
|
||||
|
||||
void Dragger::Render( Skin::Base* /*skin*/ )
|
||||
{
|
||||
//skin->DrawButton(this,false,false);
|
||||
}
|
43
btgui/Gwen/Controls/Dragger.h
Normal file
43
btgui/Gwen/Controls/Dragger.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_DRAGGER_H
|
||||
#define GWEN_CONTROLS_DRAGGER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace ControlsInternal
|
||||
{
|
||||
class GWEN_EXPORT Dragger : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( Dragger, Controls::Base );
|
||||
|
||||
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
|
||||
|
||||
virtual void OnMouseClickLeft( int x, int y, bool bDown );
|
||||
virtual void Render( Skin::Base* skin );
|
||||
|
||||
virtual void SetTarget( Controls::Base* pBase ){ m_pTarget = pBase; }
|
||||
|
||||
Gwen::Event::Caller onDragged;
|
||||
|
||||
protected:
|
||||
|
||||
bool m_bDepressed;
|
||||
Gwen::Point m_HoldPos;
|
||||
Controls::Base* m_pTarget;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
42
btgui/Gwen/Controls/GroupBox.cpp
Normal file
42
btgui/Gwen/Controls/GroupBox.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/GroupBox.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( GroupBox )
|
||||
{
|
||||
// Set to true, because it's likely that our
|
||||
// children will want mouse input, and they
|
||||
// can't get it without us..
|
||||
SetMouseInputEnabled( true );
|
||||
|
||||
SetTextPadding( Padding( 10, 0, 0, 0 ) );
|
||||
|
||||
SetAlignment( Pos::Top | Pos::Left );
|
||||
Invalidate();
|
||||
|
||||
m_InnerPanel = new Base( this );
|
||||
m_InnerPanel->Dock( Pos::Fill );
|
||||
|
||||
}
|
||||
|
||||
void GroupBox::Layout( Skin::Base* skin )
|
||||
{
|
||||
m_InnerPanel->SetMargin( Margin( TextHeight() + 3, 6, 6, 6 ) );
|
||||
|
||||
BaseClass::Layout( skin );
|
||||
}
|
||||
|
||||
|
||||
void GroupBox::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawGroupBox( this, TextX(), TextHeight(), TextWidth() );
|
||||
}
|
34
btgui/Gwen/Controls/GroupBox.h
Normal file
34
btgui/Gwen/Controls/GroupBox.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_GROUPBOX_H
|
||||
#define GWEN_CONTROLS_GROUPBOX_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
|
||||
class GWEN_EXPORT GroupBox : public Label
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( GroupBox, Label );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
172
btgui/Gwen/Controls/HSVColorPicker.cpp
Normal file
172
btgui/Gwen/Controls/HSVColorPicker.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/HSVColorPicker.h"
|
||||
#include "Gwen/Controls/ColorControls.h"
|
||||
#include "Gwen/Controls/ColorPicker.h"
|
||||
#include "Gwen/Controls/TextBox.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Controls/PanelListPanel.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( HSVColorPicker )
|
||||
{
|
||||
SetMouseInputEnabled( true );
|
||||
SetSize( 256, 128 );
|
||||
SetCacheToTexture();
|
||||
|
||||
m_LerpBox = new Gwen::Controls::ColorLerpBox( this );
|
||||
m_LerpBox->onSelectionChanged.Add( this, &HSVColorPicker::ColorBoxChanged );
|
||||
m_LerpBox->SetPos( 5, 5 );
|
||||
|
||||
m_ColorSlider = new Gwen::Controls::ColorSlider( this );
|
||||
m_ColorSlider->SetPos( m_LerpBox->Width() + 15, 5 );
|
||||
m_ColorSlider->onSelectionChanged.Add( this, &HSVColorPicker::ColorSliderChanged );
|
||||
|
||||
m_After = new Gwen::ControlsInternal::ColorDisplay( this );
|
||||
m_After->SetSize( 48, 24 );
|
||||
m_After->SetPos( m_ColorSlider->X() + m_ColorSlider->Width() + 15, 5 );
|
||||
|
||||
m_Before = new Gwen::ControlsInternal::ColorDisplay( this );
|
||||
m_Before->SetSize( 48, 24 );
|
||||
m_Before->SetPos( m_After->X(), 28 );
|
||||
|
||||
int x = m_Before->X();
|
||||
int y = m_Before->Y() + 30;
|
||||
|
||||
|
||||
{
|
||||
Label* label = new Label( this );
|
||||
label->SetText(L"R:");
|
||||
label->SizeToContents();
|
||||
label->SetPos( x, y );
|
||||
|
||||
TextBoxNumeric* numeric = new TextBoxNumeric( this );
|
||||
numeric->SetName( "RedBox" );
|
||||
numeric->SetPos( x + 15, y -1 );
|
||||
numeric->SetSize( 26, 16 );
|
||||
numeric->SetSelectAllOnFocus( true );
|
||||
numeric->onTextChanged.Add( this, &HSVColorPicker::NumericTyped );
|
||||
|
||||
}
|
||||
|
||||
y+= 20;
|
||||
|
||||
{
|
||||
Label* label = new Label( this );
|
||||
label->SetText(L"G:");
|
||||
label->SizeToContents();
|
||||
label->SetPos( x, y );
|
||||
|
||||
|
||||
TextBoxNumeric* numeric = new TextBoxNumeric( this );
|
||||
numeric->SetName( "GreenBox" );
|
||||
numeric->SetPos( x + 15, y -1 );
|
||||
numeric->SetSize( 26, 16 );
|
||||
numeric->SetSelectAllOnFocus( true );
|
||||
numeric->onTextChanged.Add( this, &HSVColorPicker::NumericTyped );
|
||||
}
|
||||
|
||||
y+= 20;
|
||||
|
||||
{
|
||||
Label* label = new Label( this );
|
||||
label->SetText(L"B:");
|
||||
label->SizeToContents();
|
||||
label->SetPos( x, y );
|
||||
|
||||
|
||||
TextBoxNumeric* numeric = new TextBoxNumeric( this );
|
||||
numeric->SetName( "BlueBox" );
|
||||
numeric->SetPos( x + 15, y -1 );
|
||||
numeric->SetSize( 26, 16 );
|
||||
numeric->SetSelectAllOnFocus( true );
|
||||
numeric->onTextChanged.Add( this, &HSVColorPicker::NumericTyped );
|
||||
}
|
||||
}
|
||||
|
||||
void HSVColorPicker::NumericTyped( Gwen::Controls::Base* control )
|
||||
{
|
||||
TextBoxNumeric* box = control->DynamicCastTextBoxNumeric();
|
||||
if ( !box ) return;
|
||||
|
||||
if ( box->GetText() == L"" ) return;
|
||||
|
||||
int textValue = atoi( Gwen::Utility::UnicodeToString( box->GetText()).c_str() );
|
||||
if ( textValue < 0 ) textValue = 0;
|
||||
if ( textValue > 255 ) textValue = 255;
|
||||
|
||||
Gwen::Color newColor = GetColor();
|
||||
|
||||
if ( box->GetName().find( "Red" ) != Gwen::String::npos )
|
||||
{
|
||||
newColor.r = textValue;
|
||||
}
|
||||
else if ( box->GetName().find( "Green" ) != Gwen::String::npos )
|
||||
{
|
||||
newColor.g = textValue;
|
||||
}
|
||||
else if ( box->GetName().find( "Blue" ) != Gwen::String::npos )
|
||||
{
|
||||
newColor.b = textValue;
|
||||
}
|
||||
else if ( box->GetName().find( "Alpha" ) != Gwen::String::npos )
|
||||
{
|
||||
newColor.a = textValue;
|
||||
}
|
||||
|
||||
SetColor( newColor );
|
||||
}
|
||||
|
||||
void HSVColorPicker::UpdateControls(Gwen::Color color)
|
||||
{
|
||||
TextBoxNumeric* redBox = FindChildByName( "RedBox", false )->DynamicCastTextBoxNumeric();
|
||||
if ( redBox ) redBox->SetText( Gwen::Utility::ToString( (int)color.r), false );
|
||||
|
||||
TextBoxNumeric* greenBox = FindChildByName( "GreenBox", false )->DynamicCastTextBoxNumeric();
|
||||
if ( greenBox ) greenBox->SetText( Gwen::Utility::ToString( (int)color.g ), false );
|
||||
|
||||
TextBoxNumeric* blueBox = FindChildByName( "BlueBox", false )->DynamicCastTextBoxNumeric();
|
||||
if ( blueBox ) blueBox->SetText( Gwen::Utility::ToString( (int)color.b ), false );
|
||||
|
||||
m_After->SetColor( color );
|
||||
}
|
||||
void HSVColorPicker::SetColor( Gwen::Color color, bool onlyHue, bool reset )
|
||||
{
|
||||
|
||||
UpdateControls( color );
|
||||
|
||||
|
||||
if ( reset )
|
||||
m_Before->SetColor( color );
|
||||
|
||||
m_ColorSlider->SetColor( color );
|
||||
m_LerpBox->SetColor( color, onlyHue );
|
||||
m_After->SetColor( color );
|
||||
}
|
||||
|
||||
Gwen::Color HSVColorPicker::GetColor()
|
||||
{
|
||||
return m_LerpBox->GetSelectedColor();
|
||||
}
|
||||
|
||||
void HSVColorPicker::ColorBoxChanged( Gwen::Controls::Base* /*pControl*/ )
|
||||
{
|
||||
onColorChanged.Call( this );
|
||||
UpdateControls( GetColor() );
|
||||
Invalidate();
|
||||
}
|
||||
void HSVColorPicker::ColorSliderChanged( Gwen::Controls::Base* /*pControl*/ )
|
||||
{
|
||||
if ( m_LerpBox )
|
||||
m_LerpBox->SetColor( m_ColorSlider->GetSelectedColor(), true );
|
||||
Invalidate();
|
||||
}
|
47
btgui/Gwen/Controls/HSVColorPicker.h
Normal file
47
btgui/Gwen/Controls/HSVColorPicker.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_HSVCOLORPICKER_H
|
||||
#define GWEN_CONTROLS_HSVCOLORPICKER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/ColorControls.h"
|
||||
#include "Gwen/Controls/ColorPicker.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT HSVColorPicker : public Controls::Base
|
||||
{
|
||||
public:
|
||||
GWEN_CONTROL( HSVColorPicker, Controls::Base );
|
||||
|
||||
Gwen::Color GetColor();
|
||||
Gwen::Color GetDefaultColor() { return m_Before->GetColor(); }
|
||||
void SetColor( Gwen::Color color, bool onlyHue = false, bool reset = false );
|
||||
|
||||
void ColorBoxChanged( Gwen::Controls::Base* pControl );
|
||||
void ColorSliderChanged( Gwen::Controls::Base* pControl );
|
||||
void NumericTyped( Gwen::Controls::Base* control );
|
||||
|
||||
void UpdateControls( Gwen::Color newColor );
|
||||
|
||||
Event::Caller onColorChanged;
|
||||
|
||||
protected:
|
||||
ColorLerpBox* m_LerpBox;
|
||||
ColorSlider* m_ColorSlider;
|
||||
ControlsInternal::ColorDisplay* m_Before;
|
||||
ControlsInternal::ColorDisplay* m_After;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
36
btgui/Gwen/Controls/Highlight.h
Normal file
36
btgui/Gwen/Controls/Highlight.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_HIGHLIGHT_H
|
||||
#define GWEN_CONTROLS_HIGHLIGHT_H
|
||||
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace ControlsInternal
|
||||
{
|
||||
class GWEN_EXPORT Highlight : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( Highlight, Controls::Base )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawHighlight( this );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
136
btgui/Gwen/Controls/HorizontalScrollBar.cpp
Normal file
136
btgui/Gwen/Controls/HorizontalScrollBar.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ScrollBar.h"
|
||||
#include "Gwen/Controls/HorizontalScrollBar.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( HorizontalScrollBar )
|
||||
{
|
||||
m_Bar->SetHorizontal();
|
||||
|
||||
m_ScrollButton[SCROLL_BUTTON_LEFT]->SetDirectionLeft();
|
||||
m_ScrollButton[SCROLL_BUTTON_LEFT]->onPress.Add( this, &HorizontalScrollBar::NudgeLeft );
|
||||
|
||||
m_ScrollButton[SCROLL_BUTTON_RIGHT]->SetDirectionRight();
|
||||
m_ScrollButton[SCROLL_BUTTON_RIGHT]->onPress.Add( this, &HorizontalScrollBar::NudgeRight );
|
||||
|
||||
m_Bar->onDragged.Add( this, &HorizontalScrollBar::OnBarMoved );
|
||||
}
|
||||
|
||||
void HorizontalScrollBar::Layout( Skin::Base* skin )
|
||||
{
|
||||
BaseClass::Layout( skin );
|
||||
|
||||
m_ScrollButton[SCROLL_BUTTON_LEFT]->SetWidth( Height() );
|
||||
m_ScrollButton[SCROLL_BUTTON_LEFT]->Dock(Pos::Left);
|
||||
|
||||
m_ScrollButton[SCROLL_BUTTON_RIGHT]->SetWidth( Height() );
|
||||
m_ScrollButton[SCROLL_BUTTON_RIGHT]->Dock(Pos::Right);
|
||||
|
||||
m_Bar->SetHeight( GetButtonSize() );
|
||||
m_Bar->SetPadding( Padding( GetButtonSize(), 0, GetButtonSize(), 0 ) );
|
||||
|
||||
float barWidth = (m_fViewableContentSize / m_fContentSize) * (Width() - (GetButtonSize() * 2));
|
||||
|
||||
if ( barWidth < GetButtonSize() * 0.5 )
|
||||
barWidth = GetButtonSize() * 0.5;
|
||||
|
||||
m_Bar->SetWidth(barWidth);
|
||||
m_Bar->SetHidden( Width() - (GetButtonSize() * 2) <= barWidth );
|
||||
|
||||
//Based on our last scroll amount, produce a position for the bar
|
||||
if ( !m_Bar->IsDepressed() )
|
||||
{
|
||||
SetScrolledAmount( GetScrolledAmount(), true );
|
||||
}
|
||||
}
|
||||
|
||||
void HorizontalScrollBar::NudgeLeft( Base* /*control*/ )
|
||||
{
|
||||
if ( !IsDisabled() )
|
||||
SetScrolledAmount( GetScrolledAmount() - GetNudgeAmount(), true);
|
||||
}
|
||||
|
||||
void HorizontalScrollBar::NudgeRight( Base* /*control*/ )
|
||||
{
|
||||
if ( !IsDisabled() )
|
||||
SetScrolledAmount( GetScrolledAmount() + GetNudgeAmount(), true);
|
||||
}
|
||||
|
||||
void HorizontalScrollBar::ScrollToLeft()
|
||||
{
|
||||
SetScrolledAmount( 0, true);
|
||||
}
|
||||
void HorizontalScrollBar::ScrollToRight()
|
||||
{
|
||||
SetScrolledAmount( 1, true);
|
||||
}
|
||||
|
||||
float HorizontalScrollBar::GetNudgeAmount()
|
||||
{
|
||||
if ( m_bDepressed )
|
||||
return m_fViewableContentSize / m_fContentSize;
|
||||
else
|
||||
return BaseClass::GetNudgeAmount();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void HorizontalScrollBar::OnMouseClickLeft( int x, int y, bool bDown )
|
||||
{
|
||||
if ( bDown )
|
||||
{
|
||||
m_bDepressed = true;
|
||||
Gwen::MouseFocus = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
Gwen::Point clickPos = CanvasPosToLocal( Gwen::Point( x, y ) );
|
||||
if ( clickPos.x < m_Bar->X() )
|
||||
NudgeLeft( this );
|
||||
else if ( clickPos.x > m_Bar->X() + m_Bar->Width() )
|
||||
NudgeRight( this );
|
||||
|
||||
m_bDepressed = false;
|
||||
Gwen::MouseFocus = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
float HorizontalScrollBar::CalculateScrolledAmount()
|
||||
{
|
||||
return (float)(m_Bar->X() - GetButtonSize()) / (float)(Width() - m_Bar->Width() - (GetButtonSize() * 2 ));
|
||||
}
|
||||
|
||||
bool HorizontalScrollBar::SetScrolledAmount( float amount, bool forceUpdate )
|
||||
{
|
||||
amount = Gwen::Clamp( amount, 0, 1 );
|
||||
|
||||
if ( !BaseClass::SetScrolledAmount( amount, forceUpdate ) )
|
||||
return false;
|
||||
|
||||
if ( forceUpdate )
|
||||
{
|
||||
int newX = GetButtonSize() + (amount * ((Width() - m_Bar->Width()) - (GetButtonSize()*2)));
|
||||
m_Bar->MoveTo( newX, m_Bar->Y() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HorizontalScrollBar::OnBarMoved( Controls::Base* control )
|
||||
{
|
||||
if ( m_Bar->IsDepressed() )
|
||||
{
|
||||
SetScrolledAmount( CalculateScrolledAmount(), false );
|
||||
BaseClass::OnBarMoved(control);
|
||||
}
|
||||
else
|
||||
InvalidateParent();
|
||||
}
|
49
btgui/Gwen/Controls/HorizontalScrollBar.h
Normal file
49
btgui/Gwen/Controls/HorizontalScrollBar.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_HORIZONTALSCROLLBAR_H
|
||||
#define GWEN_CONTROLS_HORIZONTALSCROLLBAR_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/Dragger.h"
|
||||
#include "Gwen/Controls/ScrollBar.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT HorizontalScrollBar : public BaseScrollBar
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( HorizontalScrollBar, BaseScrollBar );
|
||||
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
|
||||
virtual void OnMouseClickLeft( int x, int y, bool bDown );
|
||||
virtual void OnBarMoved( Controls::Base* control );
|
||||
|
||||
virtual int GetBarSize() { return m_Bar->Width(); }
|
||||
virtual int GetBarPos() { return m_Bar->X() - Height(); }
|
||||
virtual void SetBarSize( int size ) { m_Bar->SetWidth( size ); }
|
||||
virtual int GetButtonSize() { return Height(); }
|
||||
|
||||
virtual void ScrollToLeft();
|
||||
virtual void ScrollToRight();
|
||||
virtual void NudgeLeft( Base* control );
|
||||
virtual void NudgeRight( Base* control );
|
||||
virtual float GetNudgeAmount();
|
||||
|
||||
virtual float CalculateScrolledAmount();
|
||||
virtual bool SetScrolledAmount(float amount, bool forceUpdate);
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
45
btgui/Gwen/Controls/HorizontalSlider.cpp
Normal file
45
btgui/Gwen/Controls/HorizontalSlider.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/Slider.h"
|
||||
#include "Gwen/Controls/HorizontalSlider.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( HorizontalSlider )
|
||||
{
|
||||
}
|
||||
|
||||
float HorizontalSlider::CalculateValue()
|
||||
{
|
||||
return (float)m_SliderBar->X() / (float)( Width() - m_SliderBar->Width() );
|
||||
}
|
||||
|
||||
void HorizontalSlider::UpdateBarFromValue()
|
||||
{
|
||||
m_SliderBar->MoveTo( ( Width() - m_SliderBar->Width() ) * ( m_fValue ), m_SliderBar->Y() );
|
||||
}
|
||||
|
||||
void HorizontalSlider::OnMouseClickLeft( int x, int y, bool bDown )
|
||||
{
|
||||
m_SliderBar->MoveTo( CanvasPosToLocal( Gwen::Point( x, y ) ).x - m_SliderBar->Width() * 0.5, m_SliderBar->Y() );
|
||||
m_SliderBar->OnMouseClickLeft( x, y, bDown );
|
||||
OnMoved( m_SliderBar );
|
||||
}
|
||||
|
||||
void HorizontalSlider::Layout(Skin::Base* /*skin*/)
|
||||
{
|
||||
m_SliderBar->SetSize( 10, Height() );
|
||||
}
|
||||
|
||||
void HorizontalSlider::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawSlider( this, true, m_bClampToNotches ? m_iNumNotches : 0, m_SliderBar->Width() );
|
||||
}
|
35
btgui/Gwen/Controls/HorizontalSlider.h
Normal file
35
btgui/Gwen/Controls/HorizontalSlider.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_HORIZONTALSLIDER_H
|
||||
#define GWEN_CONTROLS_HORIZONTALSLIDER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Controls/Dragger.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/Slider.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT HorizontalSlider : public Slider
|
||||
{
|
||||
GWEN_CONTROL( HorizontalSlider, Slider );
|
||||
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
virtual void Render( Skin::Base* skin );
|
||||
|
||||
virtual float CalculateValue();
|
||||
virtual void UpdateBarFromValue();
|
||||
virtual void OnMouseClickLeft( int x, int y, bool bDown );
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
8
btgui/Gwen/Controls/ImagePanel.cpp
Normal file
8
btgui/Gwen/Controls/ImagePanel.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ImagePanel.h"
|
78
btgui/Gwen/Controls/ImagePanel.h
Normal file
78
btgui/Gwen/Controls/ImagePanel.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_IMAGEPANEL_H
|
||||
#define GWEN_CONTROLS_IMAGEPANEL_H
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Texture.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT ImagePanel : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( ImagePanel, Controls::Base )
|
||||
{
|
||||
SetUV( 0, 0, 1, 1 );
|
||||
SetMouseInputEnabled( false );
|
||||
m_DrawColor = Colors::White;
|
||||
}
|
||||
|
||||
virtual ~ImagePanel()
|
||||
{
|
||||
m_Texture.Release( GetSkin()->GetRender() );
|
||||
}
|
||||
|
||||
|
||||
virtual void SetUV( float u1, float v1, float u2, float v2 )
|
||||
{
|
||||
m_uv[0] = u1;
|
||||
m_uv[1] = v1;
|
||||
m_uv[2] = u2;
|
||||
m_uv[3] = v2;
|
||||
}
|
||||
|
||||
virtual void SetImage( const TextObject& imageName )
|
||||
{
|
||||
m_Texture.Load( imageName, GetSkin()->GetRender() );
|
||||
}
|
||||
|
||||
virtual const TextObject& GetImageName()
|
||||
{
|
||||
return m_Texture.name;
|
||||
}
|
||||
|
||||
virtual void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->GetRender()->SetDrawColor( m_DrawColor );
|
||||
skin->GetRender()->DrawTexturedRect( &m_Texture, GetRenderBounds(), m_uv[0], m_uv[1], m_uv[2], m_uv[3] );
|
||||
}
|
||||
|
||||
virtual void SizeToContents()
|
||||
{
|
||||
SetSize( m_Texture.width, m_Texture.height );
|
||||
}
|
||||
|
||||
virtual void SetDrawColor( Gwen::Color& color )
|
||||
{
|
||||
m_DrawColor = color;
|
||||
}
|
||||
|
||||
Texture m_Texture;
|
||||
float m_uv[4];
|
||||
Gwen::Color m_DrawColor;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
75
btgui/Gwen/Controls/Label.cpp
Normal file
75
btgui/Gwen/Controls/Label.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( Label )
|
||||
{
|
||||
m_Text = new ControlsInternal::Text( this );
|
||||
m_Text->SetFont( GetSkin()->GetDefaultFont() );
|
||||
|
||||
SetMouseInputEnabled( false );
|
||||
SetBounds( 0, 0, 100, 10 );
|
||||
SetAlignment( Gwen::Pos::Left | Gwen::Pos::Top );
|
||||
}
|
||||
|
||||
void Label::Layout( Skin::Base* /*skin*/ )
|
||||
{
|
||||
|
||||
int iAlign = m_iAlign;
|
||||
|
||||
int x = m_rTextPadding.left + m_Padding.left;
|
||||
int y = m_rTextPadding.top + m_Padding.top;
|
||||
|
||||
if ( iAlign & Pos::Right ) x = Width() - m_Text->Width() - m_rTextPadding.right - m_Padding.right;
|
||||
if ( iAlign & Pos::CenterH ) x = (m_rTextPadding.left + m_Padding.left) + ((Width() - m_Text->Width() ) * 0.5f) - m_rTextPadding.right - m_Padding.right;
|
||||
|
||||
if ( iAlign & Pos::CenterV ) y = (m_rTextPadding.top + m_Padding.top) + ((Height() - m_Text->Height()) * 0.5f) - m_rTextPadding.bottom - m_Padding.bottom;
|
||||
if ( iAlign & Pos::Bottom ) y = Height() - m_Text->Height() - m_rTextPadding.bottom - m_Padding.bottom;
|
||||
|
||||
m_Text->SetPos( x, y );
|
||||
|
||||
}
|
||||
|
||||
void Label::SetText( const UnicodeString& str, bool bDoEvents )
|
||||
{
|
||||
if ( m_Text->GetText() == str ) return;
|
||||
|
||||
m_Text->SetString( str );
|
||||
Redraw();
|
||||
|
||||
if ( bDoEvents )
|
||||
OnTextChanged();
|
||||
}
|
||||
|
||||
void Label::SetText( const String& str, bool bDoEvents )
|
||||
{
|
||||
SetText( Gwen::Utility::StringToUnicode( str ), bDoEvents );
|
||||
}
|
||||
|
||||
void Label::SizeToContents()
|
||||
{
|
||||
m_Text->SetPos( m_rTextPadding.left + m_Padding.left, m_rTextPadding.top + m_Padding.top );
|
||||
m_Text->RefreshSize();
|
||||
|
||||
SetSize( m_Text->Width() + m_Padding.left + m_Padding.right + m_rTextPadding.left + m_rTextPadding.right, m_Text->Height() + m_Padding.top + m_Padding.bottom + m_rTextPadding.top + m_rTextPadding.bottom );
|
||||
|
||||
}
|
||||
|
||||
Gwen::Point Label::GetCharacterPosition( int iChar )
|
||||
{
|
||||
Gwen::Point p = m_Text->GetCharacterPosition( iChar );
|
||||
p.x += m_Text->X();
|
||||
p.y += m_Text->Y();
|
||||
|
||||
return p;
|
||||
}
|
70
btgui/Gwen/Controls/Label.h
Normal file
70
btgui/Gwen/Controls/Label.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_LABEL_H
|
||||
#define GWEN_CONTROLS_LABEL_H
|
||||
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Text.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT Label : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( Label, Controls::Base );
|
||||
|
||||
virtual void SetText( const UnicodeString& str, bool bDoEvents = true );
|
||||
virtual void SetText( const String& str, bool bDoEvents = true );
|
||||
|
||||
virtual const UnicodeString& GetText() const { return m_Text->GetText(); }
|
||||
|
||||
virtual void Render( Skin::Base* /*skin*/ ){}
|
||||
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
|
||||
virtual void SizeToContents();
|
||||
|
||||
virtual void SetAlignment( int iAlign ){ m_iAlign = iAlign; }
|
||||
|
||||
virtual void SetFont( Gwen::Font* pFont ){ m_Text->SetFont( pFont ); }
|
||||
virtual Gwen::Font* GetFont(){ return m_Text->GetFont(); }
|
||||
virtual void SetTextColor( const Gwen::Color& col ){ m_Text->SetTextColor( col ); }
|
||||
inline const Gwen::Color &TextColor() const { return m_Text->TextColor(); }
|
||||
|
||||
virtual int TextWidth() { return m_Text->Width(); }
|
||||
virtual int TextRight() { return m_Text->Right(); }
|
||||
virtual int TextHeight() { return m_Text->Height(); }
|
||||
virtual int TextX() { return m_Text->X(); }
|
||||
virtual int TextY() { return m_Text->Y(); }
|
||||
virtual int TextLength() { return m_Text->Length(); }
|
||||
|
||||
Gwen::Point GetCharacterPosition( int iChar );
|
||||
|
||||
virtual void SetTextPadding( const Padding& padding ){ m_rTextPadding = padding; Invalidate(); InvalidateParent(); }
|
||||
virtual const Padding& GetTextPadding(){ return m_rTextPadding; }
|
||||
|
||||
virtual Gwen::UnicodeString GetText() { return m_Text->GetText(); }
|
||||
|
||||
inline int Alignment() const { return m_iAlign; }
|
||||
protected:
|
||||
|
||||
virtual void OnTextChanged(){};
|
||||
|
||||
Padding m_rTextPadding;
|
||||
ControlsInternal::Text* m_Text;
|
||||
int m_iAlign;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
25
btgui/Gwen/Controls/LabelClickable.cpp
Normal file
25
btgui/Gwen/Controls/LabelClickable.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/LabelClickable.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( LabelClickable )
|
||||
{
|
||||
SetIsToggle( false );
|
||||
|
||||
SetAlignment( Gwen::Pos::Left | Gwen::Pos::CenterV );
|
||||
}
|
||||
|
||||
void LabelClickable::Render( Skin::Base* /*skin*/ )
|
||||
{
|
||||
//skin->DrawButton( this, IsDepressed(), IsToggle() && GetToggleState() );
|
||||
}
|
29
btgui/Gwen/Controls/LabelClickable.h
Normal file
29
btgui/Gwen/Controls/LabelClickable.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_LABELCLICKABLE_H
|
||||
#define GWEN_CONTROLS_LABELCLICKABLE_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT LabelClickable : public Button
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( LabelClickable, Button );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
83
btgui/Gwen/Controls/Layout/Splitter (2).h
Normal file
83
btgui/Gwen/Controls/Layout/Splitter (2).h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2011 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#pragma once
|
||||
#include "Gwen/Controls/Base.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Layout
|
||||
{
|
||||
|
||||
class Splitter : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Base BaseClass;
|
||||
|
||||
Splitter( Base* pParent ) : BaseClass( pParent )
|
||||
{
|
||||
for ( int i=0; i<2; i++ )
|
||||
m_pPanel[i] = NULL;
|
||||
}
|
||||
|
||||
void SetPanel( int i, Base* pPanel )
|
||||
{
|
||||
if ( i < 0 || i > 1 ) return;
|
||||
|
||||
m_pPanel[i] = pPanel;
|
||||
|
||||
if ( m_pPanel[i] )
|
||||
{
|
||||
m_pPanel[i] ->SetParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
Base* GetPanel( int i ) const
|
||||
{
|
||||
if ( i < 0 || i > 1 ) return NULL;
|
||||
return m_pPanel[i];
|
||||
}
|
||||
|
||||
void Layout( Skin::Base* skin )
|
||||
{
|
||||
LayoutVertical( skin );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void LayoutVertical( Skin::Base* skin )
|
||||
{
|
||||
int w = Width();
|
||||
int h = Height();
|
||||
|
||||
if ( m_pPanel[0] )
|
||||
{
|
||||
const Margin& m = m_pPanel[0]->GetMargin();
|
||||
m_pPanel[0]->SetBounds( m.left, m.top, w-m.left-m.right, (h * 0.5) - m.top - m.bottom );
|
||||
}
|
||||
|
||||
if ( m_pPanel[1] )
|
||||
{
|
||||
const Margin& m = m_pPanel[1]->GetMargin();
|
||||
m_pPanel[1]->SetBounds( m.left, m.top + (h * 0.5f), w-m.left-m.right, (h * 0.5f) - m.top - m.bottom );
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutHorizontal( Skin::Base* skin )
|
||||
{
|
||||
// Todo.
|
||||
}
|
||||
|
||||
Base* m_pPanel[2];
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
87
btgui/Gwen/Controls/Layout/Splitter - Copy.h
Normal file
87
btgui/Gwen/Controls/Layout/Splitter - Copy.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_LAYOUT_SPLITTER_H
|
||||
#define GWEN_CONTROLS_LAYOUT_SPLITTER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Layout
|
||||
{
|
||||
|
||||
class GWEN_EXPORT Splitter : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Base BaseClass;
|
||||
|
||||
Splitter( Base* pParent ) : BaseClass( pParent )
|
||||
{
|
||||
for ( int i=0; i<2; i++ )
|
||||
m_pPanel[i] = NULL;
|
||||
}
|
||||
|
||||
void SetPanel( int i, Base* pPanel )
|
||||
{
|
||||
if ( i < 0 || i > 1 ) return;
|
||||
|
||||
m_pPanel[i] = pPanel;
|
||||
|
||||
if ( m_pPanel[i] )
|
||||
{
|
||||
m_pPanel[i] ->SetParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
Base* GetPanel( int i ) const
|
||||
{
|
||||
if ( i < 0 || i > 1 ) return NULL;
|
||||
return m_pPanel[i];
|
||||
}
|
||||
|
||||
void Layout( Skin::Base* skin )
|
||||
{
|
||||
LayoutVertical( skin );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void LayoutVertical( Skin::Base* /*skin*/ )
|
||||
{
|
||||
int w = Width();
|
||||
int h = Height();
|
||||
|
||||
if ( m_pPanel[0] )
|
||||
{
|
||||
const Margin& m = m_pPanel[0]->GetMargin();
|
||||
m_pPanel[0]->SetBounds( m.left, m.top, w-m.left-m.right, (h * 0.5) - m.top - m.bottom );
|
||||
}
|
||||
|
||||
if ( m_pPanel[1] )
|
||||
{
|
||||
const Margin& m = m_pPanel[1]->GetMargin();
|
||||
m_pPanel[1]->SetBounds( m.left, m.top + (h * 0.5f), w-m.left-m.right, (h * 0.5f) - m.top - m.bottom );
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutHorizontal( Skin::Base* /*skin*/ )
|
||||
{
|
||||
// Todo.
|
||||
}
|
||||
|
||||
Base* m_pPanel[2];
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
87
btgui/Gwen/Controls/Layout/Splitter.h
Normal file
87
btgui/Gwen/Controls/Layout/Splitter.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_LAYOUT_SPLITTER_H
|
||||
#define GWEN_CONTROLS_LAYOUT_SPLITTER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Layout
|
||||
{
|
||||
|
||||
class GWEN_EXPORT Splitter : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Base BaseClass;
|
||||
|
||||
Splitter( Base* pParent ) : BaseClass( pParent )
|
||||
{
|
||||
for ( int i=0; i<2; i++ )
|
||||
m_pPanel[i] = NULL;
|
||||
}
|
||||
|
||||
void SetPanel( int i, Base* pPanel )
|
||||
{
|
||||
if ( i < 0 || i > 1 ) return;
|
||||
|
||||
m_pPanel[i] = pPanel;
|
||||
|
||||
if ( m_pPanel[i] )
|
||||
{
|
||||
m_pPanel[i] ->SetParent( this );
|
||||
}
|
||||
}
|
||||
|
||||
Base* GetPanel( int i ) const
|
||||
{
|
||||
if ( i < 0 || i > 1 ) return NULL;
|
||||
return m_pPanel[i];
|
||||
}
|
||||
|
||||
void Layout( Skin::Base* skin )
|
||||
{
|
||||
LayoutVertical( skin );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void LayoutVertical( Skin::Base* /*skin*/ )
|
||||
{
|
||||
int w = Width();
|
||||
int h = Height();
|
||||
|
||||
if ( m_pPanel[0] )
|
||||
{
|
||||
const Margin& m = m_pPanel[0]->GetMargin();
|
||||
m_pPanel[0]->SetBounds( m.left, m.top, w-m.left-m.right, (h * 0.5) - m.top - m.bottom );
|
||||
}
|
||||
|
||||
if ( m_pPanel[1] )
|
||||
{
|
||||
const Margin& m = m_pPanel[1]->GetMargin();
|
||||
m_pPanel[1]->SetBounds( m.left, m.top + (h * 0.5f), w-m.left-m.right, (h * 0.5f) - m.top - m.bottom );
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutHorizontal( Skin::Base* /*skin*/ )
|
||||
{
|
||||
// Todo.
|
||||
}
|
||||
|
||||
Base* m_pPanel[2];
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
264
btgui/Gwen/Controls/Layout/Table (2).h
Normal file
264
btgui/Gwen/Controls/Layout/Table (2).h
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2011 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#pragma once
|
||||
#include "Gwen/Controls/Label.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Layout
|
||||
{
|
||||
class Table;
|
||||
|
||||
class TableRow : public Base
|
||||
{
|
||||
static const int MaxColumns = 5;
|
||||
|
||||
GWEN_CONTROL_INLINE( TableRow, Base )
|
||||
{
|
||||
for ( int i=0; i<MaxColumns; i++ )
|
||||
m_Columns[i] = NULL;
|
||||
|
||||
m_ColumnCount = 0;
|
||||
}
|
||||
|
||||
void SetColumnCount( int iCount )
|
||||
{
|
||||
if ( iCount == m_ColumnCount ) return;
|
||||
|
||||
if ( iCount >= MaxColumns )
|
||||
m_ColumnCount = MaxColumns;
|
||||
|
||||
for ( int i=0; i<MaxColumns; i++ )
|
||||
{
|
||||
if ( i < iCount )
|
||||
{
|
||||
if ( !m_Columns[i] )
|
||||
{
|
||||
m_Columns[i] = new Label( this );
|
||||
m_Columns[i]->Dock( Pos::Left );
|
||||
m_Columns[i]->SetTextPadding( Gwen::Rect( 3, 3, 3, 3 ) );
|
||||
}
|
||||
}
|
||||
else if ( m_Columns[i] )
|
||||
{
|
||||
m_Columns[i]->DelayedDelete();
|
||||
m_Columns[i] = NULL;
|
||||
}
|
||||
|
||||
m_ColumnCount = iCount;
|
||||
}
|
||||
}
|
||||
|
||||
void SetColumnWidth( int i, int iWidth )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
if ( m_Columns[i]->Width() == iWidth ) return;
|
||||
|
||||
m_Columns[i]->SetWidth( iWidth );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SetCellText( int i, const T& strString )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
m_Columns[i]->SetText( strString );
|
||||
}
|
||||
|
||||
void SetCellContents( int i, Base* pControl, bool bEnableMouseInput = false )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
pControl->SetParent( m_Columns[i] );
|
||||
|
||||
m_Columns[i]->SetMouseInputEnabled( bEnableMouseInput );
|
||||
}
|
||||
|
||||
Label* GetCellContents( int i )
|
||||
{
|
||||
return m_Columns[i];
|
||||
}
|
||||
|
||||
void SizeToContents()
|
||||
{
|
||||
int iHeight = 0;
|
||||
|
||||
for ( int i=0; i<m_ColumnCount; i++ )
|
||||
{
|
||||
if ( !m_Columns[i] ) continue;
|
||||
|
||||
// Note, more than 1 child here, because the
|
||||
// label has a child built in ( The Text )
|
||||
if ( m_Columns[i]->NumChildren() > 1 )
|
||||
{
|
||||
m_Columns[i]->SizeToChildren();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Columns[i]->SizeToContents();
|
||||
}
|
||||
|
||||
iHeight = max( iHeight, m_Columns[i]->Height() );
|
||||
}
|
||||
|
||||
SetHeight( iHeight );
|
||||
}
|
||||
|
||||
void SetTextColor( const Gwen::Color& color )
|
||||
{
|
||||
for ( int i=0; i<m_ColumnCount; i++ )
|
||||
{
|
||||
if ( !m_Columns[i] ) continue;
|
||||
m_Columns[i]->SetTextColor( color );
|
||||
}
|
||||
}
|
||||
|
||||
//You might hate this. Actually I know you will
|
||||
virtual UnicodeString GetText( int i )
|
||||
{
|
||||
return m_Columns[i]->GetText();
|
||||
}
|
||||
virtual void SetSelected( bool b ) {}
|
||||
|
||||
private:
|
||||
|
||||
int m_ColumnCount;
|
||||
Label* m_Columns[MaxColumns];
|
||||
|
||||
friend class Table;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class Table : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( Table, Base )
|
||||
{
|
||||
m_iColumnCount = 1;
|
||||
m_iDefaultRowHeight = 22;
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
m_ColumnWidth[i] = 20 + rand()%100;
|
||||
}
|
||||
|
||||
|
||||
m_bSizeToContents = false;
|
||||
}
|
||||
|
||||
void SetColumnCount( int i )
|
||||
{
|
||||
if ( m_iColumnCount == i ) return;
|
||||
|
||||
for ( Base::List::iterator it = m_Children.begin(); it != m_Children.end(); ++it )
|
||||
{
|
||||
Base* el = *it;
|
||||
if (el->getType()!=TypeTableRow)
|
||||
continue;
|
||||
|
||||
TableRow* pRow = static_cast<TableRow*>(*it);
|
||||
|
||||
pRow->SetColumnCount( i );
|
||||
}
|
||||
|
||||
m_iColumnCount = i;
|
||||
}
|
||||
|
||||
void SetColumnWidth( int i, int iWidth )
|
||||
{
|
||||
if ( m_ColumnWidth[i] == iWidth ) return;
|
||||
|
||||
m_ColumnWidth[i] = iWidth;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
TableRow* AddRow()
|
||||
{
|
||||
TableRow* row = new TableRow( this );
|
||||
row->SetColumnCount( m_iColumnCount );
|
||||
row->SetHeight( m_iDefaultRowHeight );
|
||||
row->Dock( Pos::Top );
|
||||
return row;
|
||||
}
|
||||
|
||||
void AddRow( TableRow* pRow )
|
||||
{
|
||||
pRow->SetParent( this );
|
||||
pRow->SetColumnCount( m_iColumnCount );
|
||||
pRow->SetHeight( m_iDefaultRowHeight );
|
||||
pRow->Dock( Pos::Top );
|
||||
}
|
||||
|
||||
void Layout( Skin::Base* skin )
|
||||
{
|
||||
Debug::Msg( "TABLE LAYOUT\n" );
|
||||
BaseClass::Layout( skin );
|
||||
|
||||
if ( m_bSizeToContents )
|
||||
{
|
||||
DoSizeToContents();
|
||||
m_bSizeToContents = false;
|
||||
}
|
||||
|
||||
for ( Base::List::iterator it = m_Children.begin(); it != m_Children.end(); ++it )
|
||||
{
|
||||
TableRow* pRow = static_cast<TableRow*>(*it);
|
||||
if ( !pRow ) continue;
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns && i < m_iColumnCount; i++)
|
||||
{
|
||||
pRow->SetColumnWidth( i, m_ColumnWidth[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SizeToContents()
|
||||
{
|
||||
m_bSizeToContents = true;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void DoSizeToContents()
|
||||
{
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
m_ColumnWidth[i] = 10;
|
||||
}
|
||||
|
||||
for ( Base::List::iterator it = m_Children.begin(); it != m_Children.end(); ++it )
|
||||
{
|
||||
TableRow* pRow = static_cast<TableRow*>(*it);
|
||||
if ( !pRow ) continue;
|
||||
|
||||
pRow->SizeToContents();
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
if ( pRow->m_Columns[i] )
|
||||
{
|
||||
m_ColumnWidth[i] = max( m_ColumnWidth[i], pRow->m_Columns[i]->Width() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool m_bSizeToContents;
|
||||
int m_iColumnCount;
|
||||
int m_iDefaultRowHeight;
|
||||
|
||||
int m_ColumnWidth[ TableRow::MaxColumns ];
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
294
btgui/Gwen/Controls/Layout/Table - Copy.h
Normal file
294
btgui/Gwen/Controls/Layout/Table - Copy.h
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_LAYOUT_TABLE_H
|
||||
#define GWEN_CONTROLS_LAYOUT_TABLE_H
|
||||
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Layout
|
||||
{
|
||||
class Table;
|
||||
|
||||
class GWEN_EXPORT TableRow : public Base
|
||||
{
|
||||
static const int MaxColumns = 5;
|
||||
|
||||
GWEN_CONTROL_INLINE( TableRow, Base )
|
||||
{
|
||||
for ( int i=0; i<MaxColumns; i++ )
|
||||
m_Columns[i] = NULL;
|
||||
|
||||
m_ColumnCount = 0;
|
||||
}
|
||||
|
||||
void SetColumnCount( int iCount )
|
||||
{
|
||||
if ( iCount == m_ColumnCount ) return;
|
||||
|
||||
if ( iCount >= MaxColumns )
|
||||
m_ColumnCount = MaxColumns;
|
||||
|
||||
for ( int i=0; i<MaxColumns; i++ )
|
||||
{
|
||||
if ( i < iCount )
|
||||
{
|
||||
if ( !m_Columns[i] )
|
||||
{
|
||||
m_Columns[i] = new Label( this );
|
||||
m_Columns[i]->Dock( Pos::Left );
|
||||
m_Columns[i]->SetPadding( Padding( 3, 3, 3, 3 ) );
|
||||
}
|
||||
}
|
||||
else if ( m_Columns[i] )
|
||||
{
|
||||
m_Columns[i]->DelayedDelete();
|
||||
m_Columns[i] = NULL;
|
||||
}
|
||||
|
||||
m_ColumnCount = iCount;
|
||||
}
|
||||
}
|
||||
|
||||
void SetColumnWidth( int i, int iWidth )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
if ( m_Columns[i]->Width() == iWidth ) return;
|
||||
|
||||
m_Columns[i]->SetWidth( iWidth );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SetCellText( int i, const T& strString )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
m_Columns[i]->SetText( strString );
|
||||
}
|
||||
|
||||
void SetCellContents( int i, Base* pControl, bool bEnableMouseInput = false )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
pControl->SetParent( m_Columns[i] );
|
||||
|
||||
m_Columns[i]->SetMouseInputEnabled( bEnableMouseInput );
|
||||
}
|
||||
|
||||
Label* GetCellContents( int i )
|
||||
{
|
||||
return m_Columns[i];
|
||||
}
|
||||
|
||||
void SizeToContents()
|
||||
{
|
||||
int iHeight = 0;
|
||||
|
||||
for ( int i=0; i<m_ColumnCount; i++ )
|
||||
{
|
||||
if ( !m_Columns[i] ) continue;
|
||||
|
||||
// Note, more than 1 child here, because the
|
||||
// label has a child built in ( The Text )
|
||||
if ( m_Columns[i]->NumChildren() > 1 )
|
||||
{
|
||||
m_Columns[i]->SizeToChildren();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Columns[i]->SizeToContents();
|
||||
}
|
||||
|
||||
iHeight = Utility::Max( iHeight, m_Columns[i]->Height() );
|
||||
}
|
||||
|
||||
SetHeight( iHeight );
|
||||
}
|
||||
|
||||
void SetTextColor( const Gwen::Color& color )
|
||||
{
|
||||
for ( int i=0; i<m_ColumnCount; i++ )
|
||||
{
|
||||
if ( !m_Columns[i] ) continue;
|
||||
m_Columns[i]->SetTextColor( color );
|
||||
}
|
||||
}
|
||||
|
||||
//You might hate this. Actually I know you will
|
||||
virtual UnicodeString GetText( int i )
|
||||
{
|
||||
return m_Columns[i]->GetText();
|
||||
}
|
||||
virtual void SetSelected( bool /*b*/ ) {}
|
||||
|
||||
//
|
||||
// This is sometimes called by derivatives.
|
||||
//
|
||||
Gwen::Event::Caller onRowSelected;
|
||||
|
||||
private:
|
||||
|
||||
int m_ColumnCount;
|
||||
Label* m_Columns[MaxColumns];
|
||||
|
||||
friend class Table;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class GWEN_EXPORT Table : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( Table, Base )
|
||||
{
|
||||
m_iColumnCount = 1;
|
||||
m_iDefaultRowHeight = 22;
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
m_ColumnWidth[i] = 20;
|
||||
}
|
||||
|
||||
|
||||
m_bSizeToContents = false;
|
||||
}
|
||||
|
||||
void SetColumnCount( int i )
|
||||
{
|
||||
if ( m_iColumnCount == i ) return;
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
TableRow* pRow = static_cast<TableRow*>(*it);
|
||||
if ( !pRow ) continue;
|
||||
|
||||
pRow->SetColumnCount( i );
|
||||
}
|
||||
|
||||
m_iColumnCount = i;
|
||||
}
|
||||
|
||||
void SetColumnWidth( int i, int iWidth )
|
||||
{
|
||||
if ( m_ColumnWidth[i] == iWidth ) return;
|
||||
|
||||
m_ColumnWidth[i] = iWidth;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
TableRow* AddRow()
|
||||
{
|
||||
TableRow* row = new TableRow( this );
|
||||
row->SetColumnCount( m_iColumnCount );
|
||||
row->SetHeight( m_iDefaultRowHeight );
|
||||
row->Dock( Pos::Top );
|
||||
return row;
|
||||
}
|
||||
|
||||
void AddRow( TableRow* pRow )
|
||||
{
|
||||
pRow->SetParent( this );
|
||||
pRow->SetColumnCount( m_iColumnCount );
|
||||
pRow->SetHeight( m_iDefaultRowHeight );
|
||||
pRow->Dock( Pos::Top );
|
||||
}
|
||||
|
||||
void Remove( TableRow* pRow )
|
||||
{
|
||||
pRow->DelayedDelete();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
TableRow* pRow = static_cast<TableRow*>(*it);
|
||||
if ( !pRow ) continue;
|
||||
Remove( pRow );
|
||||
}
|
||||
}
|
||||
|
||||
void Layout( Skin::Base* skin )
|
||||
{
|
||||
BaseClass::Layout( skin );
|
||||
|
||||
if ( m_bSizeToContents )
|
||||
{
|
||||
DoSizeToContents();
|
||||
}
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
TableRow* pRow = static_cast<TableRow*>(*it);
|
||||
if ( !pRow ) continue;
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns && i < m_iColumnCount; i++)
|
||||
{
|
||||
pRow->SetColumnWidth( i, m_ColumnWidth[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PostLayout( Skin::Base* /*skin*/ )
|
||||
{
|
||||
if ( m_bSizeToContents )
|
||||
{
|
||||
SizeToChildren();
|
||||
m_bSizeToContents = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SizeToContents()
|
||||
{
|
||||
m_bSizeToContents = true;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void DoSizeToContents()
|
||||
{
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
m_ColumnWidth[i] = 10;
|
||||
}
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
TableRow* pRow = static_cast<TableRow*>(*it);
|
||||
if ( !pRow ) continue;
|
||||
|
||||
pRow->SizeToContents();
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
if ( pRow->m_Columns[i] )
|
||||
{
|
||||
m_ColumnWidth[i] = Utility::Max( m_ColumnWidth[i], pRow->m_Columns[i]->Width() );
|
||||
}
|
||||
}
|
||||
//iBottom += pRow->Height();
|
||||
}
|
||||
|
||||
InvalidateParent();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool m_bSizeToContents;
|
||||
int m_iColumnCount;
|
||||
int m_iDefaultRowHeight;
|
||||
|
||||
int m_ColumnWidth[ TableRow::MaxColumns ];
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
317
btgui/Gwen/Controls/Layout/Table.h
Normal file
317
btgui/Gwen/Controls/Layout/Table.h
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_LAYOUT_TABLE_H
|
||||
#define GWEN_CONTROLS_LAYOUT_TABLE_H
|
||||
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Layout
|
||||
{
|
||||
class Table;
|
||||
|
||||
class GWEN_EXPORT TableRow : public Base
|
||||
{
|
||||
static const int MaxColumns = 5;
|
||||
|
||||
GWEN_CONTROL_INLINE( TableRow, Base )
|
||||
{
|
||||
for ( int i=0; i<MaxColumns; i++ )
|
||||
m_Columns[i] = NULL;
|
||||
|
||||
m_ColumnCount = 0;
|
||||
}
|
||||
|
||||
virtual class TableRow* DynamicCastLayoutTableRow()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
virtual const class TableRow* DynamicCastLayoutTableRow() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
void SetColumnCount( int iCount )
|
||||
{
|
||||
if ( iCount == m_ColumnCount ) return;
|
||||
|
||||
if ( iCount >= MaxColumns )
|
||||
m_ColumnCount = MaxColumns;
|
||||
|
||||
for ( int i=0; i<MaxColumns; i++ )
|
||||
{
|
||||
if ( i < iCount )
|
||||
{
|
||||
if ( !m_Columns[i] )
|
||||
{
|
||||
m_Columns[i] = new Label( this );
|
||||
m_Columns[i]->Dock( Pos::Left );
|
||||
m_Columns[i]->SetPadding( Padding( 3, 3, 3, 3 ) );
|
||||
}
|
||||
}
|
||||
else if ( m_Columns[i] )
|
||||
{
|
||||
m_Columns[i]->DelayedDelete();
|
||||
m_Columns[i] = NULL;
|
||||
}
|
||||
|
||||
m_ColumnCount = iCount;
|
||||
}
|
||||
}
|
||||
|
||||
void SetColumnWidth( int i, int iWidth )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
if ( m_Columns[i]->Width() == iWidth ) return;
|
||||
|
||||
m_Columns[i]->SetWidth( iWidth );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SetCellText( int i, const T& strString )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
m_Columns[i]->SetText( strString );
|
||||
}
|
||||
|
||||
void SetCellContents( int i, Base* pControl, bool bEnableMouseInput = false )
|
||||
{
|
||||
if ( !m_Columns[i] ) return;
|
||||
pControl->SetParent( m_Columns[i] );
|
||||
|
||||
m_Columns[i]->SetMouseInputEnabled( bEnableMouseInput );
|
||||
}
|
||||
|
||||
Label* GetCellContents( int i )
|
||||
{
|
||||
return m_Columns[i];
|
||||
}
|
||||
|
||||
void SizeToContents()
|
||||
{
|
||||
int iHeight = 0;
|
||||
|
||||
for ( int i=0; i<m_ColumnCount; i++ )
|
||||
{
|
||||
if ( !m_Columns[i] ) continue;
|
||||
|
||||
// Note, more than 1 child here, because the
|
||||
// label has a child built in ( The Text )
|
||||
if ( m_Columns[i]->NumChildren() > 1 )
|
||||
{
|
||||
m_Columns[i]->SizeToChildren();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Columns[i]->SizeToContents();
|
||||
}
|
||||
|
||||
iHeight = Utility::Max( iHeight, m_Columns[i]->Height() );
|
||||
}
|
||||
|
||||
SetHeight( iHeight );
|
||||
}
|
||||
|
||||
void SetTextColor( const Gwen::Color& color )
|
||||
{
|
||||
for ( int i=0; i<m_ColumnCount; i++ )
|
||||
{
|
||||
if ( !m_Columns[i] ) continue;
|
||||
m_Columns[i]->SetTextColor( color );
|
||||
}
|
||||
}
|
||||
|
||||
//You might hate this. Actually I know you will
|
||||
virtual UnicodeString GetText( int i )
|
||||
{
|
||||
return m_Columns[i]->GetText();
|
||||
}
|
||||
virtual void SetSelected( bool /*b*/ ) {}
|
||||
|
||||
//
|
||||
// This is sometimes called by derivatives.
|
||||
//
|
||||
Gwen::Event::Caller onRowSelected;
|
||||
|
||||
private:
|
||||
|
||||
int m_ColumnCount;
|
||||
Label* m_Columns[MaxColumns];
|
||||
|
||||
friend class Table;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class GWEN_EXPORT Table : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( Table, Base )
|
||||
{
|
||||
m_iColumnCount = 1;
|
||||
m_iDefaultRowHeight = 22;
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
m_ColumnWidth[i] = 20;
|
||||
}
|
||||
|
||||
|
||||
m_bSizeToContents = false;
|
||||
}
|
||||
|
||||
void SetColumnCount( int i )
|
||||
{
|
||||
if ( m_iColumnCount == i ) return;
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
if (!*it)
|
||||
continue;
|
||||
|
||||
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
|
||||
if ( !pRow ) continue;
|
||||
|
||||
pRow->SetColumnCount( i );
|
||||
}
|
||||
|
||||
m_iColumnCount = i;
|
||||
}
|
||||
|
||||
void SetColumnWidth( int i, int iWidth )
|
||||
{
|
||||
if ( m_ColumnWidth[i] == iWidth ) return;
|
||||
|
||||
m_ColumnWidth[i] = iWidth;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
TableRow* AddRow()
|
||||
{
|
||||
TableRow* row = new TableRow( this );
|
||||
row->SetColumnCount( m_iColumnCount );
|
||||
row->SetHeight( m_iDefaultRowHeight );
|
||||
row->Dock( Pos::Top );
|
||||
return row;
|
||||
}
|
||||
|
||||
void AddRow( TableRow* pRow )
|
||||
{
|
||||
pRow->SetParent( this );
|
||||
pRow->SetColumnCount( m_iColumnCount );
|
||||
pRow->SetHeight( m_iDefaultRowHeight );
|
||||
pRow->Dock( Pos::Top );
|
||||
}
|
||||
|
||||
void Remove( TableRow* pRow )
|
||||
{
|
||||
pRow->DelayedDelete();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
if (!(*it))
|
||||
continue;
|
||||
|
||||
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
|
||||
|
||||
if ( !pRow ) continue;
|
||||
Remove( pRow );
|
||||
}
|
||||
}
|
||||
|
||||
void Layout( Skin::Base* skin )
|
||||
{
|
||||
BaseClass::Layout( skin );
|
||||
|
||||
if ( m_bSizeToContents )
|
||||
{
|
||||
DoSizeToContents();
|
||||
}
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
if (!*it)
|
||||
continue;
|
||||
|
||||
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
|
||||
if ( !pRow ) continue;
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns && i < m_iColumnCount; i++)
|
||||
{
|
||||
pRow->SetColumnWidth( i, m_ColumnWidth[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PostLayout( Skin::Base* /*skin*/ )
|
||||
{
|
||||
if ( m_bSizeToContents )
|
||||
{
|
||||
SizeToChildren();
|
||||
m_bSizeToContents = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SizeToContents()
|
||||
{
|
||||
m_bSizeToContents = true;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void DoSizeToContents()
|
||||
{
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
m_ColumnWidth[i] = 10;
|
||||
}
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
if (!*it)
|
||||
continue;
|
||||
|
||||
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
|
||||
if ( !pRow ) continue;
|
||||
|
||||
pRow->SizeToContents();
|
||||
|
||||
for (int i=0; i<TableRow::MaxColumns; i++)
|
||||
{
|
||||
if ( pRow->m_Columns[i] )
|
||||
{
|
||||
m_ColumnWidth[i] = Utility::Max( m_ColumnWidth[i], pRow->m_Columns[i]->Width() );
|
||||
}
|
||||
}
|
||||
//iBottom += pRow->Height();
|
||||
}
|
||||
|
||||
InvalidateParent();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool m_bSizeToContents;
|
||||
int m_iColumnCount;
|
||||
int m_iDefaultRowHeight;
|
||||
|
||||
int m_ColumnWidth[ TableRow::MaxColumns ];
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
143
btgui/Gwen/Controls/ListBox.cpp
Normal file
143
btgui/Gwen/Controls/ListBox.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ListBox.h"
|
||||
#include "Gwen/Controls/ScrollControl.h"
|
||||
#include "Gwen/InputHandler.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
class ListBoxRow : public Layout::TableRow
|
||||
{
|
||||
GWEN_CONTROL_INLINE( ListBoxRow, Layout::TableRow )
|
||||
{
|
||||
SetMouseInputEnabled( true );
|
||||
SetSelected( false );
|
||||
}
|
||||
|
||||
void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawListBoxLine( this, IsSelected() );
|
||||
}
|
||||
|
||||
bool IsSelected() const
|
||||
{
|
||||
return m_bSelected;
|
||||
}
|
||||
|
||||
void OnMouseClickLeft( int /*x*/, int /*y*/, bool bDown )
|
||||
{
|
||||
if ( bDown && !m_bSelected )
|
||||
{
|
||||
SetSelected( true );
|
||||
onRowSelected.Call( this );
|
||||
}
|
||||
}
|
||||
|
||||
void SetSelected( bool b )
|
||||
{
|
||||
m_bSelected = b;
|
||||
|
||||
// TODO: Get these values from the skin.
|
||||
if ( b )
|
||||
SetTextColor( Gwen::Colors::White );
|
||||
else
|
||||
SetTextColor( Gwen::Colors::Black );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool m_bSelected;
|
||||
|
||||
};
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ListBox )
|
||||
{
|
||||
m_ScrollControl = new ScrollControl( this );
|
||||
m_ScrollControl->Dock( Pos::Fill );
|
||||
m_ScrollControl->SetScroll( false, true );
|
||||
m_ScrollControl->SetAutoHideBars( true );
|
||||
m_ScrollControl->SetMargin( Margin( 1, 1, 1, 1 ) );
|
||||
|
||||
m_InnerPanel = m_ScrollControl;
|
||||
|
||||
m_Table = new Controls::Layout::Table( this );
|
||||
m_Table->Dock( Pos::Top );
|
||||
m_Table->SetColumnCount( 1 );
|
||||
|
||||
m_bMultiSelect = false;
|
||||
}
|
||||
|
||||
void ListBox::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ )
|
||||
{
|
||||
m_ScrollControl->UpdateScrollBars();
|
||||
}
|
||||
|
||||
Layout::TableRow* ListBox::AddItem( const String& strLabel, const String& strName )
|
||||
{
|
||||
return AddItem( Utility::StringToUnicode( strLabel ), strName );
|
||||
}
|
||||
|
||||
Layout::TableRow* ListBox::AddItem( const UnicodeString& strLabel, const String& strName )
|
||||
{
|
||||
ListBoxRow* pRow = new ListBoxRow( this );
|
||||
m_Table->AddRow( pRow );
|
||||
|
||||
pRow->SetCellText( 0, strLabel );
|
||||
pRow->SetName( strName );
|
||||
|
||||
pRow->onRowSelected.Add( this, &ListBox::OnRowSelected );
|
||||
|
||||
m_Table->SizeToContents();
|
||||
|
||||
return pRow;
|
||||
}
|
||||
|
||||
void ListBox::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawListBox( this );
|
||||
}
|
||||
|
||||
void ListBox::UnselectAll()
|
||||
{
|
||||
std::list<Layout::TableRow*>::iterator it = m_SelectedRows.begin();
|
||||
while ( it != m_SelectedRows.end() )
|
||||
{
|
||||
ListBoxRow* pRow = static_cast<ListBoxRow*>(*it);
|
||||
it = m_SelectedRows.erase( it );
|
||||
|
||||
pRow->SetSelected( false );
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::OnRowSelected( Base* pControl )
|
||||
{
|
||||
ListBoxRow* pRow = static_cast<ListBoxRow*>(pControl);
|
||||
|
||||
if ( !AllowMultiSelect() || !Gwen::Input::IsShiftDown() )
|
||||
{
|
||||
UnselectAll();
|
||||
}
|
||||
|
||||
m_SelectedRows.push_back( pRow );
|
||||
|
||||
onRowSelected.Call( this );
|
||||
}
|
||||
|
||||
Layout::TableRow* ListBox::GetSelectedRow()
|
||||
{
|
||||
if ( m_SelectedRows.empty() ) return NULL;
|
||||
|
||||
return *m_SelectedRows.begin();
|
||||
}
|
||||
|
||||
void ListBox::Clear()
|
||||
{
|
||||
UnselectAll();
|
||||
m_Table->Clear();
|
||||
}
|
67
btgui/Gwen/Controls/ListBox.h
Normal file
67
btgui/Gwen/Controls/ListBox.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_LISTBOX_H
|
||||
#define GWEN_CONTROLS_LISTBOX_H
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Layout/Table.h"
|
||||
#include "Gwen/Controls/ScrollControl.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class ScrollControl;
|
||||
|
||||
class GWEN_EXPORT ListBox : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( ListBox, Base );
|
||||
|
||||
typedef std::list<Layout::TableRow*> Rows;
|
||||
|
||||
Layout::TableRow* AddItem( const String& strLabel, const String& strName = "" );
|
||||
Layout::TableRow* AddItem( const UnicodeString& strLabel, const String& strName = "" );
|
||||
|
||||
void Render( Skin::Base* skin );
|
||||
|
||||
void UnselectAll();
|
||||
|
||||
void SetColumnCount( int iCount ) { m_Table->SetColumnCount( iCount ); }
|
||||
|
||||
void SetAllowMultiSelect( bool bMultiSelect ){ m_bMultiSelect = bMultiSelect; }
|
||||
bool AllowMultiSelect() const { return m_bMultiSelect; }
|
||||
|
||||
const ListBox::Rows& GetSelectedRows(){ return m_SelectedRows; }
|
||||
Layout::TableRow* GetSelectedRow();
|
||||
|
||||
Gwen::Controls::ScrollControl* Scroller() { return m_ScrollControl; }
|
||||
|
||||
void OnChildBoundsChanged( Gwen::Rect oldChildBounds, Base* pChild );
|
||||
|
||||
Gwen::Event::Caller onRowSelected;
|
||||
|
||||
Controls::Layout::Table* GetTable() { return m_Table; }
|
||||
virtual void Clear();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
void OnRowSelected( Base* pControl );
|
||||
|
||||
Controls::Layout::Table* m_Table;
|
||||
ListBox::Rows m_SelectedRows;
|
||||
Controls::ScrollControl* m_ScrollControl;
|
||||
|
||||
bool m_bMultiSelect;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
172
btgui/Gwen/Controls/Menu.cpp
Normal file
172
btgui/Gwen/Controls/Menu.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Menu.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( Menu )
|
||||
{
|
||||
SetBounds( 0, 0, 10, 10 );
|
||||
SetPadding( Padding( 2, 2, 2, 2 ) );
|
||||
|
||||
SetDisableIconMargin( false );
|
||||
|
||||
SetAutoHideBars( true );
|
||||
SetScroll( false, true );
|
||||
}
|
||||
|
||||
|
||||
void Menu::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawMenu( this, IconMarginDisabled() );
|
||||
}
|
||||
|
||||
void Menu::RenderUnder( Skin::Base* skin )
|
||||
{
|
||||
BaseClass::RenderUnder( skin );
|
||||
skin->DrawShadow( this );
|
||||
}
|
||||
|
||||
void Menu::Layout( Skin::Base* skin )
|
||||
{
|
||||
int childrenHeight = 0;
|
||||
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
|
||||
{
|
||||
Base* pChild = (*it);
|
||||
if ( !pChild )
|
||||
continue;
|
||||
|
||||
childrenHeight += pChild->Height();
|
||||
}
|
||||
|
||||
if ( Y() + childrenHeight > GetCanvas()->Height() )
|
||||
childrenHeight = GetCanvas()->Height() - Y();
|
||||
|
||||
SetSize( Width(), childrenHeight );
|
||||
|
||||
BaseClass::Layout( skin );
|
||||
}
|
||||
|
||||
MenuItem* Menu::AddItem( const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn )
|
||||
{
|
||||
MenuItem* pItem = new MenuItem( this );
|
||||
pItem->SetText( strName );
|
||||
pItem->SetImage( strIconName );
|
||||
|
||||
if ( fn && pHandler )
|
||||
{
|
||||
pItem->onMenuItemSelected.Add( pHandler, fn );
|
||||
}
|
||||
|
||||
OnAddItem( pItem );
|
||||
|
||||
return pItem;
|
||||
}
|
||||
|
||||
void Menu::OnAddItem( MenuItem* item )
|
||||
{
|
||||
item->Dock( Pos::Top );
|
||||
item->SetTextPadding( Padding( IconMarginDisabled() ? 0 : 24, 0, 16, 0 ) );
|
||||
item->SetPadding( Padding( 4, 4, 4, 4 ) );
|
||||
item->SizeToContents();
|
||||
item->SetAlignment( Pos::CenterV | Pos::Left );
|
||||
item->onHoverEnter.Add( this, &Menu::OnHoverItem );
|
||||
|
||||
// Do this here - after Top Docking these values mean nothing in layout
|
||||
int w = item->Width() + 10 + 32;
|
||||
if ( w < Width() ) w = Width();
|
||||
SetSize( w, Height() );
|
||||
}
|
||||
|
||||
void Menu::ClearItems()
|
||||
{
|
||||
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
|
||||
{
|
||||
Base* pChild = *it;
|
||||
|
||||
if ( !pChild ) continue;
|
||||
pChild->DelayedDelete();
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem* Menu::AddItem( const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn )
|
||||
{
|
||||
return AddItem( Gwen::Utility::StringToUnicode( strName ), Gwen::Utility::StringToUnicode( strIconName ), pHandler, fn );
|
||||
}
|
||||
|
||||
|
||||
void Menu::CloseAll()
|
||||
{
|
||||
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
|
||||
{
|
||||
Base* pChild = *it;
|
||||
MenuItem* pItem = pChild->DynamicCastMenuItem();
|
||||
if ( !pItem ) continue;
|
||||
|
||||
pItem->CloseMenu();
|
||||
}
|
||||
}
|
||||
|
||||
bool Menu::IsMenuOpen()
|
||||
{
|
||||
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
|
||||
{
|
||||
Base* pChild = *it;
|
||||
MenuItem* pItem = pChild->DynamicCastMenuItem();
|
||||
if ( !pItem ) continue;
|
||||
|
||||
if ( pItem->IsMenuOpen() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Menu::OnHoverItem( Gwen::Controls::Base* pControl )
|
||||
{
|
||||
if ( !ShouldHoverOpenMenu() ) return;
|
||||
|
||||
MenuItem* pItem = pControl->DynamicCastMenuItem();
|
||||
if (!pItem) return;
|
||||
if ( pItem->IsMenuOpen() ) return;
|
||||
|
||||
CloseAll();
|
||||
pItem->OpenMenu();
|
||||
}
|
||||
|
||||
void Menu::Close()
|
||||
{
|
||||
SetHidden( true );
|
||||
}
|
||||
|
||||
void Menu::CloseMenus()
|
||||
{
|
||||
BaseClass::CloseMenus();
|
||||
|
||||
CloseAll();
|
||||
Close();
|
||||
}
|
||||
|
||||
void Menu::AddDivider()
|
||||
{
|
||||
MenuDivider* divider = new MenuDivider( this );
|
||||
divider->Dock( Pos::Top );
|
||||
divider->SetMargin( Margin( IconMarginDisabled() ? 0 : 24, 0, 4, 0 ) );
|
||||
}
|
||||
|
||||
void MenuDivider::Render( Gwen::Skin::Base* skin )
|
||||
{
|
||||
skin->DrawMenuDivider( this );
|
||||
}
|
86
btgui/Gwen/Controls/Menu.h
Normal file
86
btgui/Gwen/Controls/Menu.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_MENU_H
|
||||
#define GWEN_CONTROLS_MENU_H
|
||||
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/MenuItem.h"
|
||||
#include "Gwen/Controls/ScrollControl.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class MenuItem;
|
||||
|
||||
class GWEN_EXPORT Menu : public ScrollControl
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( Menu, ScrollControl );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void RenderUnder( Skin::Base* skin );
|
||||
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
|
||||
virtual MenuItem* AddItem( const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL );
|
||||
|
||||
virtual MenuItem* AddItem( const Gwen::UnicodeString& strName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL )
|
||||
{
|
||||
return AddItem( strName, L"", pHandler, fn );
|
||||
}
|
||||
|
||||
virtual MenuItem* AddItem( const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL );
|
||||
|
||||
virtual MenuItem* AddItem( const Gwen::String& strName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL )
|
||||
{
|
||||
return AddItem( strName, "", pHandler, fn );
|
||||
}
|
||||
|
||||
virtual void AddDivider();
|
||||
|
||||
void OnHoverItem( Gwen::Controls::Base* pControl );
|
||||
void CloseAll();
|
||||
bool IsMenuOpen();
|
||||
void ClearItems();
|
||||
|
||||
virtual void Close();
|
||||
|
||||
virtual bool IsMenuComponent(){ return true; }
|
||||
virtual void CloseMenus();
|
||||
|
||||
bool IconMarginDisabled() { return m_bDisableIconMargin; }
|
||||
void SetDisableIconMargin( bool bDisable ) { m_bDisableIconMargin = bDisable; }
|
||||
|
||||
virtual bool ShouldClip(){ return false; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool ShouldHoverOpenMenu(){ return true; }
|
||||
virtual void OnAddItem( MenuItem* item );
|
||||
|
||||
bool m_bDisableIconMargin;
|
||||
};
|
||||
|
||||
class GWEN_EXPORT MenuDivider : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( MenuDivider, Base )
|
||||
{
|
||||
SetHeight( 1 );
|
||||
}
|
||||
|
||||
void Render( Gwen::Skin::Base* skin );
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
137
btgui/Gwen/Controls/MenuItem.cpp
Normal file
137
btgui/Gwen/Controls/MenuItem.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/MenuItem.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( MenuItem )
|
||||
{
|
||||
m_Menu = NULL;
|
||||
m_bOnStrip = false;
|
||||
m_SubmenuArrow = NULL;
|
||||
SetTabable( false );
|
||||
SetCheckable( false );
|
||||
SetCheck( false );
|
||||
}
|
||||
|
||||
MenuItem::~MenuItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MenuItem::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawMenuItem( this, IsMenuOpen(), m_bCheckable ? m_bChecked : false );
|
||||
}
|
||||
|
||||
void MenuItem::Layout( Skin::Base* skin )
|
||||
{
|
||||
BaseClass::Layout( skin );
|
||||
|
||||
}
|
||||
|
||||
Menu* MenuItem::GetMenu()
|
||||
{
|
||||
if ( !m_Menu )
|
||||
{
|
||||
m_Menu = new Menu( GetCanvas() );
|
||||
m_Menu->SetHidden( true );
|
||||
|
||||
if ( !m_bOnStrip )
|
||||
{
|
||||
m_SubmenuArrow = new Symbol::Arrow( this );
|
||||
m_SubmenuArrow->Dock( Pos::Right );
|
||||
m_SubmenuArrow->SetSize( 20, 20 );
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
return m_Menu;
|
||||
}
|
||||
|
||||
void MenuItem::SetCheck( bool bCheck )
|
||||
{
|
||||
if ( bCheck == m_bChecked)
|
||||
return;
|
||||
|
||||
m_bChecked = bCheck;
|
||||
|
||||
onCheckChange.Call( this );
|
||||
|
||||
if ( bCheck )
|
||||
onChecked.Call( this );
|
||||
else
|
||||
onUnChecked.Call( this );
|
||||
}
|
||||
|
||||
void MenuItem::OnPress()
|
||||
{
|
||||
if ( m_Menu )
|
||||
{
|
||||
ToggleMenu();
|
||||
}
|
||||
else if ( !m_bOnStrip )
|
||||
{
|
||||
SetCheck( !GetChecked() );
|
||||
onMenuItemSelected.Call( this );
|
||||
GetCanvas()->CloseMenus();
|
||||
}
|
||||
|
||||
BaseClass::OnPress();
|
||||
}
|
||||
|
||||
void MenuItem::ToggleMenu()
|
||||
{
|
||||
if ( IsMenuOpen() ) CloseMenu();
|
||||
else OpenMenu();
|
||||
}
|
||||
|
||||
bool MenuItem::IsMenuOpen()
|
||||
{
|
||||
if ( !m_Menu ) return false;
|
||||
|
||||
return !m_Menu->Hidden();
|
||||
}
|
||||
|
||||
void MenuItem::OpenMenu()
|
||||
{
|
||||
if ( !m_Menu ) return;
|
||||
|
||||
m_Menu->SetHidden( false );
|
||||
m_Menu->BringToFront();
|
||||
|
||||
Gwen::Point p = LocalPosToCanvas( Gwen::Point( 0, 0 ) );
|
||||
|
||||
// Strip menus open downwards
|
||||
if ( m_bOnStrip )
|
||||
{
|
||||
m_Menu->SetPos( p.x, p.y + Height() + 1 );
|
||||
}
|
||||
// Submenus open sidewards
|
||||
else
|
||||
{
|
||||
m_Menu->SetPos( p.x + Width(), p.y);
|
||||
}
|
||||
|
||||
// TODO: Option this.
|
||||
// TODO: Make sure on screen, open the other side of the
|
||||
// parent if it's better...
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MenuItem::CloseMenu()
|
||||
{
|
||||
if ( !m_Menu ) return;
|
||||
m_Menu->Close();
|
||||
m_Menu->CloseAll();
|
||||
}
|
69
btgui/Gwen/Controls/MenuItem.h
Normal file
69
btgui/Gwen/Controls/MenuItem.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_MENUITEM_H
|
||||
#define GWEN_CONTROLS_MENUITEM_H
|
||||
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Controls/Menu.h"
|
||||
#include "Gwen/Controls/Symbol.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class Menu;
|
||||
|
||||
class GWEN_EXPORT MenuItem : public Button
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( MenuItem, Button );
|
||||
|
||||
virtual ~MenuItem();
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
|
||||
virtual void OnPress();
|
||||
|
||||
Menu* GetMenu();
|
||||
|
||||
bool IsMenuOpen();
|
||||
void OpenMenu();
|
||||
void CloseMenu();
|
||||
void ToggleMenu();
|
||||
|
||||
void SetOnStrip( bool b ){ m_bOnStrip = b;}
|
||||
bool OnStrip(){ return m_bOnStrip; }
|
||||
|
||||
virtual void SetCheckable( bool bCheck ) { m_bCheckable = bCheck; }
|
||||
virtual void SetCheck( bool bCheck );
|
||||
virtual bool GetChecked() { return m_bChecked; }
|
||||
|
||||
Gwen::Event::Caller onMenuItemSelected;
|
||||
Gwen::Event::Caller onChecked;
|
||||
Gwen::Event::Caller onUnChecked;
|
||||
Gwen::Event::Caller onCheckChange;
|
||||
|
||||
private:
|
||||
|
||||
Menu* m_Menu;
|
||||
bool m_bOnStrip;
|
||||
bool m_bCheckable;
|
||||
bool m_bChecked;
|
||||
|
||||
|
||||
|
||||
Symbol::Arrow * m_SubmenuArrow;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
44
btgui/Gwen/Controls/MenuStrip.cpp
Normal file
44
btgui/Gwen/Controls/MenuStrip.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/MenuStrip.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( MenuStrip )
|
||||
{
|
||||
SetBounds( 0, 0, 200, 22 );
|
||||
Dock( Pos::Top );
|
||||
m_InnerPanel->SetPadding( Padding( 5, 2, 2, 2 ) );
|
||||
}
|
||||
|
||||
void MenuStrip::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawMenuStrip( this );
|
||||
}
|
||||
|
||||
void MenuStrip::Layout( Skin::Base* /*skin*/ )
|
||||
{
|
||||
//TODO: We don't want to do vertical sizing the same as Menu, do nothing for now
|
||||
}
|
||||
|
||||
void MenuStrip::OnAddItem( MenuItem* item )
|
||||
{
|
||||
item->Dock( Pos::Left );
|
||||
item->SetPadding( Padding( 5, 0, 5, 0 ) );
|
||||
item->SizeToContents();
|
||||
item->SetOnStrip( true );
|
||||
item->onHoverEnter.Add( this, &Menu::OnHoverItem );
|
||||
}
|
||||
|
||||
bool MenuStrip::ShouldHoverOpenMenu()
|
||||
{
|
||||
return IsMenuOpen();
|
||||
}
|
39
btgui/Gwen/Controls/MenuStrip.h
Normal file
39
btgui/Gwen/Controls/MenuStrip.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_MENUSTRIP_H
|
||||
#define GWEN_CONTROLS_MENUSTRIP_H
|
||||
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Menu.h"
|
||||
#include "Gwen/Controls/MenuItem.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT MenuStrip : public Menu
|
||||
{
|
||||
GWEN_CONTROL( MenuStrip, Menu );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void RenderUnder( Skin::Base* /*skin*/ ){}
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnAddItem( MenuItem* item );
|
||||
virtual bool ShouldHoverOpenMenu();
|
||||
virtual void Close() {}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
37
btgui/Gwen/Controls/Modal.h
Normal file
37
btgui/Gwen/Controls/Modal.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_MODAL_H
|
||||
#define GWEN_CONTROLS_MODAL_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace ControlsInternal
|
||||
{
|
||||
class Modal : public Controls::Base
|
||||
{
|
||||
GWEN_CONTROL_INLINE( Modal, Controls::Base )
|
||||
{
|
||||
SetKeyboardInputEnabled( true );
|
||||
SetMouseInputEnabled( true );
|
||||
SetShouldDrawBackground( true );
|
||||
}
|
||||
|
||||
virtual void Layout( Skin::Base* /*skin*/ )
|
||||
{
|
||||
SetBounds( 0, 0, GetCanvas()->Width(), GetCanvas()->Height() );
|
||||
}
|
||||
|
||||
virtual void Render( Skin::Base* skin )
|
||||
{
|
||||
if ( !ShouldDrawBackground() ) return;
|
||||
|
||||
skin->DrawModalControl( this );
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
117
btgui/Gwen/Controls/NumericUpDown.cpp
Normal file
117
btgui/Gwen/Controls/NumericUpDown.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Utility.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/NumericUpDown.h"
|
||||
#include "Gwen/Controls/Layout/Splitter.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( NumericUpDown )
|
||||
{
|
||||
SetSize( 100, 20 );
|
||||
|
||||
Layout::Splitter* pSplitter = new Layout::Splitter( this );
|
||||
pSplitter->Dock( Pos::Right );
|
||||
pSplitter->SetSize( 13, 13 );
|
||||
|
||||
NumericUpDownButton_Up* pButtonUp = new NumericUpDownButton_Up( pSplitter );
|
||||
pButtonUp->onPress.Add( this, &NumericUpDown::OnButtonUp );
|
||||
pButtonUp->SetTabable( false );
|
||||
|
||||
pSplitter->SetPanel( 0, pButtonUp );
|
||||
|
||||
|
||||
NumericUpDownButton_Down* pButtonDown = new NumericUpDownButton_Down( pSplitter );
|
||||
pButtonDown->onPress.Add( this, &NumericUpDown::OnButtonDown );
|
||||
pButtonDown->SetTabable( false );
|
||||
pButtonUp->SetPadding( Padding( 0, 1, 1, 0 ) );
|
||||
|
||||
pSplitter->SetPanel( 1, pButtonDown );
|
||||
|
||||
m_iMax = 100;
|
||||
m_iMin = 0;
|
||||
m_iNumber = 0;
|
||||
SetText( "0" );
|
||||
}
|
||||
|
||||
void NumericUpDown::OnButtonUp( Base* /*control*/ )
|
||||
{
|
||||
SyncNumberFromText();
|
||||
SetValue( m_iNumber + 1 );
|
||||
}
|
||||
|
||||
void NumericUpDown::OnButtonDown( Base* /*control*/ )
|
||||
{
|
||||
SyncNumberFromText();
|
||||
SetValue( m_iNumber - 1 );
|
||||
}
|
||||
|
||||
|
||||
void NumericUpDown::SyncTextFromNumber()
|
||||
{
|
||||
SetText( Utility::ToString( m_iNumber ) );
|
||||
}
|
||||
|
||||
void NumericUpDown::SyncNumberFromText()
|
||||
{
|
||||
SetValue( (int) GetFloatFromText() );
|
||||
}
|
||||
|
||||
void NumericUpDown::SetMin( int i )
|
||||
{
|
||||
m_iMin = i;
|
||||
}
|
||||
|
||||
void NumericUpDown::SetMax( int i )
|
||||
{
|
||||
m_iMax = i;
|
||||
}
|
||||
|
||||
void NumericUpDown::SetValue( int i )
|
||||
{
|
||||
if ( i > m_iMax ) i = m_iMax;
|
||||
if ( i < m_iMin ) i = m_iMin;
|
||||
|
||||
if ( m_iNumber == i )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_iNumber = i;
|
||||
|
||||
// Don't update the text if we're typing in it..
|
||||
if ( !HasFocus() )
|
||||
{
|
||||
SyncTextFromNumber();
|
||||
}
|
||||
|
||||
OnChange();
|
||||
}
|
||||
|
||||
void NumericUpDown::OnChange()
|
||||
{
|
||||
onChanged.Call( this );
|
||||
}
|
||||
|
||||
void NumericUpDown::OnTextChanged()
|
||||
{
|
||||
BaseClass::OnTextChanged();
|
||||
|
||||
SyncNumberFromText();
|
||||
}
|
||||
|
||||
void NumericUpDown::OnEnter()
|
||||
{
|
||||
SyncNumberFromText();
|
||||
SyncTextFromNumber();
|
||||
}
|
75
btgui/Gwen/Controls/NumericUpDown.h
Normal file
75
btgui/Gwen/Controls/NumericUpDown.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_NUMERICUPDOWN_H
|
||||
#define GWEN_CONTROLS_NUMERICUPDOWN_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Controls/TextBox.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT NumericUpDownButton_Up : public Button
|
||||
{
|
||||
GWEN_CONTROL_INLINE( NumericUpDownButton_Up, Button ){}
|
||||
|
||||
virtual void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawNumericUpDownButton( this, m_bDepressed, true );
|
||||
}
|
||||
};
|
||||
|
||||
class GWEN_EXPORT NumericUpDownButton_Down : public Button
|
||||
{
|
||||
GWEN_CONTROL_INLINE( NumericUpDownButton_Down, Button ){}
|
||||
|
||||
virtual void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawNumericUpDownButton( this, m_bDepressed, false );
|
||||
}
|
||||
};
|
||||
|
||||
class GWEN_EXPORT NumericUpDown : public TextBoxNumeric
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( NumericUpDown, TextBoxNumeric );
|
||||
|
||||
virtual void SetMin( int i );
|
||||
virtual void SetMax( int i );
|
||||
virtual void SetValue( int i );
|
||||
|
||||
Event::Caller onChanged;
|
||||
|
||||
private:
|
||||
|
||||
virtual void OnEnter();
|
||||
virtual void OnChange();
|
||||
virtual void OnTextChanged();
|
||||
|
||||
virtual void OnButtonUp( Base* control );
|
||||
virtual void OnButtonDown( Base* control );
|
||||
|
||||
virtual bool OnKeyUp( bool bDown ) { if ( bDown ) OnButtonUp( NULL ); return true; }
|
||||
virtual bool OnKeyDown( bool bDown ){ if ( bDown ) OnButtonDown( NULL ); return true; }
|
||||
|
||||
virtual void SyncTextFromNumber();
|
||||
virtual void SyncNumberFromText();
|
||||
|
||||
|
||||
|
||||
int m_iNumber;
|
||||
int m_iMax;
|
||||
int m_iMin;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
124
btgui/Gwen/Controls/PanelListPanel.cpp
Normal file
124
btgui/Gwen/Controls/PanelListPanel.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
|
||||
#include "Gwen/Controls/PanelListPanel.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( PanelListPanel )
|
||||
{
|
||||
m_bVertical = false;
|
||||
m_bSizeToChildren = true;
|
||||
m_iControlSpacing = 5;
|
||||
m_iLineSpacing = 5;
|
||||
m_bWrapping = true;
|
||||
}
|
||||
|
||||
void PanelListPanel::Render( Gwen::Skin::Base* /*skin*/ )
|
||||
{
|
||||
}
|
||||
|
||||
Gwen::Point PanelListPanel::GetBiggestChildSize()
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
Controls::Base* pChild = *it;
|
||||
if ( pChild->Width() > width )
|
||||
width = pChild->Width();
|
||||
|
||||
if ( pChild->Height() > height )
|
||||
height = pChild->Height();
|
||||
}
|
||||
|
||||
return Gwen::Point( width, height );
|
||||
}
|
||||
|
||||
void PanelListPanel::DoVerticalLayout()
|
||||
{
|
||||
int panelWidth = 0;
|
||||
int panelX = GetPadding().left;
|
||||
int panelY = GetPadding().top;
|
||||
int lastPanelY = panelY;
|
||||
int testWrap = 0;
|
||||
|
||||
Gwen::Point childSize = GetBiggestChildSize();
|
||||
//Lay my children out accordingly
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
Controls::Base* pChild = *it;
|
||||
testWrap = lastPanelY + m_iControlSpacing + childSize.y;
|
||||
if ( m_bWrapping && testWrap > Height() - GetPadding().bottom )
|
||||
{
|
||||
panelY = GetPadding().top;
|
||||
panelX = GetPadding().left + panelWidth + m_iLineSpacing;
|
||||
lastPanelY = panelY + m_iControlSpacing + childSize.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
panelY = lastPanelY;
|
||||
lastPanelY = testWrap;
|
||||
}
|
||||
|
||||
pChild->SetPos( panelX, panelY );
|
||||
|
||||
if (pChild->X() + childSize.x > panelWidth )
|
||||
panelWidth = pChild->X() + childSize.x;
|
||||
}
|
||||
|
||||
if ( m_bSizeToChildren )
|
||||
{
|
||||
Gwen::Point childrenSizeTotal = ChildrenSize();
|
||||
SetSize( childrenSizeTotal.x, Height());
|
||||
}
|
||||
}
|
||||
|
||||
void PanelListPanel::DoHorizontalLayout()
|
||||
{
|
||||
int panelHeight = 0;
|
||||
int panelX = GetPadding().left;
|
||||
int panelY = GetPadding().top;
|
||||
int lastPanelX = panelX;
|
||||
int testWrap = 0;
|
||||
|
||||
Gwen::Point childSize = GetBiggestChildSize();
|
||||
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
Controls::Base* pChild = *it;
|
||||
|
||||
testWrap = lastPanelX + m_iControlSpacing + childSize.x;
|
||||
if ( m_bWrapping && testWrap > Width() - GetPadding().right )
|
||||
{
|
||||
panelX = GetPadding().left;
|
||||
panelY = GetPadding().top + panelHeight + m_iLineSpacing;
|
||||
lastPanelX = panelX + m_iControlSpacing + childSize.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
panelX = lastPanelX;
|
||||
lastPanelX = testWrap;
|
||||
}
|
||||
|
||||
pChild->SetPos( panelX, panelY );
|
||||
|
||||
if (pChild->Y() + childSize.y > panelHeight )
|
||||
panelHeight = pChild->Y() + childSize.y;
|
||||
}
|
||||
|
||||
if ( m_bSizeToChildren )
|
||||
{
|
||||
Gwen::Point childrenSizeTotal = ChildrenSize();
|
||||
SetSize( Width(), childrenSizeTotal.y);
|
||||
}
|
||||
}
|
||||
|
||||
void PanelListPanel::Layout( Skin::Base* skin )
|
||||
{
|
||||
BaseClass::Layout( skin );
|
||||
if ( IsHorizontalLayout() )
|
||||
DoHorizontalLayout();
|
||||
else
|
||||
DoVerticalLayout();
|
||||
}
|
46
btgui/Gwen/Controls/PanelListPanel.h
Normal file
46
btgui/Gwen/Controls/PanelListPanel.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_PANELLISTPANEL_H
|
||||
#define GWEN_CONTROLS_PANELLISTPANEL_H
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT PanelListPanel : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( PanelListPanel, Controls::Base );
|
||||
|
||||
void Render( Gwen::Skin::Base* skin );
|
||||
void Layout( Skin::Base* skin );
|
||||
|
||||
void DoHorizontalLayout();
|
||||
void DoVerticalLayout();
|
||||
|
||||
bool IsVerticalLayout() { return m_bVertical; }
|
||||
bool IsHorizontalLayout() { return !m_bVertical; }
|
||||
void SetVertical() { m_bVertical = true; Invalidate(); }
|
||||
void SetHorizontal() { m_bVertical = false; Invalidate(); }
|
||||
|
||||
void SetSizeToChildren( bool bShould ) { m_bSizeToChildren = bShould; }
|
||||
void SetControlSpacing( int spacing ) { m_iControlSpacing = spacing; }
|
||||
void SetLineSpacing( int spacing ) { m_iLineSpacing = spacing; }
|
||||
void SetWrapping( bool wrap ) { m_bWrapping = wrap; }
|
||||
|
||||
Gwen::Point GetBiggestChildSize();
|
||||
|
||||
protected:
|
||||
|
||||
bool m_bVertical;
|
||||
bool m_bSizeToChildren;
|
||||
int m_iControlSpacing;
|
||||
int m_iLineSpacing;
|
||||
bool m_bWrapping;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
49
btgui/Gwen/Controls/ProgressBar.cpp
Normal file
49
btgui/Gwen/Controls/ProgressBar.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ScrollControl.h"
|
||||
#include "Gwen/Controls/ProgressBar.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ProgressBar )
|
||||
{
|
||||
SetMouseInputEnabled( true );
|
||||
SetBounds( Gwen::Rect( 0, 0, 128, 32 ) );
|
||||
SetTextPadding( Padding( 3, 3, 3, 3 ) );
|
||||
SetHorizontal();
|
||||
|
||||
SetAlignment( Gwen::Pos::Center );
|
||||
|
||||
m_fProgress = 0.0f;
|
||||
m_bAutoLabel = true;
|
||||
}
|
||||
|
||||
void ProgressBar::SetValue(float val)
|
||||
{
|
||||
if ( val < 0 )
|
||||
val = 0;
|
||||
|
||||
if ( val > 1 )
|
||||
val = 1;
|
||||
|
||||
m_fProgress = val;
|
||||
|
||||
if ( m_bAutoLabel )
|
||||
{
|
||||
int displayVal = m_fProgress * 100;
|
||||
SetText( Utility::ToString( displayVal ) + "%" );
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressBar::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawProgressBar( this, m_bHorizontal, m_fProgress);
|
||||
}
|
45
btgui/Gwen/Controls/ProgressBar.h
Normal file
45
btgui/Gwen/Controls/ProgressBar.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_PROGRESSBAR_H
|
||||
#define GWEN_CONTROLS_PROGRESSBAR_H
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT ProgressBar : public Label
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( ProgressBar, Label );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
|
||||
virtual void SetVertical() { m_bHorizontal = false; }
|
||||
virtual void SetHorizontal(){ m_bHorizontal = true; }
|
||||
|
||||
virtual void SetValue( float val );
|
||||
virtual float GetValue() const { return m_fProgress; }
|
||||
|
||||
virtual void SetAutoLabel( bool b ){ m_bAutoLabel = b; }
|
||||
|
||||
protected:
|
||||
|
||||
float m_fProgress;
|
||||
|
||||
bool m_bHorizontal;
|
||||
bool m_bAutoLabel;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
125
btgui/Gwen/Controls/Properties.cpp
Normal file
125
btgui/Gwen/Controls/Properties.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/Properties.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( Properties )
|
||||
{
|
||||
m_SplitterBar = new SplitterBar( this );
|
||||
m_SplitterBar->SetPos( 80, 0 );
|
||||
m_SplitterBar->SetCursor( Gwen::CursorType::SizeWE );
|
||||
m_SplitterBar->onDragged.Add( this, &Properties::OnSplitterMoved );
|
||||
m_SplitterBar->SetShouldDrawBackground( false );
|
||||
}
|
||||
|
||||
void Properties::PostLayout( Gwen::Skin::Base* /*skin*/ )
|
||||
{
|
||||
m_SplitterBar->SetHeight( 0 );
|
||||
|
||||
if ( SizeToChildren( false, true ) )
|
||||
{
|
||||
InvalidateParent();
|
||||
}
|
||||
|
||||
m_SplitterBar->SetSize( 3, Height() );
|
||||
}
|
||||
|
||||
void Properties::OnSplitterMoved( Controls::Base * /*control*/ )
|
||||
{
|
||||
InvalidateChildren();
|
||||
}
|
||||
|
||||
int Properties::GetSplitWidth()
|
||||
{
|
||||
return m_SplitterBar->X();
|
||||
}
|
||||
|
||||
PropertyRow* Properties::Add( const UnicodeString& text, const UnicodeString& value )
|
||||
{
|
||||
Property::Base* pProp = new Property::Text( this );
|
||||
pProp->SetPropertyValue( value );
|
||||
|
||||
return Add( text, pProp );
|
||||
}
|
||||
|
||||
PropertyRow* Properties::Add( const String& text, const String& value )
|
||||
{
|
||||
return Add( Gwen::Utility::StringToUnicode( text ), Gwen::Utility::StringToUnicode( value ) );
|
||||
}
|
||||
|
||||
PropertyRow* Properties::Add( const UnicodeString& text, Property::Base* pProp )
|
||||
{
|
||||
PropertyRow* row = new PropertyRow( this );
|
||||
row->Dock( Pos::Top );
|
||||
row->GetLabel()->SetText( text );
|
||||
row->SetProperty( pProp );
|
||||
|
||||
m_SplitterBar->BringToFront();
|
||||
return row;
|
||||
}
|
||||
|
||||
PropertyRow* Properties::Add( const String& text, Property::Base* pProp )
|
||||
{
|
||||
return Add( Gwen::Utility::StringToUnicode( text ), pProp );
|
||||
}
|
||||
|
||||
void Properties::Clear()
|
||||
{
|
||||
Base::List ChildListCopy = Children;
|
||||
for ( Base::List::iterator it = ChildListCopy.begin(); it != ChildListCopy.end(); ++it )
|
||||
{
|
||||
PropertyRow* row = (*it)->DynamicCastPropertyRow();
|
||||
if ( !row ) continue;
|
||||
|
||||
row->DelayedDelete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( PropertyRow )
|
||||
{
|
||||
m_Property = NULL;
|
||||
|
||||
m_Label = new Label( this );
|
||||
m_Label->SetAlignment( Pos::CenterV | Pos::Left );
|
||||
m_Label->Dock( Pos::Left );
|
||||
m_Label->SetMargin( Margin( 2, 0, 0, 0 ) );
|
||||
|
||||
SetHeight( 16 );
|
||||
}
|
||||
|
||||
void PropertyRow::Render( Gwen::Skin::Base* skin )
|
||||
{
|
||||
skin->DrawPropertyRow( this, m_Label->Right(), m_Property->IsEditing() );
|
||||
}
|
||||
|
||||
void PropertyRow::Layout( Gwen::Skin::Base* /*skin*/ )
|
||||
{
|
||||
Properties* pParent = GetParent()->DynamicCastProperties();
|
||||
if ( !pParent ) return;
|
||||
|
||||
m_Label->SetWidth( pParent->GetSplitWidth() );
|
||||
}
|
||||
|
||||
void PropertyRow::SetProperty( Property::Base* prop )
|
||||
{
|
||||
m_Property = prop;
|
||||
m_Property->SetParent( this );
|
||||
m_Property->Dock( Pos::Fill );
|
||||
m_Property->onChange.Add( this, &ThisClass::OnPropertyValueChanged );
|
||||
}
|
||||
|
||||
void PropertyRow::OnPropertyValueChanged( Gwen::Controls::Base* /*control*/ )
|
||||
{
|
||||
onChange.Call( this );
|
||||
}
|
77
btgui/Gwen/Controls/Properties.h
Normal file
77
btgui/Gwen/Controls/Properties.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_PROPERTIES_H
|
||||
#define GWEN_CONTROLS_PROPERTIES_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Controls/Property/BaseProperty.h"
|
||||
#include "Gwen/Controls/Property/Text.h"
|
||||
#include "Gwen/Controls/SplitterBar.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
|
||||
class PropertyRow;
|
||||
|
||||
class GWEN_EXPORT Properties : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( Properties, Base );
|
||||
|
||||
virtual void PostLayout( Gwen::Skin::Base* skin );
|
||||
|
||||
PropertyRow* Add( const UnicodeString& text, const UnicodeString& value = L"" );
|
||||
PropertyRow* Add( const String& text, const String& value = "" );
|
||||
PropertyRow* Add( const UnicodeString& text, Property::Base* pProp );
|
||||
PropertyRow* Add( const String& text, Property::Base* pProp );
|
||||
|
||||
virtual int GetSplitWidth();
|
||||
|
||||
virtual void Clear();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnSplitterMoved( Controls::Base * control );
|
||||
|
||||
Controls::SplitterBar* m_SplitterBar;
|
||||
|
||||
};
|
||||
|
||||
class GWEN_EXPORT PropertyRow : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( PropertyRow, Base );
|
||||
|
||||
virtual Label* GetLabel(){ return m_Label; }
|
||||
virtual void SetProperty( Property::Base* prop );
|
||||
virtual Property::Base* GetProperty(){ return m_Property; }
|
||||
|
||||
virtual void Layout( Gwen::Skin::Base* skin );
|
||||
virtual void Render( Gwen::Skin::Base* skin );
|
||||
|
||||
Event::Caller onChange;
|
||||
|
||||
protected:
|
||||
|
||||
void OnPropertyValueChanged( Gwen::Controls::Base* control );
|
||||
|
||||
Label* m_Label;
|
||||
Property::Base* m_Property;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
60
btgui/Gwen/Controls/Property/BaseProperty.h
Normal file
60
btgui/Gwen/Controls/Property/BaseProperty.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_PROPERTY_BASEPROPERTY_H
|
||||
#define GWEN_CONTROLS_PROPERTY_BASEPROPERTY_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Property
|
||||
{
|
||||
class GWEN_EXPORT Base : public Gwen::Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( Base, Gwen::Controls::Base ){}
|
||||
|
||||
virtual String GetPropertyValueAnsi()
|
||||
{
|
||||
return Gwen::Utility::UnicodeToString( GetPropertyValue() );
|
||||
}
|
||||
|
||||
virtual void SetPropertyValue( const String& v, bool bFireChangeEvents = false )
|
||||
{
|
||||
SetPropertyValue( Gwen::Utility::StringToUnicode( v ), bFireChangeEvents );
|
||||
}
|
||||
|
||||
virtual UnicodeString GetPropertyValue() = 0;
|
||||
|
||||
virtual void SetPropertyValue( const UnicodeString& v, bool bFireChangeEvents = false ) = 0;
|
||||
|
||||
virtual bool IsEditing() = 0;
|
||||
|
||||
virtual void DoChanged()
|
||||
{
|
||||
onChange.Call( this );
|
||||
}
|
||||
|
||||
virtual void OnPropertyValueChanged( Gwen::Controls::Base* /*control*/ )
|
||||
{
|
||||
DoChanged();
|
||||
}
|
||||
|
||||
Event::Caller onChange;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
80
btgui/Gwen/Controls/Property/ColorSelector.h
Normal file
80
btgui/Gwen/Controls/Property/ColorSelector.h
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_PROPERTY_COLORSELECTOR_H
|
||||
#define GWEN_CONTROLS_PROPERTY_COLORSELECTOR_H
|
||||
|
||||
#include "Gwen/Controls/Properties.h"
|
||||
#include "Gwen/Controls/WindowControl.h"
|
||||
#include "Gwen/Controls/HSVColorPicker.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Property
|
||||
{
|
||||
class ColorSelector : public Property::Text
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( ColorSelector, Property::Text )
|
||||
{
|
||||
m_Button = new Button( this );
|
||||
m_Button->Dock( Pos::Right );
|
||||
m_Button->SetWidth( 20 );
|
||||
m_Button->onPress.Add( this, &ThisClass::OnButtonPress );
|
||||
}
|
||||
|
||||
void OnButtonPress( Controls::Base* control )
|
||||
{
|
||||
Gwen::Controls::WindowControl* wind = new Gwen::Controls::WindowControl( GetCanvas() );
|
||||
wind->SetTitle( L"Color Selection" );
|
||||
wind->SetSize( 256, 180 );
|
||||
wind->SetPos( GetCanvas()->Width() * 0.5 - 128, GetCanvas()->Height()* 0.5 - 128 );
|
||||
wind->SetDeleteOnClose( true );
|
||||
wind->DisableResizing();
|
||||
wind->MakeModal( true );
|
||||
|
||||
Gwen::Controls::HSVColorPicker* picker = new Gwen::Controls::HSVColorPicker( wind );
|
||||
picker->SetName( "picker" );
|
||||
|
||||
float defaultColor[3];
|
||||
Gwen::Utility::Strings::To::Floats( Gwen::Utility::UnicodeToString( m_TextBox->GetText() ), defaultColor, 3);
|
||||
|
||||
picker->SetColor( Gwen::Color( defaultColor[0], defaultColor[1], defaultColor[2], 255 ), false, true );
|
||||
picker->onColorChanged.Add( this, &ThisClass::ColorChanged );
|
||||
}
|
||||
|
||||
void ColorChanged( Controls::Base* control )
|
||||
{
|
||||
Gwen::Controls::HSVColorPicker* picker = control->DynamicCastHSVColorPicker();
|
||||
|
||||
Gwen::String colorStr;
|
||||
colorStr += Gwen::Utility::ToString( ( int )picker->GetColor().r ) + " ";
|
||||
colorStr += Gwen::Utility::ToString( ( int )picker->GetColor().g ) + " ";
|
||||
colorStr += Gwen::Utility::ToString( ( int )picker->GetColor().b );
|
||||
|
||||
m_TextBox->SetText( colorStr );
|
||||
DoChanged();
|
||||
}
|
||||
|
||||
virtual UnicodeString GetPropertyValue()
|
||||
{
|
||||
return m_TextBox->GetText();
|
||||
}
|
||||
|
||||
virtual void SetPropertyValue( const UnicodeString& v, bool bFireChangeEvents )
|
||||
{
|
||||
m_TextBox->SetText( v, bFireChangeEvents );
|
||||
}
|
||||
|
||||
virtual bool IsEditing()
|
||||
{
|
||||
return m_TextBox == Gwen::KeyboardFocus;
|
||||
}
|
||||
|
||||
Button* m_Button;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
52
btgui/Gwen/Controls/Property/Text.h
Normal file
52
btgui/Gwen/Controls/Property/Text.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_PROPERTY_TEXT_H
|
||||
#define GWEN_CONTROLS_PROPERTY_TEXT_H
|
||||
|
||||
#include "Gwen/Controls/Property/BaseProperty.h"
|
||||
#include "Gwen/Controls/TextBox.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
namespace Property
|
||||
{
|
||||
class GWEN_EXPORT Text : public Property::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( Text, Property::Base )
|
||||
{
|
||||
m_TextBox = new TextBox( this );
|
||||
m_TextBox->Dock( Pos::Fill );
|
||||
m_TextBox->SetShouldDrawBackground( false );
|
||||
m_TextBox->onTextChanged.Add( this, &BaseClass::OnPropertyValueChanged );
|
||||
}
|
||||
|
||||
virtual UnicodeString GetPropertyValue()
|
||||
{
|
||||
return m_TextBox->GetText();
|
||||
}
|
||||
|
||||
virtual void SetPropertyValue( const UnicodeString& v, bool bFireChangeEvents )
|
||||
{
|
||||
m_TextBox->SetText( v, bFireChangeEvents );
|
||||
}
|
||||
|
||||
virtual bool IsEditing()
|
||||
{
|
||||
return m_TextBox->HasFocus();
|
||||
}
|
||||
|
||||
TextBox* m_TextBox;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
62
btgui/Gwen/Controls/PropertyTree.h
Normal file
62
btgui/Gwen/Controls/PropertyTree.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_PROPERTYTREE_H
|
||||
#define GWEN_CONTROLS_PROPERTYTREE_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/TreeControl.h"
|
||||
#include "Gwen/Controls/Properties.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class PropertyTreeNode : public TreeNode
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( PropertyTreeNode, TreeNode )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawPropertyTreeNode( this, m_InnerPanel->X(), m_InnerPanel->Y() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class PropertyTree : public TreeControl
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( PropertyTree, TreeControl )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Properties* Add( const UnicodeString& text )
|
||||
{
|
||||
TreeNode* node = new PropertyTreeNode( this );
|
||||
node->SetText( text );
|
||||
node->Dock( Pos::Top );
|
||||
|
||||
Properties* props = new Properties( node );
|
||||
props->Dock( Pos::Top );
|
||||
|
||||
return props;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
24
btgui/Gwen/Controls/RadioButton.cpp
Normal file
24
btgui/Gwen/Controls/RadioButton.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/RadioButton.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( RadioButton )
|
||||
{
|
||||
SetSize( 11, 11 );
|
||||
SetMouseInputEnabled( true );
|
||||
SetTabable( false );
|
||||
}
|
||||
|
||||
void RadioButton::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawRadioButton( this, IsChecked(), IsDepressed() );
|
||||
}
|
||||
|
78
btgui/Gwen/Controls/RadioButton.h
Normal file
78
btgui/Gwen/Controls/RadioButton.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_RADIOBUTTON_H
|
||||
#define GWEN_CONTROLS_RADIOBUTTON_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/CheckBox.h"
|
||||
#include "Gwen/Controls/LabelClickable.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT RadioButton : public CheckBox
|
||||
{
|
||||
GWEN_CONTROL( RadioButton, CheckBox );
|
||||
virtual void Render( Skin::Base* skin );
|
||||
|
||||
private:
|
||||
|
||||
// From CheckBox
|
||||
virtual bool AllowUncheck(){ return false; }
|
||||
};
|
||||
|
||||
class GWEN_EXPORT LabeledRadioButton : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL_INLINE( LabeledRadioButton, Base )
|
||||
{
|
||||
SetSize( 200, 19 );
|
||||
|
||||
m_RadioButton = new RadioButton( this );
|
||||
m_RadioButton->Dock( Pos::Left );
|
||||
m_RadioButton->SetMargin( Margin( 0, 4, 2, 4 ) );
|
||||
m_RadioButton->SetTabable( false );
|
||||
m_RadioButton->SetKeyboardInputEnabled( false );
|
||||
|
||||
m_Label = new LabelClickable( this );
|
||||
m_Label->SetAlignment( Pos::CenterV | Pos::Left );
|
||||
m_Label->SetText( "Radio Button" );
|
||||
m_Label->Dock( Pos::Fill );
|
||||
m_Label->onPress.Add( m_RadioButton, &CheckBox::ReceiveEventPress );
|
||||
m_Label->SetTabable( false );
|
||||
m_Label->SetKeyboardInputEnabled( false );
|
||||
}
|
||||
|
||||
void RenderFocus( Gwen::Skin::Base* skin )
|
||||
{
|
||||
if ( Gwen::KeyboardFocus != this ) return;
|
||||
if ( !IsTabable() ) return;
|
||||
|
||||
skin->DrawKeyboardHighlight( this, GetRenderBounds(), 0 );
|
||||
}
|
||||
|
||||
virtual RadioButton* GetRadioButton() { return m_RadioButton; }
|
||||
virtual LabelClickable* GetLabel(){ return m_Label; }
|
||||
virtual bool OnKeySpace(bool bDown) { if ( bDown ) m_RadioButton->SetChecked( !m_RadioButton->IsChecked() ); return true; }
|
||||
|
||||
virtual void Select(){ m_RadioButton->SetChecked( true ); }
|
||||
|
||||
private:
|
||||
|
||||
RadioButton* m_RadioButton;
|
||||
LabelClickable* m_Label;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
74
btgui/Gwen/Controls/RadioButtonController.cpp
Normal file
74
btgui/Gwen/Controls/RadioButtonController.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/RadioButtonController.h"
|
||||
#include "Gwen/Controls/RadioButton.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( RadioButtonController )
|
||||
{
|
||||
m_Selected = NULL;
|
||||
SetTabable( false );
|
||||
SetKeyboardInputEnabled( false );
|
||||
}
|
||||
|
||||
void RadioButtonController::OnRadioClicked( Gwen::Controls::Base* pFromPanel )
|
||||
{
|
||||
RadioButton* pCheckedRadioButton = pFromPanel->DynamicCastRadioButton();
|
||||
|
||||
//Iterate through all other buttons and set them to false;
|
||||
for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
|
||||
{
|
||||
Base* pChild = *iter;
|
||||
LabeledRadioButton* pLRB = pChild->DynamicCastLabeledRadioButton();
|
||||
if ( pLRB )
|
||||
{
|
||||
RadioButton* pChildRadioButton = pLRB->GetRadioButton();
|
||||
if ( pChildRadioButton == pCheckedRadioButton )
|
||||
{
|
||||
m_Selected = pLRB;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLRB->GetRadioButton()->SetChecked( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnChange();
|
||||
}
|
||||
|
||||
void RadioButtonController::OnChange()
|
||||
{
|
||||
onSelectionChange.Call( this );
|
||||
}
|
||||
|
||||
LabeledRadioButton* RadioButtonController::AddOption( const Gwen::String& strText, const Gwen::String& strOptionName )
|
||||
{
|
||||
return AddOption( Gwen::Utility::StringToUnicode( strText ), strOptionName );
|
||||
}
|
||||
|
||||
LabeledRadioButton* RadioButtonController::AddOption( const Gwen::UnicodeString& strText, const Gwen::String& strOptionName )
|
||||
{
|
||||
LabeledRadioButton* lrb = new LabeledRadioButton( this );
|
||||
|
||||
lrb->SetName( strOptionName );
|
||||
lrb->GetLabel()->SetText( strText );
|
||||
lrb->GetRadioButton()->onChecked.Add( this, &RadioButtonController::OnRadioClicked );
|
||||
lrb->Dock( Pos::Top );
|
||||
lrb->SetMargin( Margin( 0, 1, 0, 1 ) );
|
||||
lrb->SetKeyboardInputEnabled( false );
|
||||
lrb->SetTabable( false );
|
||||
|
||||
Invalidate();
|
||||
|
||||
return lrb;
|
||||
}
|
48
btgui/Gwen/Controls/RadioButtonController.h
Normal file
48
btgui/Gwen/Controls/RadioButtonController.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_RADIOBOTTONCONTROLLER_H
|
||||
#define GWEN_CONTROLS_RADIOBOTTONCONTROLLER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Controls/RadioButton.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
|
||||
class GWEN_EXPORT RadioButtonController : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( RadioButtonController, Base );
|
||||
|
||||
virtual void Render( Skin::Base* /*skin*/ ){};
|
||||
virtual void OnRadioClicked( Base* pFromPanel );
|
||||
|
||||
virtual void OnChange();
|
||||
|
||||
virtual LabeledRadioButton* AddOption( const Gwen::String& strText, const Gwen::String& strOptionName = "" );
|
||||
virtual LabeledRadioButton* AddOption( const Gwen::UnicodeString& strText, const Gwen::String& strOptionName = "" );
|
||||
|
||||
virtual LabeledRadioButton* GetSelected(){ return m_Selected; }
|
||||
|
||||
virtual String GetSelectedName(){ return m_Selected->GetName(); }
|
||||
virtual UnicodeString GetSelectedLabel(){ return m_Selected->GetLabel()->GetText(); }
|
||||
|
||||
Event::Caller onSelectionChange;
|
||||
|
||||
private:
|
||||
|
||||
LabeledRadioButton* m_Selected;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
110
btgui/Gwen/Controls/ResizableControl.cpp
Normal file
110
btgui/Gwen/Controls/ResizableControl.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ImagePanel.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Controls/Resizer.h"
|
||||
#include "Gwen/Controls/ResizableControl.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ResizableControl )
|
||||
{
|
||||
m_bResizable = true;
|
||||
m_MinimumSize = Gwen::Point( 5, 5 );
|
||||
m_bClampMovement = false;
|
||||
|
||||
Resizer* resizerBottom = new Resizer (this );
|
||||
resizerBottom->Dock( Pos::Bottom );
|
||||
resizerBottom->SetResizeDir( Pos::Bottom );
|
||||
resizerBottom->SetTarget( this );
|
||||
resizerBottom->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
|
||||
Resizer* resizerBottomLeft = new Resizer( resizerBottom );
|
||||
resizerBottomLeft->Dock( Pos::Left );
|
||||
resizerBottomLeft->SetResizeDir( Pos::Bottom | Pos::Left );
|
||||
resizerBottomLeft->SetTarget(this );
|
||||
resizerBottomLeft->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
|
||||
Resizer* resizerBottomRight = new Resizer( resizerBottom );
|
||||
resizerBottomRight->Dock( Pos::Right);
|
||||
resizerBottomRight->SetResizeDir( Pos::Bottom | Pos::Right );
|
||||
resizerBottomRight->SetTarget( this );
|
||||
resizerBottomRight->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
|
||||
Resizer* resizerTop = new Resizer( this );
|
||||
resizerTop->Dock( Pos::Top );
|
||||
resizerTop->SetResizeDir( Pos::Top );
|
||||
resizerTop->SetTarget( this );
|
||||
resizerTop->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
|
||||
Resizer* resizerTopLeft = new Resizer( resizerTop );
|
||||
resizerTopLeft->Dock( Pos::Left );
|
||||
resizerTopLeft->SetResizeDir( Pos::Top | Pos::Left );
|
||||
resizerTopLeft->SetTarget( this );
|
||||
resizerTopLeft->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
|
||||
Resizer* resizerTopRight = new Resizer( resizerTop );
|
||||
resizerTopRight->Dock( Pos::Right );
|
||||
resizerTopRight->SetResizeDir( Pos::Top| Pos::Right );
|
||||
resizerTopRight->SetTarget( this );
|
||||
resizerTopRight->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
|
||||
Resizer* resizerLeft = new Resizer( this );
|
||||
resizerLeft->Dock( Pos::Left );
|
||||
resizerLeft->SetResizeDir( Pos::Left );
|
||||
resizerLeft->SetTarget( this );
|
||||
resizerLeft->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
|
||||
Resizer* resizerRight = new Resizer( this );
|
||||
resizerRight->Dock( Pos::Right );
|
||||
resizerRight->SetResizeDir( Pos::Right );
|
||||
resizerRight->SetTarget( this );
|
||||
resizerRight->onResize.Add( this, &ResizableControl::OnResizedInternal );
|
||||
}
|
||||
|
||||
void ResizableControl::DisableResizing()
|
||||
{
|
||||
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
|
||||
{
|
||||
Resizer* resizer = (*it)->DynamicCastResizer();
|
||||
if ( !resizer ) continue;
|
||||
|
||||
resizer->SetMouseInputEnabled( false );
|
||||
resizer->SetHidden( true );
|
||||
SetPadding( Padding( resizer->Width(), resizer->Width(), resizer->Width(), resizer->Width() ) );
|
||||
}
|
||||
}
|
||||
|
||||
bool ResizableControl::SetBounds( int x, int y, int w, int h )
|
||||
{
|
||||
Gwen::Point minSize = GetMinimumSize();
|
||||
|
||||
// Clamp Minimum Size
|
||||
if ( w < minSize.x ) w = minSize.x;
|
||||
if ( h < minSize.y ) h = minSize.y;
|
||||
|
||||
// Clamp to parent's window
|
||||
Base* pParent = GetParent();
|
||||
if ( pParent && m_bClampMovement )
|
||||
{
|
||||
if ( x + w > pParent->Width() ) x = pParent->Width() - w;
|
||||
if ( x < 0 ) x = 0;
|
||||
if ( y + h > pParent->Height() ) y = pParent->Height() - h;
|
||||
if ( y < 0 ) y = 0;
|
||||
}
|
||||
|
||||
return BaseClass::SetBounds( x, y, w, h );
|
||||
}
|
||||
|
||||
void ResizableControl::OnResizedInternal( Controls::Base* /*pControl*/ )
|
||||
{
|
||||
onResize.Call( this );
|
||||
OnResized();
|
||||
}
|
55
btgui/Gwen/Controls/ResizableControl.h
Normal file
55
btgui/Gwen/Controls/ResizableControl.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_RESIZABLECONTROL_H
|
||||
#define GWEN_CONTROLS_RESIZABLECONTROL_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Controls/Button.h"
|
||||
#include "Gwen/Controls/Dragger.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT ResizableControl : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( ResizableControl, Base );
|
||||
|
||||
virtual void SetClampMovement( bool shouldClamp ) { m_bClampMovement = shouldClamp; }
|
||||
virtual bool GetClampMovement() { return m_bClampMovement; }
|
||||
|
||||
virtual void SetMinimumSize( const Gwen::Point& minSize ) { m_MinimumSize = minSize; }
|
||||
virtual Gwen::Point GetMinimumSize() { return m_MinimumSize; }
|
||||
|
||||
virtual void DisableResizing();
|
||||
|
||||
virtual bool SetBounds( int x, int y, int w, int h );
|
||||
|
||||
virtual void OnResized(){};
|
||||
|
||||
Event::Caller onResize;
|
||||
|
||||
protected:
|
||||
|
||||
void OnResizedInternal( Controls::Base* pControl );
|
||||
|
||||
Gwen::Point m_MinimumSize;
|
||||
bool m_bClampMovement;
|
||||
bool m_bResizable;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
120
btgui/Gwen/Controls/Resizer.cpp
Normal file
120
btgui/Gwen/Controls/Resizer.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/Resizer.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( Resizer )
|
||||
{
|
||||
m_iResizeDir = Pos::Left;
|
||||
SetMouseInputEnabled( true );
|
||||
SetSize( 6, 6 );
|
||||
}
|
||||
|
||||
void Resizer::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
|
||||
{
|
||||
if ( !m_pTarget ) return;
|
||||
if ( !m_bDepressed ) return;
|
||||
|
||||
Gwen::Rect oldBounds = m_pTarget->GetBounds();
|
||||
Gwen::Rect pBounds = m_pTarget->GetBounds();
|
||||
|
||||
Gwen::Point pntMin = m_pTarget->GetMinimumSize();
|
||||
|
||||
Gwen::Point pCursorPos = m_pTarget->CanvasPosToLocal( Gwen::Point( x, y ) );
|
||||
|
||||
Gwen::Point pDelta = m_pTarget->LocalPosToCanvas( m_HoldPos );
|
||||
pDelta.x -= x;
|
||||
pDelta.y -= y;
|
||||
|
||||
if ( m_iResizeDir & Pos::Left )
|
||||
{
|
||||
pBounds.x -= pDelta.x;
|
||||
pBounds.w += pDelta.x;
|
||||
|
||||
// Conform to minimum size here so we don't
|
||||
// go all weird when we snap it in the base conrt
|
||||
|
||||
if ( pBounds.w < pntMin.x )
|
||||
{
|
||||
int diff = pntMin.x - pBounds.w;
|
||||
pBounds.w += diff;
|
||||
pBounds.x -= diff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( m_iResizeDir & Pos::Top )
|
||||
{
|
||||
pBounds.y -= pDelta.y;
|
||||
pBounds.h += pDelta.y;
|
||||
|
||||
// Conform to minimum size here so we don't
|
||||
// go all weird when we snap it in the base conrt
|
||||
|
||||
if ( pBounds.h < pntMin.y )
|
||||
{
|
||||
int diff = pntMin.y - pBounds.h;
|
||||
pBounds.h += diff;
|
||||
pBounds.y -= diff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( m_iResizeDir & Pos::Right )
|
||||
{
|
||||
// This is complicated.
|
||||
// Basically we want to use the HoldPos, so it doesn't snap to the edge of the control
|
||||
// But we need to move the HoldPos with the window movement. Yikes.
|
||||
// I actually think this might be a big hack around the way this control works with regards
|
||||
// to the holdpos being on the parent panel.
|
||||
|
||||
int woff = pBounds.w - m_HoldPos.x;
|
||||
int diff = pBounds.w;
|
||||
pBounds.w = pCursorPos.x + woff;
|
||||
if ( pBounds.w < pntMin.x ) pBounds.w = pntMin.x;
|
||||
diff -= pBounds.w;
|
||||
|
||||
m_HoldPos.x -= diff;
|
||||
}
|
||||
|
||||
if ( m_iResizeDir & Pos::Bottom )
|
||||
{
|
||||
int hoff = pBounds.h - m_HoldPos.y;
|
||||
int diff = pBounds.h;
|
||||
pBounds.h = pCursorPos.y + hoff;
|
||||
if ( pBounds.h < pntMin.y ) pBounds.h = pntMin.y;
|
||||
diff -= pBounds.h;
|
||||
|
||||
m_HoldPos.y -= diff;
|
||||
}
|
||||
|
||||
m_pTarget->SetBounds( pBounds );
|
||||
|
||||
onResize.Call( this );
|
||||
}
|
||||
|
||||
void Resizer::SetResizeDir( int dir )
|
||||
{
|
||||
m_iResizeDir = dir;
|
||||
|
||||
if ( (dir & Pos::Left && dir & Pos::Top) || (dir & Pos::Right && dir & Pos::Bottom) )
|
||||
return SetCursor( Gwen::CursorType::SizeNWSE );
|
||||
|
||||
if ( (dir & Pos::Right && dir & Pos::Top) || (dir & Pos::Left && dir & Pos::Bottom) )
|
||||
return SetCursor( Gwen::CursorType::SizeNESW );
|
||||
|
||||
if ( dir & Pos::Right || dir & Pos::Left )
|
||||
return SetCursor( Gwen::CursorType::SizeWE );
|
||||
|
||||
if ( dir & Pos::Top || dir & Pos::Bottom )
|
||||
return SetCursor( Gwen::CursorType::SizeNS );
|
||||
|
||||
}
|
39
btgui/Gwen/Controls/Resizer.h
Normal file
39
btgui/Gwen/Controls/Resizer.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_RESIZER_H
|
||||
#define GWEN_CONTROLS_RESIZER_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
#include "Gwen/Controls/Dragger.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace ControlsInternal
|
||||
{
|
||||
class GWEN_EXPORT Resizer : public Dragger
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( Resizer, Dragger );
|
||||
|
||||
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
|
||||
virtual void SetResizeDir( int dir );
|
||||
|
||||
Event::Caller onResize;
|
||||
|
||||
protected:
|
||||
|
||||
int m_iResizeDir;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
209
btgui/Gwen/Controls/RichLabel.cpp
Normal file
209
btgui/Gwen/Controls/RichLabel.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Controls/RichLabel.h"
|
||||
#include "Gwen/Controls/Label.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
const unsigned char Type_Text = 0;
|
||||
const unsigned char Type_Newline = 1;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( RichLabel )
|
||||
{
|
||||
m_bNeedsRebuild = false;
|
||||
}
|
||||
|
||||
void RichLabel::AddLineBreak()
|
||||
{
|
||||
DividedText t;
|
||||
t.type = Type_Newline;
|
||||
|
||||
m_TextBlocks.push_back( t );
|
||||
}
|
||||
|
||||
void RichLabel::AddText( const Gwen::TextObject& text, Gwen::Color color, Gwen::Font* font )
|
||||
{
|
||||
if ( text.m_Data.size() == 0 ) return;
|
||||
|
||||
Gwen::Utility::Strings::UnicodeList lst;
|
||||
Gwen::Utility::Strings::Split( text.GetUnicode(), L"\n", lst, false );
|
||||
|
||||
for (size_t i=0; i<lst.size(); i++ )
|
||||
{
|
||||
if ( i > 0 ) AddLineBreak();
|
||||
|
||||
DividedText t;
|
||||
t.type = Type_Text;
|
||||
t.text = lst[i];
|
||||
t.color = color;
|
||||
t.font = font;
|
||||
|
||||
m_TextBlocks.push_back( t );
|
||||
m_bNeedsRebuild = true;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
bool RichLabel::SizeToChildren( bool w, bool h )
|
||||
{
|
||||
Rebuild();
|
||||
return BaseClass::SizeToChildren( w, h );
|
||||
}
|
||||
|
||||
void RichLabel::SplitLabel( const Gwen::UnicodeString& text, Gwen::Font* pFont, const DividedText& txt, int& x, int& y, int& lineheight )
|
||||
{
|
||||
Gwen::Utility::Strings::UnicodeList lst;
|
||||
Gwen::Utility::Strings::Split( text, L" ", lst, true );
|
||||
if ( lst.size() == 0 ) return;
|
||||
|
||||
int iSpaceLeft = Width() - x;
|
||||
|
||||
// Does the whole word fit in?
|
||||
{
|
||||
Gwen::Point StringSize = GetSkin()->GetRender()->MeasureText( pFont, text );
|
||||
if ( iSpaceLeft > StringSize.x )
|
||||
{
|
||||
return CreateLabel( text, txt, x, y, lineheight, true );
|
||||
}
|
||||
}
|
||||
|
||||
// If the first word is bigger than the line, just give up.
|
||||
{
|
||||
Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText( pFont, lst[0] );
|
||||
if ( WordSize.x >= iSpaceLeft )
|
||||
{
|
||||
CreateLabel( lst[0], txt, x, y, lineheight, true );
|
||||
if ( lst[0].size() >= text.size() ) return;
|
||||
|
||||
Gwen::UnicodeString LeftOver = text.substr( lst[0].size() + 1 );
|
||||
return SplitLabel( LeftOver, pFont, txt, x, y, lineheight );
|
||||
}
|
||||
}
|
||||
|
||||
Gwen::UnicodeString strNewString = L"";
|
||||
for ( size_t i=0; i<lst.size(); i++ )
|
||||
{
|
||||
Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText( pFont, strNewString + lst[i] );
|
||||
if ( WordSize.x > iSpaceLeft )
|
||||
{
|
||||
CreateLabel( strNewString, txt, x, y, lineheight, true );
|
||||
x = 0;
|
||||
y += lineheight;
|
||||
break;;
|
||||
}
|
||||
|
||||
strNewString += lst[i];
|
||||
}
|
||||
|
||||
Gwen::UnicodeString LeftOver = text.substr( strNewString.size() + 1 );
|
||||
return SplitLabel( LeftOver, pFont, txt, x, y, lineheight );
|
||||
}
|
||||
|
||||
void RichLabel::CreateLabel( const Gwen::UnicodeString& text, const DividedText& txt, int& x, int& y, int& lineheight, bool NoSplit )
|
||||
{
|
||||
|
||||
//
|
||||
// Use default font or is one set?
|
||||
//
|
||||
Gwen::Font* pFont = GetSkin()->GetDefaultFont();
|
||||
if ( txt.font ) pFont = txt.font;
|
||||
|
||||
//
|
||||
// This string is too long for us, split it up.
|
||||
//
|
||||
Gwen::Point p = GetSkin()->GetRender()->MeasureText( pFont, text );
|
||||
|
||||
if ( lineheight == -1 )
|
||||
{
|
||||
lineheight = p.y;
|
||||
}
|
||||
|
||||
if ( !NoSplit )
|
||||
{
|
||||
if ( x + p.x > Width() )
|
||||
{
|
||||
return SplitLabel( text, pFont, txt, x, y, lineheight );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Wrap
|
||||
//
|
||||
if ( x + p.x >= Width() )
|
||||
{
|
||||
CreateNewline( x, y, lineheight );
|
||||
}
|
||||
|
||||
Gwen::Controls::Label* pLabel = new Gwen::Controls::Label( this );
|
||||
pLabel->SetText( x == 0 ? Gwen::Utility::Strings::TrimLeft<Gwen::UnicodeString>( text, L" " ) : text );
|
||||
pLabel->SetTextColor( txt.color );
|
||||
pLabel->SetFont( pFont );
|
||||
pLabel->SizeToContents();
|
||||
pLabel->SetPos( x, y );
|
||||
|
||||
//lineheight = (lineheight + pLabel->Height()) / 2;
|
||||
|
||||
x += pLabel->Width();
|
||||
|
||||
if ( x >= Width() )
|
||||
{
|
||||
CreateNewline( x, y, lineheight );
|
||||
}
|
||||
}
|
||||
|
||||
void RichLabel::CreateNewline( int& x, int& y, int& lineheight )
|
||||
{
|
||||
x = 0;
|
||||
y += lineheight;
|
||||
}
|
||||
|
||||
void RichLabel::Rebuild()
|
||||
{
|
||||
RemoveAllChildren();
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int lineheight = -1;
|
||||
for ( DividedText::List::iterator it = m_TextBlocks.begin(); it != m_TextBlocks.end(); ++it )
|
||||
{
|
||||
if ( it->type == Type_Newline )
|
||||
{
|
||||
CreateNewline( x, y, lineheight );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( it->type == Type_Text )
|
||||
{
|
||||
CreateLabel( (*it).text, *it, x, y, lineheight, false );
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_bNeedsRebuild = false;
|
||||
}
|
||||
|
||||
void RichLabel::OnBoundsChanged( Gwen::Rect oldBounds )
|
||||
{
|
||||
BaseClass::OnBoundsChanged( oldBounds );
|
||||
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void RichLabel::Layout( Gwen::Skin::Base* skin )
|
||||
{
|
||||
BaseClass::Layout( skin );
|
||||
|
||||
if ( m_bNeedsRebuild )
|
||||
{
|
||||
Rebuild();
|
||||
}
|
||||
}
|
62
btgui/Gwen/Controls/RichLabel.h
Normal file
62
btgui/Gwen/Controls/RichLabel.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_RICHLABEL_H
|
||||
#define GWEN_CONTROLS_RICHLABEL_H
|
||||
|
||||
#include "Gwen/BaseRender.h"
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/Text.h"
|
||||
#include "Gwen/TextObject.h"
|
||||
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT RichLabel : public Controls::Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( RichLabel, Gwen::Controls::Base );
|
||||
|
||||
void AddLineBreak();
|
||||
void AddText( const Gwen::TextObject& text, Gwen::Color color, Gwen::Font* font = NULL );
|
||||
|
||||
virtual bool SizeToChildren( bool w = true, bool h = true );
|
||||
|
||||
protected:
|
||||
|
||||
struct DividedText
|
||||
{
|
||||
typedef std::list<DividedText> List;
|
||||
DividedText()
|
||||
{
|
||||
type = 0;
|
||||
font = NULL;
|
||||
}
|
||||
|
||||
unsigned char type;
|
||||
Gwen::UnicodeString text;
|
||||
Gwen::Color color;
|
||||
Gwen::Font* font;
|
||||
};
|
||||
|
||||
void Layout( Gwen::Skin::Base* skin );
|
||||
void SplitLabel( const Gwen::UnicodeString& text, Gwen::Font* pFont, const DividedText& txt, int& x, int& y, int& lineheight );
|
||||
void CreateNewline( int& x, int& y, int& lineheight );
|
||||
void CreateLabel( const Gwen::UnicodeString& text, const DividedText& txt, int& x, int& y, int& lineheight, bool NoSplit );
|
||||
void Rebuild();
|
||||
|
||||
void OnBoundsChanged( Gwen::Rect oldBounds );
|
||||
|
||||
DividedText::List m_TextBlocks;
|
||||
bool m_bNeedsRebuild;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
83
btgui/Gwen/Controls/ScrollBar.cpp
Normal file
83
btgui/Gwen/Controls/ScrollBar.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ScrollBar.h"
|
||||
#include "Gwen/Controls/ScrollBarButton.h"
|
||||
#include "Gwen/Controls/ScrollBarBar.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( BaseScrollBar )
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_ScrollButton[i] = new ScrollBarButton( this );
|
||||
}
|
||||
|
||||
m_Bar = new ScrollBarBar( this );
|
||||
|
||||
SetBounds( 0, 0, 15, 15 );
|
||||
m_bDepressed = false;
|
||||
|
||||
m_fScrolledAmount = 0;
|
||||
m_fContentSize = 0;
|
||||
m_fViewableContentSize = 0;
|
||||
|
||||
SetNudgeAmount( 20 );
|
||||
}
|
||||
|
||||
void BaseScrollBar::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawScrollBar( this, false, m_bDepressed );
|
||||
}
|
||||
|
||||
void BaseScrollBar::OnBarMoved( Controls::Base* /*control*/ )
|
||||
{
|
||||
onBarMoved.Call( this );
|
||||
}
|
||||
|
||||
void BaseScrollBar::BarMovedNotification()
|
||||
{
|
||||
OnBarMoved( this );
|
||||
}
|
||||
|
||||
void BaseScrollBar::SetContentSize( float size )
|
||||
{
|
||||
if ( m_fContentSize != size )
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
m_fContentSize = size;
|
||||
|
||||
}
|
||||
void BaseScrollBar::SetViewableContentSize( float size )
|
||||
{
|
||||
if ( m_fViewableContentSize != size )
|
||||
Invalidate();
|
||||
|
||||
m_fViewableContentSize = size;
|
||||
}
|
||||
|
||||
bool BaseScrollBar::SetScrolledAmount( float amount, bool /*forceUpdate*/ )
|
||||
{
|
||||
if ( m_fScrolledAmount == amount ) return false;
|
||||
|
||||
m_fScrolledAmount = amount;
|
||||
Invalidate();
|
||||
BarMovedNotification();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
77
btgui/Gwen/Controls/ScrollBar.h
Normal file
77
btgui/Gwen/Controls/ScrollBar.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_SCROLLBAR_H
|
||||
#define GWEN_CONTROLS_SCROLLBAR_H
|
||||
|
||||
#include "Gwen/Controls/Base.h"
|
||||
#include "Gwen/Controls/ScrollBarBar.h"
|
||||
#include "Gwen/Controls/ScrollBarButton.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
|
||||
|
||||
#define SCROLL_BUTTON_UP 0
|
||||
#define SCROLL_BUTTON_LEFT 0
|
||||
#define SCROLL_BUTTON_DOWN 1
|
||||
#define SCROLL_BUTTON_RIGHT 1
|
||||
#define NUDGE_DIST 10
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace Controls
|
||||
{
|
||||
class GWEN_EXPORT BaseScrollBar : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( BaseScrollBar, Base );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
|
||||
virtual void SetBarSize(int size) = 0;
|
||||
virtual int GetBarSize() = 0;
|
||||
virtual int GetBarPos() = 0;
|
||||
|
||||
virtual void OnBarMoved( Controls::Base* control);
|
||||
virtual void OnMouseClickLeft( int /*x*/, int /*y*/, bool /*bDown*/ ){}
|
||||
|
||||
virtual void ScrollToLeft(){}
|
||||
virtual void ScrollToRight(){}
|
||||
virtual void ScrollToTop(){}
|
||||
virtual void ScrollToBottom(){}
|
||||
|
||||
virtual float GetNudgeAmount() { return m_fNudgeAmount / m_fContentSize; }
|
||||
virtual void SetNudgeAmount( float nudge ) { m_fNudgeAmount = nudge; }
|
||||
|
||||
virtual void BarMovedNotification();
|
||||
|
||||
virtual float CalculateScrolledAmount() { return 0; }
|
||||
virtual int CalculateBarSize() { return 0; }
|
||||
virtual bool SetScrolledAmount(float amount, bool forceUpdate);
|
||||
|
||||
virtual void SetContentSize(float size);
|
||||
virtual void SetViewableContentSize(float size);
|
||||
|
||||
virtual int GetButtonSize() { return 0; }
|
||||
virtual float GetScrolledAmount() { return m_fScrolledAmount; }
|
||||
|
||||
Gwen::Event::Caller onBarMoved;
|
||||
|
||||
protected:
|
||||
|
||||
ControlsInternal::ScrollBarButton* m_ScrollButton[2];
|
||||
ControlsInternal::ScrollBarBar * m_Bar;
|
||||
|
||||
bool m_bDepressed;
|
||||
float m_fScrolledAmount;
|
||||
float m_fContentSize;
|
||||
float m_fViewableContentSize;
|
||||
float m_fNudgeAmount;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
57
btgui/Gwen/Controls/ScrollBarBar.cpp
Normal file
57
btgui/Gwen/Controls/ScrollBarBar.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ScrollBar.h"
|
||||
#include "Gwen/Controls/ScrollBarBar.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
//Actual bar representing height of parent
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ScrollBarBar )
|
||||
{
|
||||
RestrictToParent( true );
|
||||
SetTarget( this );
|
||||
}
|
||||
|
||||
void ScrollBarBar::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawScrollBarBar(this, m_bDepressed, IsHovered(), m_bHorizontal );
|
||||
BaseClass::Render( skin );
|
||||
}
|
||||
|
||||
void ScrollBarBar::OnMouseMoved( int x, int y, int deltaX, int deltaY )
|
||||
{
|
||||
BaseClass::OnMouseMoved( x, y, deltaX, deltaY );
|
||||
|
||||
if ( !m_bDepressed )
|
||||
return;
|
||||
|
||||
InvalidateParent();
|
||||
}
|
||||
|
||||
void ScrollBarBar::OnMouseClickLeft( int x, int y, bool bDown )
|
||||
{
|
||||
BaseClass::OnMouseClickLeft( x, y, bDown );
|
||||
InvalidateParent();
|
||||
}
|
||||
|
||||
void ScrollBarBar::Layout( Skin::Base* /*skin*/ )
|
||||
{
|
||||
if ( !GetParent() )
|
||||
return;
|
||||
|
||||
//Move to our current position to force clamping - is this a hack?
|
||||
MoveTo( X(), Y() );
|
||||
}
|
||||
|
||||
void ScrollBarBar::MoveTo( int x, int y )
|
||||
{
|
||||
BaseClass::MoveTo( x, y );
|
||||
}
|
46
btgui/Gwen/Controls/ScrollBarBar.h
Normal file
46
btgui/Gwen/Controls/ScrollBarBar.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_SCROLLBARBAR_H
|
||||
#define GWEN_CONTROLS_SCROLLBARBAR_H
|
||||
|
||||
#include "Gwen/Controls/Dragger.h"
|
||||
#include "Gwen/Gwen.h"
|
||||
#include "Gwen/Skin.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace ControlsInternal
|
||||
{
|
||||
class GWEN_EXPORT ScrollBarBar : public ControlsInternal::Dragger
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( ScrollBarBar, ControlsInternal::Dragger );
|
||||
|
||||
virtual void Render( Skin::Base* skin );
|
||||
virtual void Layout( Skin::Base* skin );
|
||||
|
||||
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
|
||||
virtual void OnMouseClickLeft( int x, int y, bool bDown );
|
||||
|
||||
virtual void MoveTo(int x, int y);
|
||||
|
||||
virtual void SetHorizontal() { m_bHorizontal = true; }
|
||||
virtual void SetVertical() { m_bHorizontal = false; }
|
||||
virtual bool IsVertical() { return !m_bHorizontal; }
|
||||
virtual bool IsHorizontal() { return m_bHorizontal; }
|
||||
virtual bool IsDepressed() { return m_bDepressed; }
|
||||
|
||||
protected:
|
||||
|
||||
bool m_bHorizontal;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
45
btgui/Gwen/Controls/ScrollBarButton.cpp
Normal file
45
btgui/Gwen/Controls/ScrollBarButton.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ScrollBar.h"
|
||||
#include "Gwen/Controls/ScrollBarButton.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ScrollBarButton )
|
||||
{
|
||||
m_iDirection = 0;
|
||||
SetBounds(0,0,0,0);
|
||||
}
|
||||
|
||||
void ScrollBarButton::SetDirectionUp()
|
||||
{
|
||||
m_iDirection = Pos::Top;
|
||||
}
|
||||
|
||||
void ScrollBarButton::SetDirectionDown()
|
||||
{
|
||||
m_iDirection = Pos::Bottom;
|
||||
}
|
||||
|
||||
void ScrollBarButton::SetDirectionLeft()
|
||||
{
|
||||
m_iDirection = Pos::Left;
|
||||
}
|
||||
|
||||
void ScrollBarButton::SetDirectionRight()
|
||||
{
|
||||
m_iDirection = Pos::Right;
|
||||
}
|
||||
|
||||
void ScrollBarButton::Render( Skin::Base* skin )
|
||||
{
|
||||
skin->DrawScrollButton( this, m_iDirection, m_bDepressed );
|
||||
}
|
36
btgui/Gwen/Controls/ScrollBarButton.h
Normal file
36
btgui/Gwen/Controls/ScrollBarButton.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GWEN_CONTROLS_SCROLLBARBOTTON_H
|
||||
#define GWEN_CONTROLS_SCROLLBARBOTTON_H
|
||||
|
||||
#include "Gwen/Controls/Button.h"
|
||||
|
||||
namespace Gwen
|
||||
{
|
||||
namespace ControlsInternal
|
||||
{
|
||||
class GWEN_EXPORT ScrollBarButton : public Controls::Button
|
||||
{
|
||||
public:
|
||||
|
||||
GWEN_CONTROL( ScrollBarButton, Controls::Button );
|
||||
|
||||
void Render( Skin::Base* skin );
|
||||
|
||||
void SetDirectionUp();
|
||||
void SetDirectionDown();
|
||||
void SetDirectionLeft();
|
||||
void SetDirectionRight();
|
||||
|
||||
protected:
|
||||
|
||||
int m_iDirection;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
242
btgui/Gwen/Controls/ScrollControl.cpp
Normal file
242
btgui/Gwen/Controls/ScrollControl.cpp
Normal file
@ -0,0 +1,242 @@
|
||||
/*
|
||||
GWEN
|
||||
Copyright (c) 2010 Facepunch Studios
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ScrollControl.h"
|
||||
#include "Gwen/Controls/ScrollBar.h"
|
||||
#include "Gwen/Controls/VerticalScrollBar.h"
|
||||
#include "Gwen/Controls/HorizontalScrollBar.h"
|
||||
#include "Gwen/Utility.h"
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
using namespace Gwen::ControlsInternal;
|
||||
|
||||
GWEN_CONTROL_CONSTRUCTOR( ScrollControl )
|
||||
{
|
||||
SetMouseInputEnabled( false );
|
||||
|
||||
m_VerticalScrollBar = new VerticalScrollBar( this );
|
||||
m_VerticalScrollBar->Dock(Pos::Right);
|
||||
m_VerticalScrollBar->onBarMoved.Add( this, &ScrollControl::VBarMoved );
|
||||
m_VerticalScrollBar->SetNudgeAmount( 30 );
|
||||
m_bCanScrollV = true;
|
||||
|
||||
m_HorizontalScrollBar = new HorizontalScrollBar( this );
|
||||
m_HorizontalScrollBar->Dock( Pos::Bottom );
|
||||
m_HorizontalScrollBar->onBarMoved.Add( this, &ScrollControl::HBarMoved );
|
||||
m_bCanScrollH = true;
|
||||
m_HorizontalScrollBar->SetNudgeAmount( 30 );
|
||||
|
||||
m_InnerPanel = new Base( this );
|
||||
m_InnerPanel->SetPos(0, 0);
|
||||
m_InnerPanel->SetMargin( Margin(5,5,5,5));
|
||||
m_InnerPanel->SendToBack();
|
||||
m_InnerPanel->SetMouseInputEnabled( false );
|
||||
|
||||
m_bAutoHideBars = false;
|
||||
}
|
||||
|
||||
void ScrollControl::SetScroll( bool h, bool v )
|
||||
{
|
||||
m_bCanScrollV = v;
|
||||
m_bCanScrollH = h;
|
||||
m_VerticalScrollBar->SetHidden( !m_bCanScrollV );
|
||||
m_HorizontalScrollBar->SetHidden( !m_bCanScrollH );
|
||||
}
|
||||
|
||||
void ScrollControl::SetInnerSize( int w, int h )
|
||||
{
|
||||
m_InnerPanel->SetSize( w, h );
|
||||
}
|
||||
|
||||
void ScrollControl::VBarMoved( Controls::Base * /*control*/ )
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ScrollControl::HBarMoved( Controls::Base * /*control*/ )
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void ScrollControl::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ )
|
||||
{
|
||||
UpdateScrollBars();
|
||||
}
|
||||
|
||||
void ScrollControl::Layout( Skin::Base* skin )
|
||||
{
|
||||
UpdateScrollBars();
|
||||
BaseClass::Layout(skin);
|
||||
}
|
||||
|
||||
bool ScrollControl::OnMouseWheeled( int iDelta )
|
||||
{
|
||||
if ( CanScrollV() && m_VerticalScrollBar->Visible() )
|
||||
{
|
||||
if ( m_VerticalScrollBar->SetScrolledAmount( m_VerticalScrollBar->GetScrolledAmount() - m_VerticalScrollBar->GetNudgeAmount() * ( (float)iDelta / 60.0f ), true) )
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( CanScrollH() && m_HorizontalScrollBar->Visible() )
|
||||
{
|
||||
if ( m_HorizontalScrollBar->SetScrolledAmount( m_HorizontalScrollBar->GetScrolledAmount() - m_HorizontalScrollBar->GetNudgeAmount() * ( (float)iDelta / 60.0f ), true) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void ScrollControl::Render( Skin::Base* skin )
|
||||
{
|
||||
|
||||
#if 0
|
||||
|
||||
// Debug render - this shouldn't render ANYTHING REALLY - it should be up to the parent!
|
||||
|
||||
Gwen::Rect rect = GetRenderBounds();
|
||||
Gwen::Renderer::Base* render = skin->GetRender();
|
||||
|
||||
render->SetDrawColor( Gwen::Color( 255, 255, 0, 100 ) );
|
||||
render->DrawFilledRect( rect );
|
||||
|
||||
render->SetDrawColor( Gwen::Color( 255, 0, 0, 100 ) );
|
||||
render->DrawFilledRect( m_InnerPanel->GetBounds() );
|
||||
|
||||
render->RenderText( skin->GetDefaultFont(), Gwen::Point( 0, 0 ), Utility::Format( L"Offset: %i %i", m_InnerPanel->X(), m_InnerPanel->Y() ) );
|
||||
|
||||
#else //0
|
||||
|
||||
(void)skin;
|
||||
|
||||
#endif //0
|
||||
}
|
||||
|
||||
void ScrollControl::UpdateScrollBars()
|
||||
{
|
||||
if ( !m_InnerPanel )
|
||||
return;
|
||||
|
||||
int childrenWidth = 0;
|
||||
int childrenHeight = 0;
|
||||
|
||||
//Get the max size of all our children together
|
||||
for ( Base::List::iterator iter = m_InnerPanel->Children.begin(); iter != m_InnerPanel->Children.end(); ++iter )
|
||||
{
|
||||
Base* pChild = *iter;
|
||||
|
||||
childrenWidth = Utility::Max( childrenWidth, pChild->Right() );
|
||||
childrenHeight = Utility::Max( childrenHeight, pChild->Bottom() );
|
||||
}
|
||||
|
||||
m_InnerPanel->SetSize( Utility::Max(Width(), childrenWidth), Utility::Max(Height(), childrenHeight));
|
||||
|
||||
float wPercent = (float)Width() / (float)(childrenWidth + (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width()));
|
||||
float hPercent = (float)Height() / (float)(childrenHeight + (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()));
|
||||
|
||||
if ( m_bCanScrollV )
|
||||
SetVScrollRequired( hPercent >= 1 );
|
||||
else
|
||||
m_VerticalScrollBar->SetHidden( true );
|
||||
|
||||
if ( m_bCanScrollH )
|
||||
SetHScrollRequired( wPercent >= 1 );
|
||||
else
|
||||
m_HorizontalScrollBar->SetHidden( true );
|
||||
|
||||
|
||||
m_VerticalScrollBar->SetContentSize( m_InnerPanel->Height() );
|
||||
m_VerticalScrollBar->SetViewableContentSize( Height() - (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()));
|
||||
|
||||
|
||||
m_HorizontalScrollBar->SetContentSize( m_InnerPanel->Width() );
|
||||
m_HorizontalScrollBar->SetViewableContentSize( Width() - (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width()) );
|
||||
|
||||
int newInnerPanelPosX = 0;
|
||||
int newInnerPanelPosY = 0;
|
||||
|
||||
if ( CanScrollV() && !m_VerticalScrollBar->Hidden() )
|
||||
{
|
||||
newInnerPanelPosY = -( ( m_InnerPanel->Height() ) - Height() + (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()) ) * m_VerticalScrollBar->GetScrolledAmount();
|
||||
}
|
||||
if ( CanScrollH() && !m_HorizontalScrollBar->Hidden() )
|
||||
{
|
||||
newInnerPanelPosX = - ( ( m_InnerPanel->Width() ) - Width() + (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width())) * m_HorizontalScrollBar->GetScrolledAmount();
|
||||
}
|
||||
|
||||
m_InnerPanel->SetPos( newInnerPanelPosX , newInnerPanelPosY );
|
||||
}
|
||||
|
||||
void ScrollControl::SetVScrollRequired(bool req)
|
||||
{
|
||||
if ( req )
|
||||
{
|
||||
m_VerticalScrollBar->SetScrolledAmount( 0, true );
|
||||
m_VerticalScrollBar->SetDisabled( true );
|
||||
|
||||
if ( m_bAutoHideBars )
|
||||
m_VerticalScrollBar->SetHidden( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_VerticalScrollBar->SetHidden( false );
|
||||
m_VerticalScrollBar->SetDisabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollControl::SetHScrollRequired(bool req)
|
||||
{
|
||||
if ( req )
|
||||
{
|
||||
m_HorizontalScrollBar->SetScrolledAmount( 0, true );
|
||||
m_HorizontalScrollBar->SetDisabled( true );
|
||||
if ( m_bAutoHideBars )
|
||||
m_HorizontalScrollBar->SetHidden( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HorizontalScrollBar->SetHidden( false );
|
||||
m_HorizontalScrollBar->SetDisabled( true );
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollControl::ScrollToBottom()
|
||||
{
|
||||
if ( CanScrollV() )
|
||||
{
|
||||
UpdateScrollBars();
|
||||
m_VerticalScrollBar->ScrollToBottom();
|
||||
}
|
||||
}
|
||||
void ScrollControl::ScrollToTop()
|
||||
{
|
||||
if ( CanScrollV() )
|
||||
{
|
||||
UpdateScrollBars();
|
||||
m_VerticalScrollBar->ScrollToTop();
|
||||
}
|
||||
}
|
||||
void ScrollControl::ScrollToLeft()
|
||||
{
|
||||
if ( CanScrollH() )
|
||||
{
|
||||
UpdateScrollBars();
|
||||
m_HorizontalScrollBar->ScrollToLeft();
|
||||
}
|
||||
}
|
||||
void ScrollControl::ScrollToRight()
|
||||
{
|
||||
if ( CanScrollH() )
|
||||
{
|
||||
UpdateScrollBars();
|
||||
m_HorizontalScrollBar->ScrollToRight();
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollControl::Clear()
|
||||
{
|
||||
m_InnerPanel->RemoveAllChildren();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user