#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( "<#fbe7b4>%s", lpszCaption ).c_str() ); if( pMsg ) pMsg->SetCaption( CStringUtil::StringFormat( "<#ffffff>%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::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(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(m_pManager->CreateControl(arg)); pButton->SetEnableColor( m_strEnableColor.c_str() ); // bintitle. pButton->Enable(); // m_vtButtons.push_back( pButton ); } else { KUIControlButton* pButton = reinterpret_cast(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(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(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::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; }