Files
2026-06-01 12:46:52 +02:00

561 lines
14 KiB
C++

#include "stdafx.h"
#include "KViewport.h"
#include "KUIControlClockBox.h"
#include <toolkit/SafeTickCount.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KClockBoxPrimitive Implement
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
KClockBoxPrimitive::KClockBoxPrimitive()
{
m_nCurDegree = 0;
m_bReverse = false;
m_colSprite = KColor(255,255,255,255);
m_alpha = MAX_ALPHA;
}
KClockBoxPrimitive::~KClockBoxPrimitive()
{
}
bool KClockBoxPrimitive::SetClockDegree( int nDegree, bool bReverse )
{
if( m_nCurDegree != nDegree || m_bReverse != bReverse )
{
m_nCurDegree = nDegree;
m_bReverse = bReverse;
return true;
}
return false;
}
void KClockBoxPrimitive::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum )
{
K3DVector pos;
K3DMatrixGetPosVector( pos, m_matTransform );
float sprtx,sprty;
sprtx = pos.x + m_fTargetWidth;
sprty = pos.y + m_fTargetHeight;
K3DVector center;
center.x = pos.x + m_fTargetWidth / 2.f;
center.y = pos.y + m_fTargetHeight / 2.f;
float fZPos = pos.z / KSpritePrimitive::s_fLayerDevider;
const float UNIT = 8.f / 360.f;
float fCurVtx = (float)(m_nCurDegree) * UNIT; // 0~8 사이
// 현재 Vertex의 offset
float fCurVtxOffset = static_cast<float>( static_cast<int>( fCurVtx ) + 1) - fCurVtx;
int nCurVtxSize = fCurVtx + 2 + (fCurVtxOffset >= 1.0f ? 0 : 1 );
// 꽉찬경우 offset은 0으로 해줘야 한다..
fCurVtxOffset = fCurVtxOffset - static_cast<int>( fCurVtxOffset );
if( m_nCurDegree == 0)
return;
// 공통
for(int i = 0; i < nCurVtxSize; ++i)
{
m_ClockVtxBuf[i].z = fZPos;
m_ClockVtxBuf[i].color = m_colSprite.color;
//ClockBox는 윈도우 가 알파 처리 되더라도 항상 일정한 알파 값을 사용해야 하기 때문에 알파값을 그냥 고정해 버린다.
// 퀵 슬롯에서 알파값이 조절가능해야 되기 때문에 수정함 - prodongi
m_ClockVtxBuf[i].color.a = (unsigned char)m_alpha;//200;
}
// 가운데는 항상 Center
m_ClockVtxBuf[0].x = center.x; m_ClockVtxBuf[0].y = center.y;
m_ClockVtxBuf[1].x = center.x; m_ClockVtxBuf[1].y = pos.y;
float fPosX[3] = { pos.x, center.x, sprtx };
float fPosY[3] = { pos.y, center.y, sprty };
// 0 - pos, 1 - center, 2 - sprt
static int SELECT_UNIT[8][2];
if( m_bReverse )
{
static const int temp_unit[8][2] =
{
{ 2, 0 },
{ 2, 1 },
{ 2, 2 },
{ 1, 2 },
{ 0, 2 },
{ 0, 1 },
{ 0, 0 },
{ 1, 0 },
};
::memcpy( SELECT_UNIT, temp_unit, sizeof(temp_unit) );
}
else
{
static const int temp_uint[8][2] =
{
{ 0, 0 },
{ 0, 1 },
{ 0, 2 },
{ 1, 2 },
{ 2, 2 },
{ 2, 1 },
{ 2, 0 },
{ 1, 0 },
};
::memcpy( SELECT_UNIT, temp_uint, sizeof(temp_uint) );
}
nCurVtxSize = min( nCurVtxSize, 10);
for(int i = 2; i < nCurVtxSize; ++i)
{
m_ClockVtxBuf[i].x = fPosX[ SELECT_UNIT[i - 2][0] ];
m_ClockVtxBuf[i].y = fPosY[ SELECT_UNIT[i - 2][1] ];
}
static float DECEREASE_UNIT[8][2];
if( m_bReverse )
{
static const float temp_unit[8][2] =
{
{ -1.f, 0.f },
{ 0.f, -1.f },
{ 0.f, -1.f },
{ 1.f, 0.f },
{ 1.f, 0.f },
{ 0.f, 1.f },
{ 0.f, 1.f },
{ -1.f, 0.f },
};
::memcpy( DECEREASE_UNIT, temp_unit, sizeof(temp_unit) );
}
else
{
static const float temp_uint[8][2] =
{
{ 1.f, 0.f },
{ 0.f, -1.f },
{ 0.f, -1.f },
{ -1.f, 0.f },
{ -1.f, 0.f },
{ 0.f, 1.f },
{ 0.f, 1.f },
{ 1.f, 0.f },
};
::memcpy( DECEREASE_UNIT, temp_uint, sizeof(temp_uint) );
}
int nOffsetVtx = max( nCurVtxSize - 3, 0);
m_ClockVtxBuf[ nCurVtxSize - 1].x += DECEREASE_UNIT[ nOffsetVtx ][0] * fCurVtxOffset * m_fTargetWidth * .5f;
m_ClockVtxBuf[ nCurVtxSize - 1].y += DECEREASE_UNIT[ nOffsetVtx ][1] * fCurVtxOffset * m_fTargetHeight * .5;
#ifdef _KUI_INVALIDATION
// { [sonador]
for( int index = 0; index < nCurVtxSize; ++index )
{
m_ClockVtxBuf[ index ].x -= m_vRenderOffset.x;
m_ClockVtxBuf[ index ].y -= m_vRenderOffset.y;
}
// }
#endif
dev->SetTexture( 0, NULL);
dev->DrawTriangleFan( K3DFVF_XYZRHW | K3DFVF_DIFFUSE | K3DFVF_TEX1,
m_ClockVtxBuf, nCurVtxSize, s_nVertexStride);
}
void KClockBoxPrimitive::changeAlpha(float alpha)
{
int a = (int)(alpha * 255.0f);
if (0 > a) a = 0;
else if (MAX_ALPHA < a) a = MAX_ALPHA;
m_alpha = (unsigned int)a;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KUIControlClockBox Implement
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace
{
KUIWnd* Creator()
{
return new KUIControlClockBox;
}
bool bRegister = KUIFactory::GetInstance()->RegisterCreator( Creator, "clockbox");
}
KUIControlClockBox::KUIControlClockBox()
{
m_dwBeginTime = 0;
m_dwMaxTime = 0;
m_dwCurTime = 0;
m_dwTimeOffset = 0;
m_bBegin = false;
m_bInit = false;
m_bReverse = false;
_registerSprite( &m_prClock );
}
KUIControlClockBox::~KUIControlClockBox()
{
}
void KUIControlClockBox::Begin( bool bReverse )
{
m_bInit = false;
m_bBegin = true;
m_dwBeginTime = GetSafeTickCount();
m_dwTimeOffset = m_dwCurTime;
m_bReverse = bReverse;
}
void KUIControlClockBox::Stop()
{
m_bBegin = false;
m_dwBeginTime = 0;
m_dwTimeOffset = 0;
}
/*
* Init
* : 무조건 360' 꽉 채운 컨트롤을 보여준다
* // MJ 2004/11/10
*/
void KUIControlClockBox::Init()
{
m_bInit = true;
if( m_prClock.SetClockDegree( 360 ) )
InvalidateWnd();
Stop();
}
void KUIControlClockBox::Process(DWORD dwTime)
{
// assert( m_dwMaxTime && "MaxTime 이상" );
//m_dwMaxTime 이 0 일때도 처리 됨.
KUIControl::Process( dwTime );
if( m_bBegin )
{
DWORD dwTimeDiff = dwTime - m_dwBeginTime;
m_dwCurTime = m_dwTimeOffset + dwTimeDiff;
float fFactor = 360.f - static_cast<float>( m_dwCurTime ) / m_dwMaxTime * 360.f;
if( m_bReverse ) fFactor = 360.f - fFactor;
fFactor = max( 0.f, fFactor );
fFactor = min( 360.f, fFactor );
#ifdef _KUI_INVALIDATION
// { [sonador]
if( m_prClock.SetClockDegree( fFactor, m_bReverse ) )
InvalidateWnd();
// }
#else
m_prClock.SetClockDegree( fFactor, m_bReverse );
#endif
}
}
void KUIControlClockBox::Render(KViewportObject* pViewport, bool isFront)
{
if(m_bShowFlag)
{
pViewport->Register( &m_prClock, isFront);
_renderCaption(pViewport, isFront);
#ifndef _KUI_INVALIDATION
_renderToolTip(pViewport, isFront);
#endif
}
}
void KUIControlClockBox::OnAlphaChangeNotify(float fAlpha)
{
KUIControl::OnAlphaChangeNotify(fAlpha);
m_prClock.changeAlpha(fAlpha);
}
void KUIControlClockBox::_initControl()
{
m_prClock.SetPosition( m_rcRegion.left, m_rcRegion.top, m_fZPos);
m_prClock.SetTargetSize( m_rcRegion.GetWidth(), m_rcRegion.GetHeight() );
if( m_prClock.SetClockDegree( 0 ) )
InvalidateWnd();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KColorBoxPrimitive Implement
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
KColorBoxPrimitive::KColorBoxPrimitive()
{
m_colSprite = KColor(255,255,255,255);
for(int i = 0; i < 4; ++i)
m_fMasterVisibility[i] = 1.f;
}
KColorBoxPrimitive::~KColorBoxPrimitive()
{
}
void KColorBoxPrimitive::SetVisibility( float vis )
{
for(int i = 0; i < 4; ++i)
m_VtxBuf[i].color.a = (unsigned char)(m_fMasterVisibility[i] * vis * 255);
}
void KColorBoxPrimitive::SetIndexColor ( int nIndex, const KColor &color )
{
if( nIndex >= 0 && nIndex < COLOR_VTX )
{
m_VtxBuf[nIndex].color = color;
m_fMasterVisibility[nIndex] = (float)color.a/255.f;
}
}
void KColorBoxPrimitive::NoResUpdateSprite()
{
K3DMatrix matLocal;
K3DMatrixIdentity( matLocal );
K3DVector posParent, posLocal;
K3DMatrixGetPosVector( posParent, m_matTransform );
K3DMatrixGetPosVector( posLocal, matLocal);
K3DVector pos;
pos = posParent + posLocal;
float sprtx,sprty;
sprtx = pos.x + m_fTargetWidth;
sprty = pos.y + m_fTargetHeight;
K3DVector center;
center.x = pos.x + m_fTargetWidth / 2.f;
center.y = pos.y + m_fTargetHeight / 2.f;
float l = m_fLeft, t = m_fTop, r = m_fRight, b = m_fBottom;
// clipping 처리
if(m_pClipRect)
{
// No need to draw.
if ( m_pClipRect->left >= sprtx || m_pClipRect->top >= sprty ||
m_pClipRect->right <= pos.x || m_pClipRect->bottom <= pos.y )
{
m_bRenderValidate = false;
return;
}
KRect rect;
float uvwidth, uvheight;
uvwidth = r - l;
uvheight = b - t;
float scalew = 1.f;
float scaleh = 1.f;
if ( m_pClipRect->left > pos.x )
{
rect.left = m_pClipRect->left;
int d = int(rect.left - pos.x);
l += uvwidth * (float(d)/1) / scalew;
}
else rect.left = int(pos.x);
if ( m_pClipRect->top > pos.y )
{
rect.top = m_pClipRect->top;
int d = int(rect.top - pos.y);
t += uvheight * (float(d)/1) / scaleh;
}
else rect.top = int(pos.y);
if ( m_pClipRect->right < sprtx )
{
rect.right = m_pClipRect->right;
int d = int(sprtx - rect.right);
r -= uvwidth * (float(d)/1) / scalew;
}
else rect.right = int(sprtx);
if ( m_pClipRect->bottom < sprty )
{
rect.bottom = m_pClipRect->bottom;
int d = int(sprty - rect.bottom);
b -= uvheight * (float(d)/1) / scaleh;
}
else rect.bottom = int(sprty);
pos.x = (float)rect.left; pos.y = (float)rect.top; sprtx = (float)rect.right; sprty = (float)rect.bottom;
center.x = pos.x + ((sprtx - pos.x)/2.f);
center.y = pos.y + ((sprty - pos.y)/2.f);
}
// For rotating around center of the sprite.
pos.x -= center.x;
pos.y -= center.y;
sprtx -= center.x;
sprty -= center.y;
float fZPos = pos.z / s_fLayerDevider;
m_VtxBuf[0].x = pos.x; m_VtxBuf[1].x = sprtx;
m_VtxBuf[0].y = pos.y; m_VtxBuf[1].y = pos.y;
m_VtxBuf[0].z = fZPos; m_VtxBuf[1].z = fZPos;
m_VtxBuf[0].w = 1; m_VtxBuf[1].w = 1;
m_VtxBuf[0].u = l; m_VtxBuf[1].u = r;
m_VtxBuf[0].v = t; m_VtxBuf[1].v = t;
// m_VtxBuf[0].color = KColor(0,0,255,255); m_VtxBuf[1].color = KColor(255,0,0,255);
m_VtxBuf[2].x = pos.x; m_VtxBuf[3].x = sprtx;
m_VtxBuf[2].y = sprty; m_VtxBuf[3].y = sprty;
m_VtxBuf[2].z = fZPos; m_VtxBuf[3].z = fZPos;
m_VtxBuf[2].w = 1; m_VtxBuf[3].w = 1;
m_VtxBuf[2].u = l; m_VtxBuf[3].u = r;
m_VtxBuf[2].v = b; m_VtxBuf[3].v = b;
// m_VtxBuf[2].color = KColor(0,0,255,255); m_VtxBuf[3].color = KColor(255,0,0,255);
// Rotate
static float fMatRot[2][2];
fMatRot[0][0] = m_matTransform._11 * matLocal._11 + m_matTransform._12 * matLocal._21;
fMatRot[0][1] = m_matTransform._11 * matLocal._12 + m_matTransform._12 * matLocal._22;
fMatRot[1][0] = m_matTransform._21 * matLocal._11 + m_matTransform._22 * matLocal._21;
fMatRot[1][1] = m_matTransform._21 * matLocal._12 + m_matTransform._22 * matLocal._22;
for(int i = 0; i < 4; ++i)
{
float xOrg = m_VtxBuf[i].x;
// See DX Help - Directly Mapping Texels to Pixels
m_VtxBuf[i].x = xOrg * fMatRot[0][0] + m_VtxBuf[i].y * fMatRot[1][0] + center.x - 0.5f;
m_VtxBuf[i].y = xOrg * fMatRot[0][1] + m_VtxBuf[i].y * fMatRot[1][1] + center.y - 0.5f;
#ifdef _KUI_INVALIDATION
// { [sonador]
m_VtxBuf[i].x -= m_vRenderOffset.x;
m_VtxBuf[i].y -= m_vRenderOffset.y;
// }
#endif
}
m_bRenderValidate = true;
}
void KColorBoxPrimitive::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum /*= true*/ )
{
if(m_bModify && m_bRenderEnable)
{
NoResUpdateSprite();
m_bModify = false;
}
if(m_bRenderValidate && m_bRenderEnable )
{
dev->SetTexture( 0, NULL);
dev->DrawTriangleStrip( K3DFVF_XYZRHW | K3DFVF_DIFFUSE | K3DFVF_TEX1,
m_VtxBuf, 4, s_nVertexStride);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KUIControlColorBox Implement
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace
{
KUIWnd* colorboxCreator()
{
return new KUIControlColorBox;
}
bool bColorboxRegister = KUIFactory::GetInstance()->RegisterCreator( colorboxCreator, "colorbox");
const float c_fCOLOR_TIME = 5000.f;
}
KUIControlColorBox::KUIControlColorBox()
{
_registerSprite( &m_prColor );
m_weightColor = KColor(255,255,255,255);
m_nFlag = 0;
m_bEnableColorAni = false;
}
KUIControlColorBox::~KUIControlColorBox()
{
}
void KUIControlColorBox::OnAlphaChangeNotify(float fAlpha)
{
KUIControl::OnAlphaChangeNotify( fAlpha );
m_prColor.SetVisibility( fAlpha );
}
void KUIControlColorBox::Process(DWORD dwTime)
{
KUIControl::Process( dwTime );
m_dwTime = dwTime;
if( m_bEnableColorAni )
{
if( m_dwCheckTime == 0 )
m_dwCheckTime = dwTime;
if( m_dwTime - m_dwCheckTime > c_fCOLOR_TIME )
{
m_dwCheckTime = m_dwTime;
m_nFlag = m_nFlag == 0 ? 1 : 0;
}
else
{
float fDlt = 1.f;
if( m_nFlag )
fDlt = (m_dwTime - m_dwCheckTime)/c_fCOLOR_TIME;
else
fDlt = 1.f-(m_dwTime - m_dwCheckTime)/c_fCOLOR_TIME;
m_Color[0] = KColor( (1-fDlt)*m_weightColor.r, (1-fDlt)*m_weightColor.g, (1-fDlt)*m_weightColor.b, 255 );
m_Color[1] = KColor( (1-fDlt)*m_weightColor.r, (1-fDlt)*m_weightColor.g, (1-fDlt)*m_weightColor.b, 255 );
m_Color[2] = KColor( fDlt*m_weightColor.r, fDlt*m_weightColor.g, fDlt*m_weightColor.b, 255 );
m_Color[3] = KColor( fDlt*m_weightColor.r, fDlt*m_weightColor.g, fDlt*m_weightColor.b, 255 );
}
m_prColor.SetIndexColor( 0, m_Color[ 0 ] );
m_prColor.SetIndexColor( 1, m_Color[ 2 ] );
m_prColor.SetIndexColor( 2, m_Color[ 1 ] );
m_prColor.SetIndexColor( 3, m_Color[ 3 ] );
InvalidateWnd();
}
}
void KUIControlColorBox::Render(KViewportObject* pViewport, bool isFront /*= false*/ )
{
if(m_bShowFlag)
{
pViewport->Register( &m_prColor, isFront);
#ifndef _KUI_INVALIDATION
_renderToolTip(pViewport, isFront);
#endif
}
}
void KUIControlColorBox::_initControl()
{
m_prColor.SetPosition( m_rcRegion.left, m_rcRegion.top, m_fZPos);
m_prColor.SetTargetSize( m_rcRegion.GetWidth(), m_rcRegion.GetHeight() );
}