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

1248 lines
31 KiB
C++

#include "stdafx.h"
#include "KUITextureManager.h"
#include "KUIWndManager.h"
#include "KUIListControl.h"
#include <map>
using namespace std;
KUIListItem::KUIListItem()
: m_bExtendBaseCtrl( false ),
m_bShow( true ),
m_bHalfExtend( false )
{
}
KUIListItem::~KUIListItem()
{
Release(); // 메모리 해제.
}
// 메모리 해제.
void KUIListItem::Release()
{
m_bExtendBaseCtrl = false;
m_pBaseControl = NULL; // Base Control.
// Column Controls.
// 부모윈도우에 등록되어있는 Control들은 부모윈도우에서 해제하므로
// 이곳에선 list만 해제한다.
m_Columns.clear();
}
// Item내부의 Control 보임, 숨김 처리.
void KUIListItem::SetShowControl( bool bShow )
{
m_pBaseControl->SetShow( bShow );
//m_pBaseControl->SetShow( m_pBaseControl->IsShow() ? bShow : false );
KRect baseRt = m_pBaseControl->GetRect();
// Columns Rect.
for( list< KUIControl * >::iterator it = m_Columns.begin(); it != m_Columns.end(); it++ )
{
if( baseRt.IsIntersect( (*it)->GetRect() ) )
(*it)->SetShow( bShow ? true : bShow );
else
(*it)->SetShow( false );
}
}
// Item 보임, 숨김 처리.
void KUIListItem::SetShowItem( bool bShow )
{
m_bShow = bShow;
m_pBaseControl->SetShow( bShow );
// Columns Rect.
for( list< KUIControl * >::iterator it = m_Columns.begin(); it != m_Columns.end(); ++it )
{
(*it)->SetShow( bShow );
}
}
// Item 에 속하는 자식 컨트롤들의 보임, 숨김 처리.
void KUIListItem::SetShowItemChild( bool bShow )
{
m_bShow = bShow;
//m_pBaseControl->SetShow( bShow );
// Columns Rect.
for( list< KUIControl * >::iterator it = m_Columns.begin(); it != m_Columns.end(); ++it )
{
(*it)->SetShow( bShow );
}
}
// 높이 위치값 재조정.
void KUIListItem::ReadjustPosition( int index, int gap )
{
// Base Rect.
KRect crrRect = m_pBaseControl->GetRect();
int height = crrRect.GetHeight() + gap;
int h = index * height;
m_pBaseControl->MovePosOffset( 0, h );
// Columns Rect.
for( list< KUIControl * >::iterator it = m_Columns.begin(); it != m_Columns.end(); ++it )
{
(*it)->MovePosOffset( 0, h );
}
}
// 높이 위치값 재조정.
void KUIListItem::ReadjustPosition( int pushHeight )
{
if( pushHeight == 0 )
return;
m_pBaseControl->MovePosOffset( 0, pushHeight );
// Columns Rect.
for( list< KUIControl * >::iterator it = m_Columns.begin(); it != m_Columns.end(); ++it )
{
(*it)->MovePosOffset( 0, pushHeight );
}
}
// Base Control 의 높이값.
int KUIListItem::GetBaseHeight()
{
return m_pBaseControl->GetRect().GetHeight();
}
// 마우스 충돌검사.
bool KUIListItem::Collision( int mouseX, int mouseY )
{
return m_pBaseControl->IsInRect( mouseX, mouseY );
}
// column 구하기.
bool KUIListItem::GetColumnIndex( int & out_columnIndex, int mouseX, int mouseY )
{
int i = 0;
for( list< KUIControl * >::iterator it = m_Columns.begin(); it != m_Columns.end(); ++it, i++ )
{
// 선택!
if( (*it)->IsInRect( mouseX, mouseY ) )
{
ITEMTYPE type = ITEMTYPE::TYPE_ITEM_Column;
out_columnIndex = i;
return true;
}
}// for
return false;
}
// Column Control 설정.
void KUIListItem::AddColumn( KUIControl * pColumn )
{
m_Columns.push_back( pColumn );
}
// Column Control 반환. 성공:true / 실패:false
bool KUIListItem::GetControl( KUIControl *& out_pControl/*OUT*/, int column )
{
list< KUIControl * >::iterator it = m_Columns.begin();
for( int i=0; i<column; ++i )
++it;
if( it != m_Columns.end() )
{
out_pControl = (*it);
return true;
}
return false;
}
// Column Control 반환. 성공:true / 실패:false
bool KUIListItem::GetControl( KUIControl *& out_pControl/*OUT*/, const char * strID )
{
for( list< KUIControl * >::iterator it=m_Columns.begin(); it!=m_Columns.end(); ++it )
{
if( !::_stricmp( strID, (*it)->GetID() ) )
{
out_pControl = (*it);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//
// class KUIListControl
//
KUIListControl::KUIListControl( KUIWnd * pParent, char * strList, char * strHeader, char * strItem, int listCount, bool bExtendControl/*=false*/, int gap/*=0*/, int magnifycation/*=1*/ )
: m_pParentWnd( pParent ),
m_StrList( strList ), m_StrBaseHeader( strHeader ), m_StrBaseItem( strItem ),
m_pHeader( NULL ),
m_nListCount( listCount ), m_Gap( gap ), m_nMagnifycation( magnifycation ),
m_nSelectedIndex( -1 ),
m_bExtendControl( bExtendControl ),
m_nListDataCountMAX( 0 ),
m_bExtendAll( false ),
m_nListControlIndex( 0 )
{
// MOUSE EVENT 정의.
m_Map_MouseEvent.insert( make_pair(KLBUTTON_DOWN, KUI_MESSAGE::KLIST_ITEM_LBUTTON_DOWN) );
m_Map_MouseEvent.insert( make_pair(KRBUTTON_DOWN, KUI_MESSAGE::KLIST_ITEM_RBUTTON_DOWN) );
m_Map_MouseEvent.insert( make_pair(KLBUTTON_UP, KUI_MESSAGE::KLIST_ITEM_LBUTTON_UP) );
m_Map_MouseEvent.insert( make_pair(KRBUTTON_UP, KUI_MESSAGE::KLIST_ITEM_RBUTTON_UP) );
m_Map_MouseEvent.insert( make_pair(KMOUSE_MOVE, KUI_MESSAGE::KLIST_ITEM_MOUSEMOVE) );
m_Map_MouseEvent.insert( make_pair(KLBUTTON_DBLCLK, KUI_MESSAGE::KLIST_ITEM_LBUTTON_DBCLICK) );
}
KUIListControl::~KUIListControl()
{
Release(); // 메모리 해제.
}
// 메모리 해제.
void KUIListControl::Release()
{
m_arrShowIndex.clear();
m_ArrItemState.clear();
// Header.
m_arrHeaderColumn.clear();
if( m_pHeader )
delete m_pHeader;
// Item.
KUIListItem * pTemp = NULL;
m_arrItemColumn.clear();
for( list< KUIListItem * >::iterator it=m_ListRows.begin(); it!=m_ListRows.end(); ++it )
{
pTemp = NULL;
pTemp = (*it);
if( pTemp )
delete pTemp;
}
m_ListRows.clear();
}
void KUIListControl::AddStringHeaderColumn( char * str )
{
m_arrHeaderColumn.push_back( string( str ) );
}
void KUIListControl::AddStringItemColumn( char * str )
{
m_arrItemColumn.push_back( string( str ) );
}
// ** 컬럼명 추가 후 반드시 호출할것.
// string을 이용해 control을 가져와 원하는 개수만큼 복사하여 리스트를 형성한다.
void KUIListControl::Create()
{
if( m_pParentWnd )
{
// 부모 Wnd.
this->SetParent( m_pParentWnd );
// List Control 의 Base.
m_ListControl = static_cast< KUIControl * >( m_pParentWnd->GetChild( m_StrList.c_str() ) );
//-------------------------
// Header.
//
if( m_StrBaseHeader != "" && m_StrBaseHeader.size() > 0 )
{
KUIListItem * pItemHeader = new KUIListItem();
// Base
pItemHeader->SetBase( static_cast< KUIControl * >( m_pParentWnd->GetChild( m_StrBaseHeader.c_str() ) ) );
// Columns
for( vector< string >::iterator it=m_arrHeaderColumn.begin(); it!=m_arrHeaderColumn.end(); ++it )
{
pItemHeader->AddColumn( static_cast< KUIControl * >( m_pParentWnd->GetChild( (*it).c_str() ) ) );
}
// List 에 Header 등록.
this->SetHeader( pItemHeader );
}
else
{
// Header 가 존재하지 않는 리스트 이다.
this->SetHeader( NULL );
}
//-------------------------
// Item.
//
string strBase = m_StrBaseItem;
for( int i=0; i<m_nListCount; i++ )
{
KUIListItem * pItem = new KUIListItem();
// Base
pItem->SetBase( static_cast< KUIControl * >( m_pParentWnd->GetChild( m_StrBaseItem.c_str() ) )->Clone() );
// Columns
for( vector< string >::iterator it=m_arrItemColumn.begin(); it!=m_arrItemColumn.end(); ++it )
{
pItem->AddColumn( static_cast< KUIControl * >( m_pParentWnd->GetChild( (*it).c_str() ) )->Clone() );
}
// List 에 Item 등록.
this->AddItem( pItem );
}
// 원본 사이즈 보관.
m_SrcRect = m_pParentWnd->GetChild( m_StrBaseItem.c_str() )->GetRect();
// 기본이 되는 기존 Base Item 숨김처리.
for( int i=0; i<m_nListCount; i++ )
{
// Base
m_pParentWnd->GetChild( m_StrBaseItem.c_str() )->SetShow( false );
// Columns
for( vector< string >::iterator it=m_arrItemColumn.begin(); it!=m_arrItemColumn.end(); ++it )
m_pParentWnd->GetChild( (*it).c_str() )->SetShow( false );
}
// ListControl 의 영역.
m_RectListControl = m_ListControl->GetRect();
this->SetRect( m_RectListControl );
}
}
// Header Item.
void KUIListControl::SetHeader( KUIListItem * pHeader )
{
m_pHeader = pHeader;
}
// 스크롤 다운, 최상위 아이템을 제거.
void KUIListControl::ScrollUp()
{
// 백업
KUIListItem * pTemp = m_ListRows.front();
int height = pTemp->GetBaseHeight();
// Pop
m_ListRows.pop_front();
KUIListItem * pBack = m_ListRows.back();
int backLeft = pBack->GetRect().left;
int backTop = pBack->GetRect().top;
// 위치 조절 ( 위로 올림 ).
for( list< KUIListItem * >::iterator it = m_ListRows.begin(); it != m_ListRows.end(); ++it )
{
(*it)->MovePosOffset( 0, -height );
}
pTemp->MovePos(backLeft, backTop);
m_ListRows.push_back(pTemp);
}
// 스크롤 업, 최하위 아이템을 제거.
void KUIListControl::ScrollDown()
{
// 백업
KUIListItem * pTemp = m_ListRows.back();
int height = pTemp->GetBaseHeight();
// Pop
m_ListRows.pop_back();
KUIListItem * pFront = m_ListRows.front();
int frontLeft = pFront->GetRect().left;
int frontTop = pFront->GetRect().top;
// 위치 조절 ( 아래로 내림 ).
for( list< KUIListItem * >::iterator it = m_ListRows.begin(); it != m_ListRows.end(); ++it )
{
(*it)->MovePosOffset( 0, height );
}
pTemp->MovePos(frontLeft, frontTop);
m_ListRows.push_front(pTemp);
}
// 아이템을 생성하여 반환한다.
KUIListItem * KUIListControl::CreateItem()
{
KUIListItem * pItem = new KUIListItem();
// Base
pItem->SetBase( static_cast< KUIControl * >( m_pParentWnd->GetChild( m_StrBaseItem.c_str() ) )->Clone() );
// Columns
for( vector< string >::iterator it=m_arrItemColumn.begin(); it!=m_arrItemColumn.end(); ++it )
{
pItem->AddColumn( static_cast< KUIControl * >( m_pParentWnd->GetChild( (*it).c_str() ) )->Clone() );
}
return pItem;
}
// 생성한 KUIListItem을 자식리스트에 넣어 관리한다.
void KUIListControl::AddItem( KUIListItem * p )
{
// 위치조절.
p->ReadjustPosition( m_ListRows.size(), m_Gap );
// 내부컨트롤들의 숨김처리. (확장시에만 나와야하는 경우의 컨트롤들)
p->SetShowControl( true );
// 추가.
m_ListRows.push_back( p );
}
// Item 을 생성하고 List에 추가한다.
void KUIListControl::AddItem()
{
AddItem( CreateItem() );
}
// 아이템 제거.
void KUIListControl::DeleteItem( int index )
{
if( m_ListRows.size() > index )
{
list< KUIListItem * >::iterator it = m_ListRows.begin();
for( int i=0; i<index; ++i )
++it;
if( it != m_ListRows.end() )
{
KRect rt = (*it)->GetRect();
int h = index * rt.GetHeight() + index * m_Gap;
delete (*it);
it = m_ListRows.erase( it );
// 제거대상 아래의 아이템들은 위치를 위로 올린다.
for( ; it != m_ListRows.end(); ++it )
{
KRect rect = (*it)->GetRect();
rect.top = h;
rect.bottom = rect.top + rt.GetHeight();
(*it)->SetRect( rect );
}
}
}
}
// 마우스 좌표에 따른 선택정보 반환.
// * type - header OR baseItem OR column
// * index - 아이템경우 index.
bool KUIListControl::GetSeletionInfo( ITEMTYPE & out_type, int & out_index, int & out_columnIndex, int mouseX, int mouseY )
{
bool bFind = false;
out_type = ITEMTYPE::TYPE_NONE;
// 헤더검사
if( m_pHeader && m_pHeader->Collision( mouseX, mouseY ) )
{
bFind = true;
out_type = ITEMTYPE::TYPE_HEADER_Base;
// Column 찾기.
// 선택 control 을 찾았으면 true 반환.
if( m_pHeader->GetColumnIndex( out_columnIndex, mouseX, mouseY ) )
{
bFind = true;
out_type = ITEMTYPE::TYPE_HEADER_Column;
return bFind;
}
}
// 아이템검사
if( !bFind )
{
int i = 0; // 아이템 index.
for( list< KUIListItem * >::iterator it = m_ListRows.begin(); it != m_ListRows.end(); ++it, i++ )
{
// 선택!
if( (*it)->Collision( mouseX, mouseY ) )
{
bFind = true;
out_type = ITEMTYPE::TYPE_ITEM_Base;
out_index = i;
KUIListItem * pItem = (*it);
// Column 찾기.
// 선택 control 을 찾았으면 true 반환.
if( pItem->GetColumnIndex( out_columnIndex, mouseX, mouseY ) )
{
bFind = true;
out_type = ITEMTYPE::TYPE_ITEM_Column;
}
break;
}
}// for
}
return bFind;
}
// 마우스이벤트에 따른 Control이벤트를 처리하여
// 부모윈도우로 메세지를 전송한다.
DWORD KUIListControl::OnMouseMessage( DWORD dwMessage, int x, int y )
{
DWORD dwRet = KUIControl::OnMouseMessage(dwMessage,x,y);
if( m_ListControl->IsInRect(x,y) )
{
ITEMTYPE type = ITEMTYPE::TYPE_NONE;
int rowIndex = 0;
int columnIndex = 0;
// 선택정보 얻어오기.
if( GetSeletionInfo( type, rowIndex, columnIndex, x, y ) )
{
/*if( dwMessage == KLBUTTON_DOWN || dwMessage == KLBUTTON_UP ||
dwMessage == KRBUTTON_DOWN || dwMessage == KRBUTTON_UP || dwMessage == KLBUTTON_DBLCLK )
{*/
// 부모윈도우로 보낼 메세지 생성.
MSG_LISTCONTROL _msg( type, rowIndex, columnIndex, m_nListControlIndex );
DWORD pumpMsg = *( (DWORD *)( &_msg ) );
// 부모 PumpUpMessage에서 형변환 예제.
// ** MSG_LISTCONTROL msg = *( (MSG_LISTCONTROL *)( &pumpMsg ) );
// 해당 UI Control.
KUIControl * pControl;
this->GetControl( pControl, type, rowIndex, columnIndex );
// 부모창으로 메세지 펌프.
PumpUpMessage( pControl->GetID(), m_Map_MouseEvent[ dwMessage ], pumpMsg, 0 );
//}
}
}
return dwRet;
}
// 스크롤 처리. nValue:스크롤의 움직임값.
void KUIListControl::UpdateScrollBar( int nOldPos, int nCrrPos )
{
int nUpdatePos = nCrrPos - nOldPos;
// 음수이면 스크롤다운.
if( nUpdatePos < 0 )
{
for( int i=0; i>nUpdatePos; --i )
ScrollDown();
}
// 양수이면 스크롤업.
else if( nUpdatePos > 0 )
{
for( int i=0; i<nUpdatePos; ++i )
ScrollUp();
}
}
// List 상태 변경.
void KUIListControl::UpdateListItem()
{
}
//
// 기본적인 메세지 처리를 한다.
void KUIListControl::PumpUpMessage( LPCSTR lpszControlID, DWORD nMessage, DWORD lParam, DWORD wParam )
{
//switch( nMessage )
//{
////// Scroll Control 처리.
////case KUI_MESSAGE::KSCROLL_SELECT:
//// {
//// int nPos = (int)lParam;
////
//// _oprint( "********************************** Scroll : %d\n", nPos );
//// }
//// break;
//}
// 부모창으로 메세지를 Pumping한다.
KUIControl::PumpUpMessage( lpszControlID, nMessage, lParam, wParam);
}
// 인자에 해당하는 Control 을 반환.
bool KUIListControl::GetControl( KUIControl *& out_pControl/*OUT*/, ITEMTYPE type, int row, int column )
{
bool bRes = false;
/////////////////////
// HEADER
if( m_pHeader && type == ITEMTYPE::TYPE_HEADER_Base )
{
bRes = true;
out_pControl = m_pHeader->GetBaseControl();
}
// HEADER Column
else if( m_pHeader && type == ITEMTYPE::TYPE_HEADER_Column )
{
bRes = m_pHeader->GetControl( out_pControl, column );
}
///////////////////
// ITEM
else if( type == ITEMTYPE::TYPE_ITEM_Base )
{
list< KUIListItem * >::iterator it = m_ListRows.begin();
for( int i=0; i<row; ++i )
++it;
if( it != m_ListRows.end() )
{
bRes = true;
out_pControl = (*it)->GetBaseControl();
}
}
// ITEM Column
else if( type == TYPE_ITEM_Column )
{
list< KUIListItem * >::iterator it = m_ListRows.begin();
for( int i=0; i<row; ++i )
++it;
if( it != m_ListRows.end() )
bRes = (*it)->GetControl( out_pControl, column );
}
return bRes;
}
// 인자에 해당하는 Control 을 반환.
bool KUIListControl::GetControl( KUIControl *& out_pControl/*OUT*/, ITEMTYPE type, int row, const char * strID )
{
bool bRes = false;
/////////////////////
// HEADER
if( m_pHeader && type == ITEMTYPE::TYPE_HEADER_Base )
{
bRes = true;
out_pControl = m_pHeader->GetBaseControl();
}
// HEADER Column
else if( m_pHeader && type == ITEMTYPE::TYPE_HEADER_Column )
{
bRes = m_pHeader->GetControl( out_pControl, strID );
}
///////////////////
// ITEM
else if( type == ITEMTYPE::TYPE_ITEM_Base )
{
list< KUIListItem * >::iterator it = m_ListRows.begin();
for( int i=0; i<row; ++i )
++it;
if( it != m_ListRows.end() )
{
bRes = true;
out_pControl = (*it)->GetBaseControl();
}
}
// ITEM Column
else if( type == TYPE_ITEM_Column )
{
list< KUIListItem * >::iterator it = m_ListRows.begin();
for( int i=0; i<row; ++i )
++it;
if( it != m_ListRows.end() )
bRes = (*it)->GetControl( out_pControl, strID );
}
return bRes;
}
// KUIListItem 반환.
KUIListItem * KUIListControl::GetItem( int row )
{
if( row < m_ListRows.size() )
{
std::list< KUIListItem * >::iterator it = m_ListRows.begin();
for( int i=0; i<row; i++ )
it++;
if( it != m_ListRows.end() )
return (*it);
}
return NULL;
}
// Front KUIListItem 반환.
KUIListItem * KUIListControl::GetFrontItem()
{
return m_ListRows.front();
}
// End KUIListItem 반환.
KUIListItem * KUIListControl::GetEndItem()
{
return m_ListRows.back();
}
// 배율만큼 사이즈 조정
void KUIListControl::SetResizeWidth( KUIControl * pControl, float nMagnifycation )
{
KRect rt = pControl->GetRect();
rt.bottom = rt.top + rt.GetHeight() * nMagnifycation;
pControl->Resize( rt );
}
// 배율만큼 세로 사이즈 조정
void KUIListControl::SetResizeWidth( unsigned int type, int nRow, int nCol, float nMagnifycation, int scrollPos )
{
int targetListIndex = 0; // list컨트롤의 아이템에 실제로 들어오는 정보의 인덱스.
// 스크롤을 움직이지 않았음.
if( scrollPos == 0 )
targetListIndex = nRow;
else
targetListIndex = scrollPos + nRow;
KUIListItem * pItem = GetItem( nRow );
if( targetListIndex < m_ArrItemState.size() )
{
// 확장되어있다. 원본크기로 줄임.
if( pItem->m_bExtendBaseCtrl )
{
m_ArrItemState[ targetListIndex ] = SItemState( false, nRow );
pItem->m_bExtendBaseCtrl = false;
ResizeSourceWidth( type, nRow, nCol, nMagnifycation );
// 보이는 최하단아이템의 확장상태가 반겹침인 경우에서, 확장상태로 전환.
SetEndItemExtend();
}
// 확장시킨다.
else
{
m_ArrItemState[ targetListIndex ] = SItemState( true, nRow );
pItem->m_bExtendBaseCtrl = true;
KUIControl * pControl = pItem->GetBaseControl();
if( pControl )
{
KRect rt = pControl->GetRect();
int prevHeight = rt.GetHeight();
rt.bottom = rt.top + rt.GetHeight() * nMagnifycation;
pControl->Resize( rt );
//
// 해당 컨트롤의 사이즈 조정으로 인한 나머지(하위) Item들의 위치조정.
ReadjustPosition( nRow + 1, rt.GetHeight() - prevHeight );
}
}
}
}
// 원본사이즈로 되돌림.
void KUIListControl::ResizeSourceWidth( KUIControl * pControl, float nMagnifycation )
{
KRect rt = pControl->GetRect();
rt.bottom = rt.top + m_SrcRect.GetHeight();
pControl->Resize( rt );
// pControl->Resize( m_SrcRect );
}
// 원본사이즈로 되돌림.
void KUIListControl::ResizeSourceWidth( unsigned int type, int nRow, int nCol, float nMagnifycation )
{
KUIListItem * pItem = GetItem( nRow );
if( pItem )
{
pItem->m_bExtendBaseCtrl = false;
KUIControl * pControl = pItem->GetBaseControl();
/*int prevHeight = pControl->GetRect().GetHeight();
pControl->Resize( m_SrcRect );*/
KRect rt = pControl->GetRect();
int prevHeight = rt.GetHeight();
rt.bottom = rt.top + m_SrcRect.GetHeight();
pControl->Resize( rt );
//
// 해당 컨트롤의 사이즈 조정으로 인한 나머지(하위) Item들의 위치조정.
ReadjustPosition( nRow + 1, m_SrcRect.GetHeight() - prevHeight );
}
}
void KUIListControl::ResizeSourceHeight( int nRow )
{
KUIListItem * pItem = GetItem( nRow );
if( pItem )
{
pItem->m_bExtendBaseCtrl = false;
KUIControl * pControl = pItem->GetBaseControl();
KRect rt = pControl->GetRect();
int prevHeight = rt.GetHeight();
rt.bottom = rt.top + m_SrcRect.GetHeight();
pControl->Resize( rt );
pItem->SetShowControl( true ); // Item내부의 Control 보임, 숨김 처리.
}
}
//
void KUIListControl::RefreshList( int nScroll )
{
// 리스트컨트롤의 영역.
KRect listBaseRect = m_ListControl->GetRect();
KUIListItem * pItem;
for( int i=0; i<m_nListCount; i++ )
{
pItem = GetItem( i );
if( pItem )
{
//pItem->SetHalfExtension( false ); // 절반 확장상태 초기화.
// 최종적으로 보여야 할 item 인지 확인.
// 리스트컨트롤의 기본크기를 넘어가는 Item은 숨김처리.
if( listBaseRect.IsIntersect( pItem->GetBaseControl()->GetRect() ) )
{
vector< int >::iterator it = find( m_arrShowIndex.begin(), m_arrShowIndex.end(), i );
if( it != m_arrShowIndex.end() )
{
// 최종적으로 보여야할 아이템.
pItem->SetShowItem( true );
pItem->SetShowControl( true ); // Item내부의 Control 보임, 숨김 처리.
}
else
{
// 보이지 말아야할 아이템( ItemBase - 윤곽은 보이게 한다. )
pItem->SetShowItemChild( false );
}
}
else
{
pItem->SetShowItem( false );
pItem->SetShowControl( false ); // Item내부의 Control 보임, 숨김 처리.
}
//// 최종적으로 보여야 할 item 인지 확인.
//vector< int >::iterator it = find( m_arrShowIndex.begin(), m_arrShowIndex.end(), i );
//if( it != m_arrShowIndex.end() )
//{
// // 리스트컨트롤의 기본크기를 넘어가는 Item은 숨김처리.
// if( listBaseRect.IsIntersect( pItem->GetBaseControl()->GetRect() ) )
// {
// pItem->SetShowItem( true );
// pItem->SetShowControl( true ); // Item내부의 Control 보임, 숨김 처리.
// }
// else
// {
// pItem->SetShowItem( false );
// pItem->SetShowControl( false ); // Item내부의 Control 보임, 숨김 처리.
// }
//}
//else
//{
// pItem->SetShowItem( false );
// //pItem->SetShowItemChild( false );
//}
}
}
// 확장컨트롤의 경우에만 수행.
if( m_bExtendControl )
{
///////////
// 최하단 Item이 ListControl크기를 벗어난경우( 확장부분이 넘어간경우 ) 축소한다.
KUIListItem * pEndItem = this->FindEndItem(); // 보이는 최하단 Item.
if( pEndItem )
{
int nIndex = 0; // 마지막 아이템의 Row.
for( list< KUIListItem * >::iterator it=m_ListRows.begin(); it!=m_ListRows.end(); it++, nIndex++ )
{
if( pEndItem == (*it) )
break;
}
// 넘어간경우.
if( pEndItem->GetBaseControl()->GetRect().bottom > (m_ListControl->GetRect().bottom + 4) )
{
if( nIndex < (m_ArrItemState.size() - nScroll) )
{
// 원본 크기로..
ResizeSourceWidth( 0, nIndex, 0, 0 );
pEndItem->m_bExtendBaseCtrl = true; // 확장상태의 경우에만 넘어가므로 true 강제적용.
m_ArrItemState[ nIndex + nScroll ] = SItemState( true, nIndex ); // TEST
pEndItem->SetShowControl( true ); // Item내부의 Control 보임, 숨김 처리.
///////
// 보이는 최하단 컨트롤의 밑에, 내부컨트롤이없는( 깡통 아이템 ) 이 존재 할 경우에
// 창을 넘어가는 문제를 방지하기위해 추가.
if( nIndex + 1 < m_ArrItemState.size() )
{
// 원본 크기로..
ResizeSourceWidth( 0, nIndex, 0, 0 );
pEndItem->SetShowControl( false ); // Item내부의 Control 보임, 숨김 처리.
}
}
}
}
}
// 최종적으로 보이는 인덱스 클리어.
m_arrShowIndex.clear();
}
// index 아이템 이하(↓) 위치재조정.
void KUIListControl::ReadjustPosition( int index, int pushHeight )
{
// 리스트컨트롤의 영역.
KRect listBaseRect = m_ListControl->GetRect();
KUIListItem * pItem;
for( int i=index; i<m_nListCount; i++ )
{
pItem = GetItem( i );
pItem->ReadjustPosition( pushHeight );
}
}
void KUIListControl::RefreshItemState( int n )
{
// 이전 상태값을 저장.
m_OldArrItemState = m_ArrItemState;
int size = m_OldArrItemState.size();
//// 최대 리스트로 들어올 수 있는 개수만큼 상태정보를 가진다.
m_ArrItemState.clear();
m_ArrItemState.resize( n );
// 초기화.
for( int i=0; i<n; i++ )
{
m_ArrItemState[ i ] = SItemState();
if( i >= size )
{
m_ArrItemState[ i ].nRow = i;
if( m_bExtendAll )
m_ArrItemState[ i ].bExtend = m_bExtendAll;
}
/*KUIListItem * pItem = GetItem( i );
if( pItem )
pItem->m_bExtendBaseCtrl = false;*/
}
// 이전 상태값 적용.
for( int i=0; i<size; i++ )
{
int nIndex = m_OldArrItemState[i].nRow;
if( m_ArrItemState.size() > nIndex )
m_ArrItemState[ nIndex ] = m_OldArrItemState[i];
}
m_nListDataCountMAX = n;
}
// 전체 아이템의 확장 비확장여부.
int KUIListControl::GetIsAllExtend()
{
// 확장된 아이템의 개수와 전체아이템의 개수가 같으면,
// 전체아이템들이 모두 확장상태 이다.
int nExtendCount = GetExtendItemCount();
int nItemCount = m_ArrItemState.size();
if( nItemCount == nExtendCount ) // 전체 확장.
return ITEMEXTENDSTATE::ITEMEXTEND_EXTEND;
else if( nExtendCount == 0 ) // 전체 원본.
return ITEMEXTENDSTATE::ITEMEXTEND_ORIGINAL;
return ITEMEXTENDSTATE::ITEMEXTEND_NONE;
}
// 해당 아이템을 확장 or 축소(원본크기) 한다.
void KUIListControl::SetResize( int nRow, int nItemStateIndex, int nMagnifycation )
{
KUIListItem * pItem = GetItem( nRow );
// 최종적으로 보이는 인덱스.
m_arrShowIndex.push_back( nRow );
if( m_bExtendControl && pItem && nItemStateIndex < m_ArrItemState.size() )
{
// 확장되어있다. 원본크기로 줄임.
if( !m_ArrItemState[ nItemStateIndex ].bExtend )
{
pItem->m_bExtendBaseCtrl = false;
ResizeSourceWidth( 0, nRow, 0, 0 );
}
// 확장시킨다.
else
{
// 이전에 확장되어있지 않은경우에만 확장.
if( !pItem->m_bExtendBaseCtrl )
{
pItem->m_bExtendBaseCtrl = true;
KUIControl * pControl = pItem->GetBaseControl();
if( pControl )
{
KRect rt = pControl->GetRect();
int prevHeight = rt.GetHeight();
rt.bottom = rt.top + rt.GetHeight() * nMagnifycation;
pControl->Resize( rt );
//
// 해당 컨트롤의 사이즈 조정으로 인한 나머지(하위) Item들의 위치조정.
ReadjustPosition( nRow + 1, rt.GetHeight() - prevHeight );
}
}
else
ReadjustPosition( 0, 0 );
}
}
}
// 전체 아이템 확장 or 축소 한다.
void KUIListControl::SetResizeAll( bool bExtend )
{
m_bExtendAll = bExtend;
int size = m_ArrItemState.size();
for( int i=0; i<size; i++ )
{
m_ArrItemState[ i ] = SItemState( bExtend, i );
}
}
// ListControl에서 보이는 Item들중 최하단 아이템을 반환한다.
KUIListItem * KUIListControl::FindEndItem()
{
for( list< KUIListItem * >::reverse_iterator it=m_ListRows.rbegin();
it != m_ListRows.rend(); it++ )
{
KRect rt = (*it)->GetBaseControl()->GetRect();
if( rt.top < m_ListControl->GetRect().bottom )
{
return (*it);
}
}
return NULL;
}
// 아이템 상태배열에 선택활성화 여부 설정, 활성화는 한번에 하나만 되므로 나머지 아이템 활성화는 비활성화 한다.
void KUIListControl::SetSelectItem( int nScroll, int nRow )
{
int targetIndex = nScroll + nRow;
if( targetIndex < m_ArrItemState.size() )
{
m_nSelectedIndex = targetIndex;
}
}
// 리스트컨트롤 전체 보임,숨김 처리.( 내부 아이템들까지 영향. )
void KUIListControl::SetShowList( bool bShow )
{
for( list< KUIListItem * >::iterator it=m_ListRows.begin(); it!=m_ListRows.end(); it++ )
{
(*it)->SetShowItem( bShow );
}
}
// 아이템이 리스트에서 몇번째 인덱스인지 반환.
int KUIListControl::GetItemIndex( KUIListItem * pItem )
{
if( pItem )
{
int nIndex = 0;
for( list< KUIListItem * >::iterator it=m_ListRows.begin(); it!=m_ListRows.end(); it++, nIndex++ )
{
if( pItem == (*it) )
return nIndex;
}
}
return -1;
}
// 보이는 마지막 아이템의 인덱스 반환.
int KUIListControl::GetIndexOfVisibleEndItem()
{
return GetItemIndex( FindEndItem() );
}
// 확장된 아이템 개수.
int KUIListControl::GetExtendItemCount()
{
int extendCount = 0;
int size = m_ArrItemState.size();
for( int i=0; i<size; i++ )
{
if( m_ArrItemState[ i ].bExtend )
++extendCount;
}
return extendCount;
}
// 보이는 최하단아이템의 확장상태가 반겹침인 경우에서, 확장상태로 전환.
void KUIListControl::SetEndItemExtend()
{
// 보이는 마지막 아이템의 바로위 아이템.
int nRow = GetIndexOfVisibleEndItem();
if( nRow == -1 )
return;
//if( m_ArrItemState.size() - 1 == nRow )
if( nRow > 1 )
--nRow;
KUIListItem * pEnd = GetItem( nRow );
if( pEnd )
{
// // 절반 확장상태이다.
// if( pEnd->GetIsHalfExtension() )
// {
// KRect rt = pEnd->GetBaseControl()->GetRect();
//// m_SrcRect
// // 스크롤이 올라갔지만 실제 크기가 원본상태인 경우, 크기를 확장시킨다.
// if( ( rt.top + rt.GetHeight() * m_nMagnifycation ) <= m_ListControl->GetRect().bottom )
// {
// pEnd->m_bExtendBaseCtrl = true;
//
// int prevHeight = rt.GetHeight();
// rt.bottom = rt.top + rt.GetHeight() * m_nMagnifycation;
// pEnd->Resize( rt );
//
// //
// // 해당 컨트롤의 사이즈 조정으로 인한 나머지(하위) Item들의 위치조정.
// //ReadjustPosition( nRow + 1, rt.GetHeight() - prevHeight );
//
// // 절반 확장상태 취소.
// pEnd->SetHalfExtension( false );
//
// pEnd->SetShowControl( true ); // Item내부의 Control 보임, 숨김 처리.
//
// }
// }
KRect rt = pEnd->GetBaseControl()->GetRect();
// 절반 확장상태이다.
//if( m_ArrItemState[ nRow ].bExtend && pEnd->GetIsExtension() && rt.GetHeight() == m_SrcRect.GetHeight() )
if( pEnd->GetIsExtension() && rt.GetHeight() == m_SrcRect.GetHeight() )
{
// 스크롤이 올라갔지만 실제 크기가 원본상태인 경우, 크기를 확장시킨다.
int nBottom = rt.top + rt.GetHeight() * m_nMagnifycation;
if( nBottom <= m_ListControl->GetRect().bottom )
{
pEnd->m_bExtendBaseCtrl = false;
//int prevHeight = rt.GetHeight();
//rt.bottom = nBottom;
//pEnd->Resize( rt );
//
// 해당 컨트롤의 사이즈 조정으로 인한 나머지(하위) Item들의 위치조정.
//ReadjustPosition( nRow + 1, rt.GetHeight() - prevHeight );
// 절반 확장상태 취소.
//pEnd->SetHalfExtension( false );
//pEnd->SetShowControl( true ); // Item내부의 Control 보임, 숨김 처리.
}
}
}
}