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

670 lines
18 KiB
C++

#include "stdafx.h"
#include <toolkit/XStringUtil.h>
#include "SStringDB.h"
#include "SItemDB.h"
#include "SMixCategoryDB.h"
#include "SGameMessage.h"
#include "SGameManager.h"
//#include "SGameMessageUI.h"
//#include "KUIControl.h"
#include "KUIControlStatic.h"
#include "KUIControlButton.h"
#include "KUIControlScroll.h"
#include "KUIListControl.h"
#include "SUIFormulaListWnd.h"
namespace
{
const int g_nListSize = 6; // 리스트 행 개수.
const char * g_pStrDefault = "common_panel_inframe_titanium_blue";
const char * g_pStrSelected = "common_select_titanium_bg_orange";
// 0 강화, 1 조합.
const int g_arrWndType[] = { 9709, 9718 };
// 공식을 전달할 윈도우 ID.
SIMSG_TOGGLE_UIWINDOW::_UIWINDOW_TYPE synthetic_wnd[] = { SIMSG_TOGGLE_UIWINDOW::UIWINDOW_UPGRADE, SIMSG_TOGGLE_UIWINDOW::UIWINDOW_ITEMCOMBINE };
};
// 2010.09.03 - prodongi
SUIFormulaListWnd::SList::~SList()
{
SAFE_DELETE( m_pList );
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// struct SList
//
void SUIFormulaListWnd::SList::RefreshScrollBar()
{
if( m_pScrollBar )
m_pScrollBar->SetScrollRange( g_nListSize, m_nMaxSize );
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
SUIFormulaListWnd::SUIFormulaListWnd( SGameManager * pGameManager ) :
SUIWnd( pGameManager )
{
}
SUIFormulaListWnd::~SUIFormulaListWnd()
{
Release();
}
void SUIFormulaListWnd::Release()
{
}
//
// CreateWnd
//
SUIWnd* SUIFormulaListWnd::CreateWnd( const char* szFile, KUIWndManager* pWndManager, KPoint kPos, int nWindowID )
{
SUIWnd::CreateWnd( szFile, pWndManager, kPos, nWindowID );
// 커스텀 윈도우 move 영역 설정
SetCustomMovingRect( GetChild( "titlebar" )->GetRect() );
m_nSystheticID = 0; // 합성분류 - 강화/조합/수리/복원....
// 공식리스트 구조체 배열.
for( int i=0; i<LIST_GROUP::LIST_MAX; ++i )
{
//------------------------------------
// ListControl 생성.
KUIListControl * pList = new KUIListControl(
this,
const_cast< char * >( CStringUtil::StringFormat( "listcontrol%02d", i+1 ).c_str() ), "",
const_cast< char * >( CStringUtil::StringFormat( "list_%02d_item", i+1 ).c_str() ),
g_nListSize );
pList->SetListControlIndex( i ); // List Index 설정.
// Item column
pList->AddStringItemColumn( const_cast< char * >( CStringUtil::StringFormat( "list_%02d_column_01", i+1 ).c_str() ) );
// Create
pList->Create();
//-------------------------------------
m_List[ i ].m_pList = pList;
m_List[ i ].m_pScrollBar = dynamicCast< KUIControlVScrollSmallEx * >( GetChild( CStringUtil::StringFormat( "scrollbar_list_%02d", i+1 ).c_str() ) ); // 스크롤.
m_List[ i ].m_pScrollBar->SetParent( ( KUIWnd * )( pList->GetListControl() ) ); // 스크롤의 부모를 리스트컨트롤의 영역 컨트롤로 지정.
//m_List[ i ].m_pScrollBar->SetWheelUse( false ); // 휠기능 끔.
m_List[ i ].m_pSelectedControl = GetChild( CStringUtil::StringFormat( "back_line_select_%02d", i+1 ).c_str() ); // 선택아이템에 출력될 컨트롤.
m_List[ i ].m_pSelectedControl->SetShow( false );
// 선택된 아이템 인덱스. ( 스크롤값을 제외한 보이는 아이템에서의 인덱스 )
m_nSelectIndex[ i ] = -1;
// 선택한 아이템의 텍스트를 출력할 컨트롤.
m_arrSelectedText[ i ] = GetChild( CStringUtil::StringFormat( "text_%02d", i + 1 ).c_str() );
}
CStringUtil::GetTextDecoration( GetChild("list_01_column_01")->GetCaption(), m_strDecoListItem ); // 리스트 아이템 꾸미기텍스트.
CStringUtil::GetTextDecoration( GetChild("text_01")->GetCaption(), m_strDecoSelected ); // 선택된 아이템 꾸미기텍스트.
return this;
}
//
// InitControls
//
bool SUIFormulaListWnd::InitControls( KPoint kPos )
{
return SUIWnd::InitControls( kPos );
}
//
// OnNotifyUIWindowOpen
//
void SUIFormulaListWnd::OnNotifyUIWindowOpen( bool bOpen, bool bLimitWnd)
{
if( bOpen )
{
// 합성분류당 대,중,소 분류 각각의 개수.
m_CategoryCount = GetMixCategoryDB().GetCategorySize( m_nSystheticID );
// 리스트 채움.
RefreshListAll();
}
else
{
// 초기화.
for( int i=0; i<LIST_GROUP::LIST_MAX; ++i )
{
if( m_arrSelectedText[ i ] )
m_arrSelectedText[ i ]->SetCaption( " " ); // 선택한 아이템의 텍스트를 출력할 컨트롤.
m_nSelectIndex[ i ] = -1; // 선택된 아이템 인덱스.
m_List[ i ].clear();
}
}
}
//
// ProcMsgAtStatic
//
void SUIFormulaListWnd::ProcMsgAtStatic( SGameMessage* pMsg )
{
switch( pMsg->nType )
{
// 합성분류( 0강화, 1조합 ) 를 저장.
case IMSG_SYNTHETIC_ID :
{
pMsg->bUse = true;
SIMSG_SYNTHETIC_ID * pData = dynamicCast< SIMSG_SYNTHETIC_ID * >( pMsg );
m_nSystheticID = pData->synthetic_id;
// Title 설정.
KUIWnd * pWnd = GetChild( "text_mix_alllist" );
if( pWnd )
{
if( m_strDecoTitle.empty() )
CStringUtil::GetTextDecoration( pWnd->GetCaption(), m_strDecoTitle );
std::string strDeco( m_strDecoTitle );
strDeco.append( S( g_arrWndType[ m_nSystheticID ] ) );
pWnd->SetCaption( strDeco.c_str() );
}
}
break;
}
}
//
// PumpUpMessage
//
void SUIFormulaListWnd::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lparam, DWORD wparam )
{
switch( nMessage )
{
// Scroll
case KUI_MESSAGE::KSCROLL_SELECT :
{
int nScrollIndex = 0;
std::string str( lpszControlID );
std::string::size_type fpos = str.find_last_of( "scrollbar_list_" );
if( fpos != std::string::npos )
nScrollIndex = ::atoi( str.substr( fpos + 1, str.size() ).c_str() ) - 1;
m_List[ nScrollIndex ].m_nScrollPos = max( (int)lparam, 0 );
// 리스트 채움.
RefreshListControl( nScrollIndex );
// 스크롤바 조절.
m_List[ nScrollIndex ].RefreshScrollBar( );
// 셀렉트컨트롤 조정.
RefreshSelectedContol( nScrollIndex );
}
break;
// List.
case KUI_MESSAGE::KLIST_ITEM_LBUTTON_DOWN :
// ** MSG_LISTCONTROL msg = *( (MSG_LISTCONTROL *)( &pumpMsg ) );
{
MSG_LISTCONTROL msg = *( (MSG_LISTCONTROL *)( &lparam ) );
// 리스트의 아이템 선택.
ListItemClick( msg );
}
break;
case KUI_MESSAGE::KBUTTON_CLICK :
{
if( !::_stricmp( lpszControlID, "button_close" ) || !::_stricmp( lpszControlID, "button_close_01" )) // 닫기.
{
m_nSystheticID ^= 1;
m_pGameManager->PostMsgAtDynamic( new SIMSG_SHOW_UIWINDOW( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_FORMULA, false ) );
break;
}
if( !::_stricmp( lpszControlID, "button_apply" ) ) // 적용.
{
Apply(); // 공식적용.
break;
}
}
break;
// 윈도우 이동
case KUI_MESSAGE::KGENWND_MOVE:
LimitMoveWnd(); // 게임 외부로 나가지 못하게 제한
break;
}
SUIWnd::PumpUpMessage( lpszControlID, nMessage, lparam, wparam );
}
//
// OnMouseMessage
//
DWORD SUIFormulaListWnd::OnMouseMessage(DWORD dwMessage, int x, int y)
{
if( dwMessage == KLBUTTON_DOWN )
{
// 리스트 컨트롤에 마우스 이벤트 전달.
for( int i=0; i<LIST_GROUP::LIST_MAX; ++i )
m_List[ i ].m_pList->OnMouseMessage( dwMessage, x, y );
}
return SUIWnd::OnMouseMessage( dwMessage, x, y );
}
//
// RefreshList : 아이템합성 공식 리스트 채움.
//
void SUIFormulaListWnd::RefreshList( int listIndex )
{
if( listIndex >= LIST_GROUP::LIST_MAX )
return;
// 공식리스트 구조체 배열.
int maxSize = 0;
switch( listIndex )
{
case LIST_GROUP::LIST_HIGH :
//maxSize = m_CategoryCount.highSize;
maxSize = m_CategoryCount.GetHighSize();
break;
case LIST_GROUP::LIST_MIDDLE :
if( m_nSelectIndex[ LIST_GROUP::LIST_HIGH ] > -1 )
maxSize = m_CategoryCount.GetMiddleSize( m_nSelectIndex[ LIST_GROUP::LIST_HIGH ] );
break;
case LIST_GROUP::LIST_LOW :
if( m_nSelectIndex[ LIST_GROUP::LIST_MIDDLE ] > -1 )
maxSize = m_CategoryCount.GetLowSize( m_nSelectIndex[ LIST_GROUP::LIST_HIGH ], m_nSelectIndex[ LIST_GROUP::LIST_MIDDLE ] );
break;
}
m_List[ listIndex ].m_nMaxSize = maxSize;
m_List[ listIndex ].m_pList->RefreshItemState( maxSize );
m_List[ listIndex ].RefreshScrollBar();
// 리스트 채움.
RefreshListControl( listIndex );
}
//
// RefreshList : 아이템합성 공식 리스트 채움.
//
void SUIFormulaListWnd::RefreshListAll()
{
// 공식리스트 구조체 배열.
for( int i=0; i<LIST_GROUP::LIST_MAX; ++i )
{
RefreshList( i );
}
}
//
// RefreshList : 아이템합성 공식 리스트 채움.
//
void SUIFormulaListWnd::RefreshListControl( int nScrollIndex )
{
KUIListControl * pListControl = m_List[ nScrollIndex ].m_pList;
if( pListControl == NULL )
return;
int nScroll = m_List[ nScrollIndex ].m_nScrollPos;
int nMaxSize = m_List[ nScrollIndex ].m_nMaxSize;
KUIControl * pControl = NULL;
int maxSize = pListControl->GetListConutMAX(); // 리스트 최대개수.
int dataIndex = 0;
for( int i=0; i<maxSize; i++ )
{
// ListControl 의 Item.
KUIListItem * pItem = pListControl->GetItem( i );
if( pItem )
{
// Data Index;
dataIndex = i + nScroll;
// index가 권한목록 최대개수 이하인동안 Refresh.
if( dataIndex < nMaxSize )
{
// Category.
MixCategoryBase * pCategory = GetCategory( nScrollIndex, dataIndex );
if( pCategory )
{
// 컨트롤에 텍스트 맵핑.
if( pItem->GetControl( pControl, CStringUtil::StringFormat( "list_%02d_column_01", nScrollIndex + 1 ).c_str() ) )
{
pControl->SetCaption( CStringUtil::StringFormat( "%s%s",
m_strDecoListItem.c_str(),
S( pCategory->category_text_id ) ).c_str() );
}
}
////-------------------------------
//// ** 해당 아이템을 확장 or 축소(원본크기) 한다.
pListControl->SetResize( i, dataIndex, 1 );
}
else
break;
}
}// for
////-------------------------------
//// ** 리스트정보 최종 업데이트.
pListControl->RefreshList( nScroll );
}
//
// ClearListControl : 리스트 의 아이템 초기화.
//
void SUIFormulaListWnd::ClearListControl( int nScrollIndex )
{
KUIListControl * pListControl = m_List[ nScrollIndex ].m_pList;
if( pListControl == NULL )
return;
KUIControl * pControl = NULL;
int maxSize = pListControl->GetListConutMAX(); // 리스트 최대개수.
for( int i=0; i<maxSize; i++ )
{
// ListControl 의 Item.
KUIListItem * pItem = pListControl->GetItem( i );
if( pItem )
{
// 컨트롤에 텍스트 맵핑.
if( pItem->GetControl( pControl, CStringUtil::StringFormat( "list_%02d_column_01", nScrollIndex + 1 ).c_str() ) )
pControl->SetCaption( " " );
////-------------------------------
//// ** 해당 아이템을 확장 or 축소(원본크기) 한다.
pListControl->SetResize( i, i, 1 );
}
}
////-------------------------------
//// ** 리스트정보 최종 업데이트.
pListControl->RefreshList( 0 );
}
// 리스트의 아이템 선택시 처리.
void SUIFormulaListWnd::ListItemClick( MSG_LISTCONTROL & msg )
{
//
// ListControl 을 선택.
SList & sList = m_List[ msg.listControlIndex ];
KUIControl * pControl;
if( sList.m_pList->GetControl( pControl, ( ITEMTYPE )msg.type, msg.itemIndex, msg.columnIndex ) )
{
//
// 아이템 선택.
if( ITEMTYPE::TYPE_ITEM_Base == msg.type || ITEMTYPE::TYPE_ITEM_Column == msg.type )
{
sList.m_pList->SetSelectItem( sList.m_nScrollPos, msg.itemIndex );
// 컨트롤명.
if( !::_stricmp( pControl->GetID(), CStringUtil::StringFormat( "list_%02d_column_01", msg.listControlIndex + 1 ).c_str() ) )
{
// 셀렉트 컨트롤 가시성 결정.
VisibilitySelectedControl( true, msg.listControlIndex, msg.itemIndex );
// 선택된 아이템 인덱스.
m_nSelectIndex[ msg.listControlIndex ] = msg.itemIndex + sList.m_nScrollPos;
// 선택한 아이템 텍스트 출력.
MixCategoryBase * pCategory = GetCategory( msg.listControlIndex, m_nSelectIndex[ msg.listControlIndex ] );
if( pCategory )
{
if( m_arrSelectedText[ msg.listControlIndex ] )
m_arrSelectedText[ msg.listControlIndex ]->SetCaption( CStringUtil::StringFormat( "%s%s",
m_strDecoSelected.c_str(),
S( pCategory->category_text_id ) ).c_str() );
}
switch( msg.listControlIndex )
{
// 대.
case LIST_GROUP::LIST_HIGH :
// 하위분류의 스크롤값 초기화.
m_List[ LIST_GROUP::LIST_MIDDLE ].m_nScrollPos = 0;
m_List[ LIST_GROUP::LIST_LOW ].m_nScrollPos = 0;
m_List[ LIST_GROUP::LIST_MIDDLE ].m_pScrollBar->SetPosition( 0 );
m_List[ LIST_GROUP::LIST_LOW ].m_pScrollBar->SetPosition( 0 );
// 하위분류의 선택 인덱스 초기화.
m_nSelectIndex[ LIST_GROUP::LIST_MIDDLE ] = -1;
m_nSelectIndex[ LIST_GROUP::LIST_LOW ] = -1;
// 하위분류의 선택 텍스트 초기화.
if( m_arrSelectedText[ LIST_GROUP::LIST_MIDDLE ] && m_arrSelectedText[ LIST_GROUP::LIST_LOW ] )
{
m_arrSelectedText[ LIST_GROUP::LIST_MIDDLE ]->SetCaption( " " );
m_arrSelectedText[ LIST_GROUP::LIST_LOW ]->SetCaption( " " );
}
// 대분류를 선택한 경우 소분류 리스트 초기화.
ClearListControl( LIST_GROUP::LIST_LOW );
// 셀렉트 컨트롤 가시성 결정.
VisibilitySelectedControl( false, LIST_GROUP::LIST_MIDDLE );
VisibilitySelectedControl( false, LIST_GROUP::LIST_LOW );
break;
// 중.
case LIST_GROUP::LIST_MIDDLE :
// 하위분류의 스크롤값 초기화.
m_List[ LIST_GROUP::LIST_LOW ].m_nScrollPos = 0;
m_List[ LIST_GROUP::LIST_LOW ].m_pScrollBar->SetPosition( 0 );
// 하위분류의 선택 인덱스 초기화.
m_nSelectIndex[ LIST_GROUP::LIST_LOW ] = -1;
// 하위분류의 선택 텍스트 초기화.
if( m_arrSelectedText[ LIST_GROUP::LIST_LOW ] )
m_arrSelectedText[ LIST_GROUP::LIST_LOW ]->SetCaption( " " );
// 중분류를 선택한 경우 소분류 리스트 초기화.
ClearListControl( LIST_GROUP::LIST_LOW );
// 셀렉트 컨트롤 가시성 결정.
VisibilitySelectedControl( false, LIST_GROUP::LIST_LOW );
break;
// 소.
case LIST_GROUP::LIST_LOW :
return; // 소분류를 선택한 경우에는 하위리스트가 없으므로 제외.
}
//
// 리스트 채움. 선택한 리스트의 하위리스트를 채우기 위해 + 1 한다.
RefreshList( msg.listControlIndex + 1 );
}
}
}
}
//
// GetCategory : 인자에 해당하는 카테고리 정보를 반환.
//
MixCategoryBase * SUIFormulaListWnd::GetCategory( int nListIndex, int nDataIndex )
{
// 대/중/소.
switch( nListIndex )
{
case LIST_GROUP::LIST_HIGH :
return GetMixCategoryDB().GetCategory( m_nSystheticID, GameRule::GetCurrentLocalBitSet(), nDataIndex );
case LIST_GROUP::LIST_MIDDLE :
if( m_nSelectIndex[ LIST_GROUP::LIST_HIGH ] > -1 )
return GetMixCategoryDB().GetCategory( m_nSystheticID, GameRule::GetCurrentLocalBitSet(),
m_nSelectIndex[ LIST_GROUP::LIST_HIGH ], nDataIndex );
case LIST_GROUP::LIST_LOW :
if( m_nSelectIndex[ LIST_GROUP::LIST_MIDDLE ] > -1 )
return GetMixCategoryDB().GetCategory( m_nSystheticID, GameRule::GetCurrentLocalBitSet(),
m_nSelectIndex[ LIST_GROUP::LIST_HIGH ],
m_nSelectIndex[ LIST_GROUP::LIST_MIDDLE ],
nDataIndex );
}
return NULL;
}
//
// Apply : 공식 적용.
//
void SUIFormulaListWnd::Apply()
{
MixCategoryBase * pCategory = GetMixCategoryDB().GetCategory( m_nSystheticID, GameRule::GetCurrentLocalBitSet(),
m_nSelectIndex[ LIST_GROUP::LIST_HIGH ],
m_nSelectIndex[ LIST_GROUP::LIST_MIDDLE ],
m_nSelectIndex[ LIST_GROUP::LIST_LOW ] );
if( pCategory )
{
m_pGameManager->PostMsgAtDynamic( new SIMSG_FORMAL_ID( synthetic_wnd[ m_nSystheticID ], pCategory->formal_id, pCategory->result_id ) );
// 메세지박스.
//m_pGameManager->ProcMsgAtStatic( new SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::_MSGBOXID::MSGBOX_GENERAL, S( pCategory->formal_id ) ) );
}
}
//
// VisibilitySelectedControl : 셀렉트 컨트롤 가시성 결정.
//
void SUIFormulaListWnd::VisibilitySelectedControl( bool flag, int listIndex, int itemIndex )
{
SList & sList = m_List[ listIndex ];
// 셀렉트컨트롤 설정.
if( flag )
SetSelectedControl( listIndex, itemIndex );
sList.m_pSelectedControl->SetShow( flag );
}
//
// RefreshSelectedContol : 셀렉트컨트롤 조정.
//
void SUIFormulaListWnd::RefreshSelectedContol( int nScrollIndex )
{
SList & sList = m_List[ nScrollIndex ];
// 선택된 아이템이 없으면 숨김처리 후 종료.
if( m_nSelectIndex[ nScrollIndex ] == -1 )
{
sList.m_pSelectedControl->SetShow( false );
return;
}
int selectedIndex = sList.m_pList->GetSelectedIndex();
int endIndex = sList.m_pList->GetIndexOfVisibleEndItem() + sList.m_nScrollPos;
bool bShow = false;
if( selectedIndex > -1 && endIndex >= selectedIndex )
{
selectedIndex -= sList.m_nScrollPos;
if( selectedIndex > -1 )
{
SetSelectedControl( nScrollIndex, selectedIndex );
bShow = true;
}
}
sList.m_pSelectedControl->SetShow( bShow );
}
//
// SetSelectedControl : 셀렉트컨트롤 설정.
//
void SUIFormulaListWnd::SetSelectedControl( int listIndex, int itemIndex )
{
SList & sList = m_List[ listIndex ];
// 셀렉트컨트롤 출력.
KUIListItem * pItem = sList.m_pList->GetItem( itemIndex );
if( pItem )
{
KUIControl * pBaseControl = pItem->GetBaseControl();
if( pBaseControl )
{
sList.m_pSelectedControl->MovePos( pBaseControl->GetRect().left, pBaseControl->GetRect().top );
// Item_Base 보다 위에 뜨게 해야한다. 툴상의 LayOut 이 제대로 적용되지 않는 문제때문...
std::list<KUIWnd*>::iterator it_itembase = std::find( m_listChild.begin(), m_listChild.end(), static_cast< KUIWnd * >( pBaseControl ) ); // ItemBase.
std::list<KUIWnd*>::iterator it_select = std::find( m_listChild.begin(), m_listChild.end(), sList.m_pSelectedControl ); // SelectControl.
if( it_itembase != m_listChild.end() && it_select != m_listChild.end() )
{
m_listChild.erase( it_select );
m_listChild.insert( ( ++it_itembase ), sList.m_pSelectedControl ); // insert는 iterator의 앞쪽에 추가되므로 + 1 한다.
}
}
}
}