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

564 lines
14 KiB
C++

#include "stdafx.h"
#include "KUIMsgControl.h"
#include "KUIFactory.h"
#include "KUIWndManager.h"
#include "KUIControlTitleBar.h"
#include "KUIControlStatusBar.h"
#include "KUIControlButton.h"
#include "KUIControlStatic.h"
#include "KViewport.h"
#include "KResourceManager.h"
#include "KUIDefine.h"
//#include "Util.h"
#ifdef _RAC
#include "SGameInterface.h"
//#include "SGameMessageUI.h"
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// KUIMsgControl Implement
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace
{
KUIWnd* MsgWndCreator()
{
return new KUIMsgControl;
}
bool bMsgWndRegister = KUIFactory::GetInstance()->RegisterCreator( MsgWndCreator, "msgwnd");
const int FRAME_GAP = 8;
const DWORD TITLE_BAR_MARGIN = 30;
const DWORD BUTTON_MARGIN = 40;
const DWORD MSGBOX_HORIZONTAL_MARGIN = 100;
const DWORD MSGBOX_VERTICAL_MARGIN = TITLE_BAR_MARGIN + BUTTON_MARGIN; // Title + Button
const DWORD MSGBOX_MIN_WIDTH = 300 - MSGBOX_HORIZONTAL_MARGIN;
// 2010.08.26 - prodongi
//const DWORD MSGBOX_MAX_WIDTH = 500 - MSGBOX_HORIZONTAL_MARGIN;
const DWORD MSGBOX_MAX_WIDTH = 600 - MSGBOX_HORIZONTAL_MARGIN;
const DWORD MSGBOX_MIN_HEIGHT = 100 - MSGBOX_VERTICAL_MARGIN;
const DWORD MSGBOX_POPUP_TIME = 300;
const DWORD MSGBOX_POPDOWN_TIME = 300;
// 기본 메세지박스.
//const std::string BACKGROUND_NAME = "static_common_outframe01";
//const char * g_strButtonAni = "button_common";
const std::string BACKGROUND_NAME = "common_panel_outframe_gold_sub"; // 변경. bintitle. 2010.06.07. UI팀요청으로 메세지박스 이미지 변경됨.
const char * g_strButtonAni = "common_button_beamblue_stretch"; // 메세지박스 안의 버튼 이미지.
}
KUIMsgControl::KUIMsgControl()
{
m_State = STATE_CREATED;
m_dwTime = 0;
m_dwPopEffectStartTime = 0;
m_dwContinueTime = 0;
m_dwStartTime = 0;
m_dwDefaultEndMsg = KMB_OK_MSG;
m_nDefaultEndIndex = 0;
m_pTitleBar = NULL;
m_pStatusBar = NULL;
m_pBackgroundArea = NULL;
m_nBackgroundCount = 0;
m_pBackgroundList = NULL;
m_customizer = NULL;
}
KUIMsgControl::~KUIMsgControl()
{
SAFE_DELETE_ARRAY( m_pBackgroundList );
SAFE_DELETE_ARRAY( m_pBackgroundArea );
SAFE_DELETE(m_customizer);
}
void KUIMsgControl::Create(KUIWND_CREATE_ARG& arg)
{
m_sTitleText = arg.lpszToolTip;
arg.lpszToolTip = "";
arg.lpszAniName = BACKGROUND_NAME; //"common_panel_outframe_gold_sub";
KUIControl::Create( arg );
this->SetEnableColor( "<#ffffff>" ); // bintitle. 2010.06.15.
}
void KUIMsgControl::Render(KViewportObject* pViewport, bool isFront )
{
if ( m_bShowFlag )
{
// Back
for(int i = 0; i < m_nPieceCount; ++i)
{
pViewport->Register(&m_pSpriteList[i]);
}
// Top Frame
pViewport->Register( &m_prTopFrame);
// Child (Title, Status, Button)
_renderChild( pViewport);
// 메시지
_renderCaption(pViewport);
}
}
void KUIMsgControl::Process(DWORD dwTime)
{
KUIControl::Process( dwTime );
m_dwTime = dwTime;
DWORD dwTimeDiff = m_dwTime - m_dwPopEffectStartTime;
switch( m_State)
{
case STATE_CREATED:
_statePopUp();
break;
case STATE_POPUP:
{
float fAlphaValue = (float)dwTimeDiff / (float)MSGBOX_POPUP_TIME;
ChangeAlpha( fAlphaValue);
if(dwTimeDiff >= MSGBOX_POPUP_TIME )
m_State = STATE_NORMAL;
}
break;
case STATE_NORMAL:
break;
case STATE_POPDOWN:
{
float fAlphaValue = 1.0f - ( (float)dwTimeDiff / (float)MSGBOX_POPDOWN_TIME );
ChangeAlpha( fAlphaValue);
if(dwTimeDiff >= MSGBOX_POPDOWN_TIME )
m_State = STATE_END;
}
break;
case STATE_END:
{
SetDestroy( true );
}
break;
}
if( m_dwStartTime == 0 )
{
m_dwStartTime = m_dwTime;
}
else
{
if( m_dwContinueTime )
{
//지속 시간이 끝났다.
if( m_dwTime - m_dwStartTime > m_dwContinueTime )
{
SetDestroy( true );
}
}
}
if (m_customizer)
m_customizer->process(dwTime);
}
void KUIMsgControl::PumpUpMessage( LPCSTR lpszControlID, DWORD dwMessage, DWORD lparam, DWORD wparam )
{
if( m_State != STATE_NORMAL)
return;
if( dwMessage == KUI_MESSAGE::KBUTTON_CLICK)
{
for(int i = 0; i < m_vtButtons.size(); ++i)
{
if( strcmp( lpszControlID, m_vtButtons.at(i)->GetID() ) == 0)
{
_invokeFunc( i);
_statePopDown();
return;
}
}
}
}
DWORD KUIMsgControl::OnMouseMessage(DWORD dwMessage, int x, int y)
{
if( m_State != STATE_NORMAL)
return KMR_NORMAL;
return KUIControl::OnMouseMessage( dwMessage ,x , y);
}
DWORD KUIMsgControl::OnKeyMessage( DWORD dwMessage, DWORD dwKeyCode)
{
if( m_State != STATE_NORMAL)
return KMR_NORMAL;
if ( dwMessage == KKEY_DOWN && dwKeyCode == VK_RETURN )
{
// _oprint( "KUIMsgControl::OnKeyMessage\n" );
//PumpUpMessage( "IDOK", KUI_MESSAGE::KBUTTON_CLICK, 0, 0 );
}
return KUIControl::OnKeyMessage( dwMessage, dwKeyCode);
}
void KUIMsgControl::SetContinueTime(DWORD dwContinueTime)
{
if( m_dwContinueTime != dwContinueTime )
{
m_dwContinueTime = dwContinueTime;
InvalidateWnd();
}
}
void KUIMsgControl::SetEndBtnIndex(int nIndex)
{
if( m_nDefaultEndIndex != nIndex )
{
m_nDefaultEndIndex = nIndex;
InvalidateWnd();
}
}
void KUIMsgControl::MakeUpButton()
{
}
void KUIMsgControl::RegisterCallback(KObject* pObj)
{
m_pCallbackObj = pObj;
}
void KUIMsgControl::SetMsg( LPCSTR lpszID, LPCSTR lpszCaption )
{
KUIWnd * pMsg = GetChild(lpszID);
//if( pMsg ) pMsg->SetCaption( CStringUtil::StringFormat( "<size:10><#fbe7b4><hcenter><vcenter>%s", lpszCaption ).c_str() );
if( pMsg ) pMsg->SetCaption( CStringUtil::StringFormat( "<size:10><#ffffff><hcenter><vcenter>%s", lpszCaption ).c_str() );
InvalidateWnd();
}
void KUIMsgControl::AddMsg( LPCSTR lpszID, LPCSTR lpszCaption )
{
KUIWND_CREATE_ARG arg;
arg.lpszClassName = "static";
arg.lpszID = lpszID;
arg.lpszCaption = lpszCaption;
arg.lpszAniName = "";
arg.lpszSprName = m_sSprName.c_str();
arg.rcRect = m_rcRegion;
arg.pParent = this;
arg.dwStyle = 0;
// arg.dwAnchor = KANCHOR_BOTTOM | KANCHOR_LEFT;
KSize size = KTextPhrase::GetStringSize( lpszCaption, m_rcRegion.GetWidth() );
//가로 크기 늘리기
if( (m_rcRegion.GetWidth() - size.width) <= 10 )
{
arg.rcRect.left -= 20;
arg.rcRect.right += 20;
}
//ControlStatic의 Msg정렬 기준이 MessageBox전체 크기에서 버튼의 top을 뺀 수치로 재 설정
if( m_vtButtons.empty() == false )
{
int button_height = arg.rcRect.bottom ;
std::vector<KUIControlButton*>::iterator itButton = m_vtButtons.begin();
for( ; itButton != m_vtButtons.end(); ++itButton )
{
if( button_height > (*itButton)->GetRect().top )
button_height = (*itButton)->GetRect().top;
}
arg.rcRect.bottom = button_height;
}
KUIControlStatic * pMsgStatic = reinterpret_cast<KUIControlStatic*>(m_pManager->CreateControl(arg));
InvalidateWnd();
m_msgControlId = lpszID;
}
void KUIMsgControl::AddButton( LPCSTR lpszID, LPCSTR lpszCaption, bool bUseSprCaption, int nButtonCount )
{
// if ( m_pStatusBar == NULL ) return;
// 버튼의 갯수에 따라 한버튼의 크기 달라진다
int nWidth = m_rcRegion.GetWidth()/nButtonCount;
int nRealWidth = nWidth - FRAME_GAP;
KRect rc;
std::string strButtonAniName = g_strButtonAni;
KResSprite* pFrame = NULL;
// 첫번째 버튼
if( m_vtButtons.empty() )
{
pFrame = _getSpriteSet()->GetSpriteRes( strButtonAniName.c_str(), 0 );
if( nButtonCount == 1 ) rc.left = m_rcRegion.left + m_rcRegion.GetWidth()/2 - 70/2;
else if( nButtonCount == 2 ) rc.left = m_rcRegion.left + m_rcRegion.GetWidth()/2 - 70 - 10;
else if( nButtonCount == 3 ) rc.left = m_rcRegion.left + m_rcRegion.GetWidth()/2 - 70/2 - 80;
}
// 두번째 버튼
else if( m_vtButtons.size() == 1 )
{
pFrame = _getSpriteSet()->GetSpriteRes( strButtonAniName.c_str(), 0 );
if( nButtonCount == 2 ) rc.left = m_rcRegion.left + m_rcRegion.GetWidth()/2 + 10;
else if( nButtonCount == 3 ) rc.left = m_rcRegion.left + m_rcRegion.GetWidth()/2 - 70/2;
}
// 마지막 세번째 버튼
else if( m_vtButtons.size() == 2 )
{
pFrame = _getSpriteSet()->GetSpriteRes( strButtonAniName.c_str(), 0 );
rc.left = m_rcRegion.left + m_rcRegion.GetWidth()/2 + 70/2 + 10;
}
rc.right = rc.left + 70;
rc.top = m_rcRegion.bottom - pFrame->GetSizeY() - FRAME_GAP;
rc.bottom = rc.bottom = m_rcRegion.bottom - FRAME_GAP;
// if( rc.right >= m_rcRegion.right ) rc.right = m_rcRegion.right - 2;
// rc.top -= FRAME_GAP; rc.bottom -= FRAME_GAP;
KUIWND_CREATE_ARG arg;
arg.lpszClassName = "button";
arg.lpszID = lpszID;
arg.lpszCaption = lpszCaption;
arg.lpszAniName = strButtonAniName.c_str();
arg.lpszSprName = m_sSprName.c_str();
arg.rcRect = rc;
arg.pParent = this;
arg.dwStyle = 0;
arg.dwAnchor = KANCHOR_BOTTOM | KANCHOR_LEFT;
if( bUseSprCaption )
{
KUIControlCaptionButton* pButton = reinterpret_cast<KUIControlCaptionButton*>(m_pManager->CreateControl(arg));
pButton->SetEnableColor( m_strEnableColor.c_str() ); // bintitle.
pButton->Enable(); //
m_vtButtons.push_back( pButton );
}
else
{
KUIControlButton* pButton = reinterpret_cast<KUIControlButton*>(m_pManager->CreateControl(arg));
pButton->SetEnableColor( m_strEnableColor.c_str() ); // bintitle.
pButton->Enable(); //
m_vtButtons.push_back( pButton );
}
// _refreshStatusBar();
InvalidateWnd();
}
void KUIMsgControl::_initControl()
{
_clearRegisteredSprite();
// String의 Size 측정
// 2010.08.26 - prodongi
//KSize msgSize = KTextPhrase::GetStringSize( m_sCaption.c_str(), MSGBOX_MAX_WIDTH);
KSize msgSize = KTextPhrase::GetLongestStringSize( m_sCaption.c_str(), MSGBOX_MAX_WIDTH);
msgSize.width = max( (int)msgSize.width, (int)MSGBOX_MIN_WIDTH);
msgSize.height = max( (int)msgSize.height, (int)MSGBOX_MIN_HEIGHT);
DWORD dwBoxWidth = msgSize.width + MSGBOX_HORIZONTAL_MARGIN;
DWORD dwBoxHeight = msgSize.height + MSGBOX_VERTICAL_MARGIN;
const KSize& size = KUIWndManager::GetResolution();
// box의 크기 설정
m_rcRegion.left = size.width / 2 - dwBoxWidth / 2;
m_rcRegion.right = m_rcRegion.left + dwBoxWidth;
m_rcRegion.top = size.height / 2 - dwBoxHeight / 2;
m_rcRegion.bottom = m_rcRegion.top + dwBoxHeight;
UpdateBack();
//KUIWND_CREATE_ARG CHILD_ARG;
//// TitleBar 생성
//if(m_dwStyle & KSTYLE_NOTITLE)
//{
// m_pTitleBar = NULL;
//}
//else
//{
// CHILD_ARG.lpszSprName = m_sSprName;
// CHILD_ARG.lpszClassName = "titlebar";
// CHILD_ARG.lpszID = "_title";
// CHILD_ARG.lpszAniName = "window_titlebar01";
// CHILD_ARG.lpszCaption = m_sTitleText;
// CHILD_ARG.rcRect = m_rcRegion;
// CHILD_ARG.rcRect.top += FRAME_GAP;
// CHILD_ARG.rcRect.left += FRAME_GAP;
// CHILD_ARG.dwStyle = 0;
// CHILD_ARG.dwAnchor = KANCHOR_TOP | KANCHOR_LEFT;
// CHILD_ARG.pParent = this;
// m_pTitleBar = reinterpret_cast<KUIControlTitleBar*>(m_pManager->CreateControl(CHILD_ARG) );
//}
// Msg 의 크기 설정
//m_rcCaptionArea.left = size.width / 2 - msgSize.width / 2;
//m_rcCaptionArea.right = m_rcCaptionArea.left + msgSize.width;
//m_rcCaptionArea.top = m_rcRegion.top + TITLE_BAR_MARGIN;
//m_rcCaptionArea.bottom = m_rcCaptionArea.top + msgSize.height;
//SetCaptionAlign( KTextRender::KTALIGN_HCENTER | KTextRender::KTALIGN_VCENTER);
//UpdateCaption();
// Back Ground Setting
// _reArrangeBackground();
_makeBackground();
// _makeTopFrame();
// _registerSprite( &m_prTopFrame);
//// status bar
//CHILD_ARG.lpszSprName = m_sSprName;
//CHILD_ARG.lpszClassName = "statusbar";
//CHILD_ARG.lpszID = "_Status";
//CHILD_ARG.lpszAniName = "window_statusbar";
//CHILD_ARG.lpszCaption = "";
//CHILD_ARG.rcRect = m_rcRegion;
//CHILD_ARG.dwStyle = 0;
//CHILD_ARG.dwAnchor = 0;
//CHILD_ARG.pParent = this;
//m_pStatusBar = reinterpret_cast<KUIControlStatusBar*>(m_pManager->CreateControl(CHILD_ARG) );
//_refreshStatusBar();
}
void KUIMsgControl::_invokeFunc(DWORD dwEndMsg)
{
if(m_pCallbackObj)
{
_CID( UI_CALLBACK );
KCallbackMessage msg;
msg.sMsgID = GetID();
// MessageBox 의 [확인] [취소] 가 => [취소] [확인] 으로 변경되어 수정. bintitle. 2010.06.17
//msg.dwResult = dwEndMsg;
msg.dwResult = dwEndMsg;
msg.dwResult ^= 1;
msg.strReqValue = m_strReqValue;
m_pCallbackObj->Perform( id_UI_CALLBACK, msg);
}
}
void KUIMsgControl::_statePopUp()
{
m_State = STATE_POPUP;
m_dwPopEffectStartTime = m_dwTime;
InvalidateWnd();
}
void KUIMsgControl::_statePopDown()
{
m_State = STATE_POPDOWN;
m_dwPopEffectStartTime = m_dwTime;
InvalidateWnd();
}
void KUIMsgControl::_reArrangeBackground()
{
}
void KUIMsgControl::_makeBackground()
{
}
void KUIMsgControl::_makeTopFrame()
{
//BuildPrimitive( &m_prTopFrame, "window_topframe", 1,
// K3DVertex(m_rcRegion.left, m_rcRegion.top + FRAME_GAP, m_fZPos),
// 1.0f, KSize(m_rcRegion.GetWidth(), -1), false );
}
void KUIMsgControl::_refreshStatusBar()
{
}
void KUIMsgControl::setCustomizing(cMsgControlCustomizer* customizer)
{
SAFE_DELETE(m_customizer);
m_customizer = customizer;
if (!m_customizer)
return ;
m_customizer->setMsgControl(this);
m_customizer->customizing();
ChangeAlpha(0.0f);
}
KUIWnd* KUIMsgControl::addStatic(const char *id, const char *caption)
{
KUIWND_CREATE_ARG arg;
arg.lpszClassName = "static";
arg.lpszID = id;
arg.lpszCaption = caption;
arg.lpszAniName = "";
arg.lpszSprName = m_sSprName.c_str();
arg.pParent = this;
arg.dwStyle = 0;
// x는 메세지 박스의 중앙 위치
int x = GetRect().left + (GetRect().GetWidth() >> 1);
int y = GetRect().top;
KSize size = KTextPhrase::GetStringSize( caption, m_rcRegion.GetWidth() );
/// 텍스트 사이즈가 중간에 변할 수 있기 때문에, 윈도우 사이즈만큼 넓이를 잡아 준다
size.width = m_rcRegion.GetWidth();
/// 5는 여백
size.width -= 5;
/// 중앙을 기준으로 정렬
x -= (size.width >> 1);
arg.rcRect = KRect(x, y, x + size.width, y + size.height);
KUIWnd* wnd = m_pManager->CreateControl(arg);
assert(!wnd && "faild addStatic create control");
InvalidateWnd();
return wnd;
}
void KUIMsgControl::moveButtons(int offsetX, int offsetY)
{
if (m_vtButtons.empty())
return ;
std::vector<KUIControlButton*>::iterator it = m_vtButtons.begin();
for( ; it != m_vtButtons.end(); ++it)
{
KRect const& r = (*it)->GetRect();
(*it)->MovePos(r.left + offsetX, r.top + offsetY);
}
}
bool KUIMsgControl::getButtonTopPos(int& top) const
{
if (m_vtButtons.empty())
return false;
top = m_vtButtons[0]->GetRect().top;
return true;
}