Files
Leviathan/Client/Game/engine/Ui/Controls/KUIControlGauge.cpp
T
2026-06-01 12:46:52 +02:00

289 lines
6.9 KiB
C++

#include "stdafx.h"
#include "KViewport.h"
#include "KUIControlStatic.h"
#include "KUIControlGauge.h"
#include "KResourceManager.h"
#include "KUIWndManager.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KUIControlGauge Implement
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace
{
KUIWnd* Creator()
{
return new KUIControlGauge;
}
bool bRegister = KUIFactory::GetInstance()->RegisterCreator( Creator, "gauge");
}
KUIControlGauge::KUIControlGauge()
{
m_dwCur = 0;
m_dwStart = 0;
m_dwMax = 100;
m_dwTarget = 0;
m_dwTime = 0;
m_dwStartTime = 0;
m_dwTargetTime = 0;
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
_registerSprite(&m_prSprite[i][j]);
}
m_bWithoutGhost = false;
m_bBackGround = false;
m_pBackGround = NULL;
}
KUIControlGauge::~KUIControlGauge()
{
}
void KUIControlGauge::SetGauge( DWORD dwDest, DWORD dwTime )
{
if( m_dwTarget != dwDest || m_dwStart != m_dwCur || m_dwStartTime != m_dwTime || m_dwTargetTime != m_dwTime + dwTime )
{
m_dwTarget = dwDest;
m_dwStart = m_dwCur;
m_dwStartTime = m_dwTime;
m_dwTargetTime = m_dwTime + dwTime;
InvalidateWnd();
}
}
void KUIControlGauge::SetMax( DWORD dwMax )
{
if( m_dwMax != dwMax )
{
m_dwMax = dwMax;
InvalidateWnd();
}
}
void KUIControlGauge::ReSizeBackGround()
{
if( m_pBackGround )
{
KRect rect = GetRect();
rect.left -= 2;
rect.right += 3;
rect.top -= 2;
rect.bottom += 4;
m_pBackGround->Resize( rect );
InvalidateWnd();
}
}
void KUIControlGauge::SetBackGround( const char * pAniName )
{
SAFE_DELETE( m_pBackGround );
if( pAniName == NULL )
{
m_bBackGround = false;
return;
}
m_bBackGround = true;
// BackGround 생성
KUIWND_CREATE_ARG arg;
arg.lpszSprName = m_sSprName.c_str();
arg.lpszAniName = pAniName;
arg.rcRect = GetRect();
//HP Gauge Back
arg.lpszAniName = pAniName;
arg.lpszClassName = "static";
arg.lpszID = "_hp_back";
arg.pParent = this;
arg.rcRect.left -= 2;
arg.rcRect.right += 3;
arg.rcRect.top -= 2;
arg.rcRect.bottom += 4;
arg.dwFlag = KFLAG_GET_PASS_MESSAGE | KFLAG_NO_GET_FOCUS;
m_pBackGround = reinterpret_cast<KUIControlStatic*>( m_pManager->CreateControl( arg ));
m_pBackGround->SetUsePosEnable( false );
InvalidateWnd();
}
void KUIControlGauge::Process( DWORD dwTime )
{
m_dwTime = dwTime;
if ( m_dwCur != m_dwTarget )
{
#ifdef _KUI_INVALIDATION
// { [sonador]
InvalidateWnd();
// }
#endif
int nDiff = (int)m_dwTarget - (int)m_dwStart;
float ratio = (m_dwTargetTime == m_dwStartTime) ? 1.f : ( float(m_dwTime + 1- m_dwStartTime) / float(m_dwTargetTime - m_dwStartTime) );
if ( ratio >= 1.0f )
{
m_dwCur = m_dwTarget;
return;
}
float fResult = (float)nDiff * ratio;
fResult = m_dwStart + fResult;
fResult = min(m_dwMax, (DWORD)fResult);
fResult = max(0.f, (float)fResult);
m_dwCur = (DWORD)fResult;
}
_processToolTip();
}
void KUIControlGauge::Render(KViewportObject * pViewport, bool isFront )
{
if(false == m_bShowFlag)
return;
// render BackGround
if( m_bBackGround && m_pBackGround )
m_pBackGround->Render( pViewport );
// render back
int nCount = m_bWithoutGhost ? 1 : 2;
_RenderPrimitive( nCount , m_rcRegion.GetWidth(), pViewport);
float mainRatio = std::min(1.f, ( (float)m_dwCur / m_dwMax) );
float ghostRatio = std::min(1.f, ( (float)m_dwTarget / m_dwMax) );
int nLenGhost, nLenMain;
nLenMain = (int)((float)m_rcRegion.GetWidth() * mainRatio);
nLenGhost = (int)((float)m_rcRegion.GetWidth() * ghostRatio);
if ( m_dwCur > m_dwTarget )
std::swap( nLenMain, nLenGhost );
// Ghost(잔상) 렌더링
if(false == m_bWithoutGhost)
{
_RenderPrimitive( 1, nLenGhost, pViewport);
}
// 실제 Gauge 렌더링
_RenderPrimitive( 0, nLenMain, pViewport);
//툴팁
#ifndef _KUI_INVALIDATION
_renderToolTip(pViewport, isFront);
#endif
}
void KUIControlGauge::OnChagneBackNotify()
{
_initControl();
#ifdef _KUI_INVALIDATION
//인벨리데이트로 추가된부분 주의요망
KUIControl::OnChagneBackNotify();
#endif
}
void KUIControlGauge::_initControl()
{
if( m_sAniName.empty() )
{
m_rcCaptionArea = m_rcRegion;
return;
}
KResSprite* pFrameLeft = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 0 );
KResSprite* pFrameCenter = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 1 );
KResSprite* pFrameRight = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), 2 );
int nPieceCount = _getSpriteSet()->GetSpriteResAniCount( m_sAniName.c_str());
// 6조각 짜리라면 Ghost를 쓰지 않느 Gauge 이다.
if(nPieceCount == 6)
{
m_bWithoutGhost = true;
}
if( !pFrameRight )
{
assert( false && "Cannot find Sprite Res Frame" );
return;
}
m_rcRegion.bottom = m_rcRegion.top + pFrameRight->GetSizeY();
m_nSize[0] = pFrameLeft->GetSizeX();
m_nSize[2] = pFrameRight->GetSizeX();
m_nSize[1] = m_rcRegion.GetWidth() - (m_nSize[0] + m_nSize[2]);
int nCount = (true == m_bWithoutGhost) ? 2 : 3;
for ( int i = 0 ; i < nCount ; ++i )
{
pFrameLeft = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i * 3 + 0 );
pFrameCenter = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i * 3 + 1 );
pFrameRight = _getSpriteSet()->GetSpriteRes( m_sAniName.c_str(), i * 3 + 2 );
m_prSprite[i][0].SetRes( pFrameLeft );
m_prSprite[i][0].SetPosition( m_rcRegion.left, m_rcRegion.top, m_fZPos );
m_prSprite[i][1].SetRes( pFrameCenter );
m_prSprite[i][1].SetPosition( m_rcRegion.left + pFrameLeft->GetSizeX(), m_rcRegion.top, m_fZPos );
m_prSprite[i][2].SetRes( pFrameRight );
m_prSprite[i][2].SetPosition( m_rcRegion.right - pFrameRight->GetSizeX(), m_rcRegion.top, m_fZPos );
}
}
void KUIControlGauge::_RenderPrimitive(int nCount, int nLenTotal,KViewportObject* pViewport)
{
int nMidSize = m_rcRegion.GetWidth() - m_nSize[0] - m_nSize[2];
if( m_dwStyle & KSTYLE_GAUGE_WITH_GRADUATION)
nMidSize = min( nLenTotal - m_nSize[0], nMidSize);
else
nMidSize = nLenTotal - m_nSize[0] - m_nSize[2];
nMidSize = max( nMidSize, 0 );
int nPos[3] = { m_rcRegion.left, m_rcRegion.left + m_nSize[0],
m_rcRegion.left + m_nSize[0] + nMidSize };
int nRenderTotalSize = 0;
int nRenderSize[3] = { m_nSize[0], nMidSize, nLenTotal - m_nSize[0] - nMidSize };
for ( int i = 0 ; i < 3 ; ++i )
{
m_prSprite[nCount][i].SetPosition( nPos[i], m_rcRegion.top, m_fZPos );
int nSize = min( nRenderSize[i], (nLenTotal - nRenderTotalSize) );
m_rcSpriteClip[nCount][i] = KRect(nPos[i], m_rcRegion.top, nPos[i] + nSize, m_rcRegion.bottom);
m_rcSpriteClip[nCount][i].Intersect( m_rcClipArea );
m_prSprite[nCount][i].SetClipRect( &m_rcSpriteClip[nCount][i] );
if( ! (m_dwStyle & KSTYLE_GAUGE_WITH_GRADUATION) && i == 1)
{
m_prSprite[nCount][i].SetTargetSize( nSize, m_rcRegion.GetHeight() );
}
pViewport->Register( &m_prSprite[nCount][i] );
nRenderTotalSize += nSize;
if( nLenTotal <= nRenderTotalSize )
return;
}
}