Origin Point support for Scale and Angle in UI Controls.

This commit is contained in:
Martín Lucas Golini
2016-02-29 03:58:45 -03:00
parent fe7309f9f4
commit 1ac065fa29
5 changed files with 150 additions and 28 deletions

View File

@@ -10,6 +10,7 @@
#include <eepp/math/interpolation.hpp>
#include <eepp/math/waypoints.hpp>
#include <eepp/math/math.hpp>
#include <eepp/math/originpoint.hpp>
using namespace EE::Math;
#include <eepp/system/bitop.hpp>

View File

@@ -247,6 +247,7 @@ class EE_API UIControl {
Vector2i mPos;
Vector2i mScreenPos;
Vector2f mScreenPosf;
Sizei mSize;
Uint32 mFlags;
@@ -322,6 +323,8 @@ class EE_API UIControl {
virtual void UpdateQuad();
virtual void UpdateCenter();
virtual void MatrixSet();
virtual void MatrixUnset();

View File

@@ -23,11 +23,27 @@ class EE_API UIControlAnim : public UIDragable {
void Angle( const Float& angle );
void Angle( const Float& angle, const OriginPoint& center );
const OriginPoint& AngleOriginPoint() const;
void AngleOriginPoint( const OriginPoint& center );
Vector2f AngleCenter();
const Vector2f& Scale() const;
void Scale( const Vector2f& scale );
void Scale( const Float& scale );
void Scale( const Vector2f& scale, const OriginPoint& center );
void Scale( const Float& scale , const OriginPoint & center = OriginPoint::OriginCenter );
const OriginPoint& ScaleOriginPoint() const;
void ScaleOriginPoint( const OriginPoint& center );
Vector2f ScaleCenter();
const Float& Alpha() const;
@@ -68,9 +84,12 @@ class EE_API UIControlAnim : public UIDragable {
bool FadingOut();
protected:
friend class UIManager;
friend class UIControl;
Float mAngle;
OriginPoint mAngleOriginPoint;
Vector2f mScale;
OriginPoint mScaleOriginPoint;
Float mAlpha;
Interpolation * mAngleAnim;
@@ -86,6 +105,8 @@ class EE_API UIControlAnim : public UIDragable {
virtual void UpdateQuad();
virtual void OnSizeChange();
virtual void OnAngleChange();
virtual void OnScaleChange();
@@ -95,6 +116,8 @@ class EE_API UIControlAnim : public UIDragable {
virtual void MatrixSet();
virtual void MatrixUnset();
void UpdateOriginPoint();
};
}}

View File

@@ -120,11 +120,13 @@ bool UIControl::IsInside( const Vector2i& Pos ) const {
void UIControl::Pos( const Vector2i& Pos ) {
mPos = Pos;
OnPosChange();
}
void UIControl::Pos( const Int32& x, const Int32& y ) {
mPos = Vector2i( x, y );
OnPosChange();
}
@@ -250,7 +252,7 @@ void UIControl::Draw() {
BorderDraw();
if ( NULL != mSkinState )
mSkinState->Draw( (Float)mScreenPos.x, (Float)mScreenPos.y, (Float)mSize.Width(), (Float)mSize.Height(), 255 );
mSkinState->Draw( mScreenPosf.x, mScreenPosf.y, (Float)mSize.Width(), (Float)mSize.Height(), 255 );
if ( UIManager::instance()->HighlightFocus() && UIManager::instance()->FocusControl() == this ) {
Primitives P;
@@ -514,11 +516,13 @@ void UIControl::OnPosChange() {
}
void UIControl::OnSizeChange() {
UpdateCenter();
SendCommonEvent( UIEvent::EventOnSizeChange );
}
Rectf UIControl::GetRectf() {
return Rectf( Vector2f( (Float)mScreenPos.x, (Float)mScreenPos.y ), Sizef( (Float)mSize.Width(), (Float)mSize.Height() ) );
return Rectf( mScreenPosf, Sizef( (Float)mSize.Width(), (Float)mSize.Height() ) );
}
void UIControl::BackgroundDraw() {
@@ -551,7 +555,7 @@ void UIControl::BorderDraw() {
//! @TODO: Check why was this +0.1f -0.1f?
if ( mFlags & UI_CLIP_ENABLE ) {
Rectf R( Vector2f( (Float)mScreenPos.x + 0.1f, (Float)mScreenPos.y + 0.1f ), Sizef( (Float)mSize.Width() - 0.1f, (Float)mSize.Height() - 0.1f ) );
Rectf R( Vector2f( mScreenPosf.x + 0.1f, mScreenPosf.y + 0.1f ), Sizef( (Float)mSize.Width() - 0.1f, (Float)mSize.Height() - 0.1f ) );
if ( mBackground->Corners() ) {
P.DrawRoundedRectangle( GetRectf(), 0.f, Vector2f::One, mBackground->Corners() );
@@ -871,8 +875,7 @@ const Vector2f& UIControl::GetPolygonCenter() const {
}
void UIControl::UpdateQuad() {
mPoly = Polygon2f( eeAABB( (Float)mScreenPos.x, (Float)mScreenPos.y, (Float)mScreenPos.x + mSize.Width(), (Float)mScreenPos.y + mSize.Height() ) );
mCenter = Vector2f( (Float)mScreenPos.x + (Float)mSize.Width() * 0.5f, (Float)mScreenPos.y + (Float)mSize.Height() * 0.5f );
mPoly = Polygon2f( eeAABB( mScreenPosf.x, mScreenPosf.y, mScreenPosf.x + mSize.Width(), mScreenPosf.y + mSize.Height() ) );
UIControl * tParent = Parent();
@@ -880,14 +883,18 @@ void UIControl::UpdateQuad() {
if ( tParent->IsAnimated() ) {
UIControlAnim * tP = reinterpret_cast<UIControlAnim *> ( tParent );
mPoly.Rotate( tP->Angle(), tP->GetPolygonCenter() );
mPoly.Scale( tP->Scale(), tP->GetPolygonCenter() );
mPoly.Rotate( tP->Angle(), tP->AngleCenter() );
mPoly.Scale( tP->Scale(), tP->ScaleCenter() );
}
tParent = tParent->Parent();
};
}
void UIControl::UpdateCenter() {
mCenter = Vector2f( mScreenPosf.x + (Float)mSize.Width() * 0.5f, mScreenPosf.y + (Float)mSize.Height() * 0.5f );
}
Time UIControl::Elapsed() {
return UIManager::instance()->Elapsed();
}
@@ -1031,6 +1038,9 @@ void UIControl::UpdateScreenPos() {
ControlToScreen( Pos );
mScreenPos = Pos;
mScreenPosf = Vector2f( Pos.x, Pos.y );
UpdateCenter();
}
UISkin * UIControl::GetSkin() {
@@ -1238,9 +1248,10 @@ void UIControl::WorldToControl( Vector2i& pos ) const {
UIControl * tParent = (*it);
UIControlAnim * tP = tParent->IsAnimated() ? reinterpret_cast<UIControlAnim *> ( tParent ) : NULL;
Vector2f pPos ( tParent->mPos.x * scale.x , tParent->mPos.y * scale.y );
Vector2f Center ( tParent->mSize.x * 0.5f * scale.x , tParent->mSize.y * 0.5f * scale.y );
Vector2f Center;
if ( NULL != tP && 1.f != tP->Scale() ) {
Center = tP->ScaleOriginPoint() * scale;
scale *= tP->Scale();
pPos.Scale( scale, pPos + Center );
@@ -1249,7 +1260,7 @@ void UIControl::WorldToControl( Vector2i& pos ) const {
Pos -= pPos;
if ( NULL != tP && 0.f != tP->Angle() ) {
Center = Vector2f( tParent->mSize.x * 0.5f * scale.x , tParent->mSize.y * 0.5f * scale.y );
Center = tP->AngleOriginPoint() * scale;
Pos.Rotate( -tP->Angle(), Center );
}
}
@@ -1275,13 +1286,15 @@ void UIControl::ControlToWorld( Vector2i& pos ) const {
UIControl * tParent = (*it);
UIControlAnim * tP = tParent->IsAnimated() ? reinterpret_cast<UIControlAnim *> ( tParent ) : NULL;
Vector2f pPos ( tParent->mPos.x , tParent->mPos.y );
Vector2f Center ( pPos.x + tParent->mSize.x * 0.5f , pPos.y + tParent->mSize.y * 0.5f );
Pos += pPos;
if ( NULL != tP ) {
Pos.Rotate( tP->Angle(), Center );
Pos.Scale( tP->Scale(), Center );
Vector2f CenterAngle( pPos.x + tP->mAngleOriginPoint.x, pPos.y + tP->mAngleOriginPoint.y );
Vector2f CenterScale( pPos.x + tP->mScaleOriginPoint.x, pPos.y + tP->mScaleOriginPoint.y );
Pos.Rotate( tP->Angle(), CenterAngle );
Pos.Scale( tP->Scale(), CenterScale );
}
}

View File

@@ -17,6 +17,8 @@ UIControlAnim::UIControlAnim( const CreateParams& Params ) :
mMoveAnim(NULL)
{
mControlFlags |= UI_CTRL_FLAG_ANIM;
UpdateOriginPoint();
}
UIControlAnim::~UIControlAnim() {
@@ -43,7 +45,7 @@ void UIControlAnim::Draw() {
BorderDraw();
if ( NULL != mSkinState )
mSkinState->Draw( (Float)mScreenPos.x, (Float)mScreenPos.y, (Float)mSize.Width(), (Float)mSize.Height(), (Uint32)mAlpha );
mSkinState->Draw( mScreenPosf.x, mScreenPosf.y, (Float)mSize.Width(), (Float)mSize.Height(), (Uint32)mAlpha );
if ( UIManager::instance()->HighlightFocus() && UIManager::instance()->FocusControl() == this ) {
Primitives P;
@@ -67,22 +69,68 @@ const Float& UIControlAnim::Angle() const {
return mAngle;
}
const OriginPoint& UIControlAnim::AngleOriginPoint() const {
return mAngleOriginPoint;
}
void UIControlAnim::AngleOriginPoint( const OriginPoint & center ) {
mAngleOriginPoint = center;
UpdateOriginPoint();
}
Vector2f UIControlAnim::AngleCenter() {
switch ( mAngleOriginPoint.OriginType ) {
case OriginPoint::OriginCenter: return mCenter;
case OriginPoint::OriginTopLeft: return mScreenPosf;
case OriginPoint::OriginCustom: default: return mScreenPosf + mAngleOriginPoint;
}
}
void UIControlAnim::Angle( const Float& angle ) {
mAngle = angle;
OnAngleChange();
}
void UIControlAnim::Angle( const Float& angle , const OriginPoint & center ) {
mAngleOriginPoint = center;
UpdateOriginPoint();
Angle( angle );
}
const Vector2f& UIControlAnim::Scale() const {
return mScale;
}
void UIControlAnim::Scale( const Vector2f& scale ) {
void UIControlAnim::Scale( const Vector2f & scale ) {
mScale = scale;
OnScaleChange();
}
void UIControlAnim::Scale( const Float& scale ) {
Scale( Vector2f( scale, scale ) );
const OriginPoint& UIControlAnim::ScaleOriginPoint() const {
return mScaleOriginPoint;
}
void UIControlAnim::ScaleOriginPoint( const OriginPoint & center ) {
mScaleOriginPoint = center;
UpdateOriginPoint();
}
Vector2f UIControlAnim::ScaleCenter() {
switch ( mScaleOriginPoint.OriginType ) {
case OriginPoint::OriginCenter: return mCenter;
case OriginPoint::OriginTopLeft: return mScreenPosf;
case OriginPoint::OriginCustom: default: return mScreenPosf + mScaleOriginPoint;
}
}
void UIControlAnim::Scale( const Vector2f& scale, const OriginPoint& center ) {
mScaleOriginPoint = center;
UpdateOriginPoint();
Scale( scale );
}
void UIControlAnim::Scale( const Float& scale, const OriginPoint& center ) {
Scale( Vector2f( scale, scale ), center );
}
const Float& UIControlAnim::Alpha() const {
@@ -113,18 +161,25 @@ void UIControlAnim::AlphaChilds( const Float &alpha ) {
void UIControlAnim::MatrixSet() {
if ( mScale != 1.f || mAngle != 0.f ) {
GlobalBatchRenderer::instance()->Draw();
GLi->PushMatrix();
Vector2f Center( mScreenPos.x + mSize.Width() * 0.5f, mScreenPos.y + mSize.Height() * 0.5f );
GLi->Translatef( Center.x , Center.y, 0.f );
GLi->Rotatef( mAngle, 0.0f, 0.0f, 1.0f );
Vector2f scaleCenter = ScaleCenter();
GLi->Translatef( scaleCenter.x , scaleCenter.y, 0.f );
GLi->Scalef( mScale.x, mScale.y, 1.0f );
GLi->Translatef( -Center.x, -Center.y, 0.f );
GLi->Translatef( -scaleCenter.x, -scaleCenter.y, 0.f );
Vector2f angleCenter = AngleCenter();
GLi->Translatef( angleCenter.x , angleCenter.y, 0.f );
GLi->Rotatef( mAngle, 0.0f, 0.0f, 1.0f );
GLi->Translatef( -angleCenter.x, -angleCenter.y, 0.f );
}
}
void UIControlAnim::MatrixUnset() {
if ( mScale != 1.f || mAngle != 0.f ) {
GlobalBatchRenderer::instance()->Draw();
GLi->PopMatrix();
}
}
@@ -320,7 +375,7 @@ void UIControlAnim::BorderDraw() {
//! @TODO: Check why was this +0.1f -0.1f?
if ( mFlags & UI_CLIP_ENABLE ) {
Rectf R( Vector2f( (Float)mScreenPos.x + 0.1f, (Float)mScreenPos.y + 0.1f ), Sizef( (Float)mSize.Width() - 0.1f, (Float)mSize.Height() - 0.1f ) );
Rectf R( Vector2f( mScreenPosf.x + 0.1f, mScreenPosf.y + 0.1f ), Sizef( (Float)mSize.Width() - 0.1f, (Float)mSize.Height() - 0.1f ) );
if ( mBackground->Corners() ) {
P.DrawRoundedRectangle( GetRectf(), 0.f, Vector2f::One, mBackground->Corners() );
@@ -341,11 +396,10 @@ ColorA UIControlAnim::GetColor( const ColorA& Col ) {
}
void UIControlAnim::UpdateQuad() {
mPoly = Polygon2f( eeAABB( (Float)mScreenPos.x, (Float)mScreenPos.y, (Float)mScreenPos.x + mSize.Width(), (Float)mScreenPos.y + mSize.Height() ) );
mCenter = Vector2f( (Float)mScreenPos.x + (Float)mSize.Width() * 0.5f, (Float)mScreenPos.y + (Float)mSize.Height() * 0.5f );
mPoly = Polygon2f( eeAABB( mScreenPosf.x, mScreenPosf.y, mScreenPosf.x + mSize.Width(), mScreenPosf.y + mSize.Height() ) );
mPoly.Rotate( mAngle, mCenter );
mPoly.Scale( mScale, mCenter );
mPoly.Rotate( mAngle, AngleCenter() );
mPoly.Scale( mScale, ScaleCenter() );
UIControl * tParent = Parent();
@@ -353,14 +407,42 @@ void UIControlAnim::UpdateQuad() {
if ( tParent->IsAnimated() ) {
UIControlAnim * tP = reinterpret_cast<UIControlAnim *> ( tParent );
mPoly.Rotate( tP->Angle(), tP->GetPolygonCenter() );
mPoly.Scale( tP->Scale(), tP->GetPolygonCenter() );
mPoly.Rotate( tP->Angle(), tP->AngleCenter() );
mPoly.Scale( tP->Scale(), tP->ScaleCenter() );
}
tParent = tParent->Parent();
};
}
void UIControlAnim::OnSizeChange() {
UpdateOriginPoint();
}
void UIControlAnim::UpdateOriginPoint() {
switch ( mAngleOriginPoint.OriginType ) {
case OriginPoint::OriginCenter:
mAngleOriginPoint.x = mSize.x * 0.5f;
mAngleOriginPoint.y = mSize.y * 0.5f;
break;
case OriginPoint::OriginTopLeft:
mAngleOriginPoint.x = mAngleOriginPoint.y = 0;
break;
default: {}
}
switch ( mScaleOriginPoint.OriginType ) {
case OriginPoint::OriginCenter:
mScaleOriginPoint.x = mSize.x * 0.5f;
mScaleOriginPoint.y = mSize.y * 0.5f;
break;
case OriginPoint::OriginTopLeft:
mScaleOriginPoint.x = mScaleOriginPoint.y = 0;
break;
default: {}
}
}
Interpolation * UIControlAnim::RotationInterpolation() {
if ( NULL == mAngleAnim )
mAngleAnim = eeNew( Interpolation, () );