744 lines
18 KiB
C++
744 lines
18 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2001.
|
|
// -------------------------------------------------------------------------
|
|
// File name: layerslistbox.cpp
|
|
// Version: v1.00
|
|
// Created: 10/4/2002 by Timur.
|
|
// Compilers: Visual C++ 7.0
|
|
// Description:
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "LayersListBox.h"
|
|
|
|
#include "Objects\ObjectManager.h"
|
|
|
|
// CLayersListBox dialog
|
|
#define INDENT_SIZE 16
|
|
#define ITEM_EXPANDED_BITMAP 2
|
|
#define ITEM_COLLAPSED_BITMAP 3
|
|
#define ITEM_LEAF_BITMAP 4
|
|
|
|
#define BUTTON_VISIBLE 0
|
|
#define BUTTON_USABLE 1
|
|
#define BUTTON_EXPAND 2
|
|
|
|
IMPLEMENT_DYNAMIC(CLayersListBox, CListBox)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CLayersListBox::CLayersListBox()
|
|
{
|
|
m_itemHeight = 24;
|
|
m_handCursor = false;
|
|
m_mousePaintFlags = 0;
|
|
m_mousePaintValue = false;
|
|
m_noReload = false;
|
|
m_draggingItem = -1;
|
|
m_rclickedItem = -1;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CLayersListBox::~CLayersListBox()
|
|
{
|
|
DeleteObject( m_hHandCursor );
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CLayersListBox, CListBox)
|
|
ON_WM_DRAWITEM_REFLECT()
|
|
ON_WM_MEASUREITEM_REFLECT()
|
|
ON_WM_COMPAREITEM_REFLECT()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
ON_WM_CREATE()
|
|
ON_WM_SETCURSOR()
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_RBUTTONDOWN()
|
|
ON_WM_RBUTTONUP()
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
// CLayersListBox message handlers
|
|
|
|
void CLayersListBox::DrawItem(LPDRAWITEMSTRUCT lpdis)
|
|
{
|
|
//dis->
|
|
if (lpdis->itemAction == ODA_SELECT || lpdis->itemAction == ODA_DRAWENTIRE)
|
|
{
|
|
CRect rc = lpdis->rcItem;
|
|
|
|
CDC dc;
|
|
dc.Attach(lpdis->hDC);
|
|
|
|
SLayerInfo &layerInfo = m_layersInfo[lpdis->itemData];
|
|
|
|
CString text = layerInfo.name;
|
|
|
|
CBrush brush( GetSysColor(COLOR_BTNFACE) );
|
|
//CBrush *prevBrush = dc.SelectObject( &brush );
|
|
HPEN prevPen = (HPEN)dc.SelectObject( (HPEN)GetStockObject(WHITE_PEN) );
|
|
|
|
CRect buttonRc = GetButtonsFrame(rc);
|
|
CRect nameRc;
|
|
nameRc.SubtractRect(rc,buttonRc);
|
|
|
|
CRect btnrc = buttonRc;
|
|
btnrc.top += 1;
|
|
dc.Draw3dRect( btnrc,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
|
|
|
|
if (lpdis->itemState & ODS_SELECTED)
|
|
{
|
|
// Selected
|
|
dc.FillSolidRect( nameRc,GetSysColor(COLOR_HIGHLIGHT) ); // blue.
|
|
//dc.DrawRect(rc,GetSysColor(COLOR_3DDKSHADOW),GetSysColor(COLOR_3DHILIGHT) );
|
|
dc.SetTextColor( GetSysColor(COLOR_HIGHLIGHTTEXT) );
|
|
}
|
|
else
|
|
{
|
|
// Normal.
|
|
dc.FillSolidRect( nameRc,GetSysColor(COLOR_BTNFACE) ); // blue.
|
|
//dc.Draw3dRect(rc,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
|
|
dc.SetTextColor( GetSysColor(COLOR_BTNTEXT) );
|
|
}
|
|
|
|
// Draw separator white line.
|
|
dc.MoveTo( nameRc.left,nameRc.top );
|
|
dc.LineTo( nameRc.right,nameRc.top );
|
|
|
|
//int indent = max(0,layerInfo.indent-1);
|
|
int indent = layerInfo.indent;
|
|
|
|
// Draw text.
|
|
int textX = nameRc.left + 3 + indent*INDENT_SIZE;
|
|
int textY = nameRc.top + (nameRc.bottom-nameRc.top)/2 - 8;
|
|
|
|
/*
|
|
if (layerInfo.indent > 0)
|
|
{
|
|
CPen pen(PS_SOLID,1,RGB(128,128,128) );
|
|
CPen *oldPen = dc.SelectObject( &pen );
|
|
CPoint center = nameRc.CenterPoint();
|
|
dc.MoveTo( textX-2,center.y );
|
|
dc.LineTo( textX-10,center.y );
|
|
//dc.LineTo( textX-10,nameRc.top );
|
|
dc.MoveTo( textX-10,rc.top );
|
|
if (layerInfo.lastchild)
|
|
dc.LineTo( textX-10,center.y );
|
|
else
|
|
dc.LineTo( textX-10,rc.bottom );
|
|
dc.SelectObject( oldPen );
|
|
}
|
|
*/
|
|
|
|
if (layerInfo.childs)
|
|
{
|
|
CRect expandRect = GetExpandButtonRect( lpdis->itemData );
|
|
//expandRect.left -= 14;
|
|
// Draw Expand icon.
|
|
if (layerInfo.expanded)
|
|
m_imageList.Draw( &dc,ITEM_EXPANDED_BITMAP,CPoint(expandRect.left,expandRect.top+5),ILD_TRANSPARENT );
|
|
else
|
|
m_imageList.Draw( &dc,ITEM_COLLAPSED_BITMAP,CPoint(expandRect.left,expandRect.top+5),ILD_TRANSPARENT );
|
|
textX += 14;
|
|
}
|
|
|
|
CFont *prevFont = NULL;
|
|
if (layerInfo.pLayer->IsExternal())
|
|
{
|
|
if (!m_externalFont.GetSafeHandle())
|
|
{
|
|
VERIFY(m_externalFont.CreateFont(-::MulDiv(8, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72), 0, 0, 0,
|
|
FW_DONTCARE, FALSE, TRUE, FALSE,
|
|
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
|
DEFAULT_PITCH, "Tahoma"));
|
|
}
|
|
prevFont = dc.SelectObject( &m_externalFont );
|
|
}
|
|
|
|
m_imageList.Draw( &dc,ITEM_LEAF_BITMAP,CPoint(textX,textY),ILD_TRANSPARENT );
|
|
dc.TextOut( textX+2+16,textY+2,text );
|
|
|
|
DrawCheckButton( dc,rc,0,m_layersInfo[lpdis->itemData].visible );
|
|
DrawCheckButton( dc,rc,1,m_layersInfo[lpdis->itemData].usable );
|
|
|
|
dc.SelectObject( prevPen );
|
|
if (prevFont)
|
|
dc.SelectObject( prevFont );
|
|
|
|
if (lpdis->itemData == m_layersInfo.size()-1)
|
|
{
|
|
HPEN prevPen = (HPEN)dc.SelectObject( (HPEN)GetStockObject(BLACK_PEN) );
|
|
// For last item draw black line at bottom.
|
|
dc.MoveTo( nameRc.left,nameRc.bottom-1 );
|
|
dc.LineTo( nameRc.right,nameRc.bottom-1 );
|
|
dc.SelectObject(prevPen);
|
|
}
|
|
//dc.SelectObject(prevBrush);
|
|
dc.Detach();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
|
|
{
|
|
// lpMeasureItemStruct->itemWidth = 0;
|
|
lpMeasureItemStruct->itemHeight = m_itemHeight;
|
|
//lpMeasureItemStruct->itemData = 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
int CLayersListBox::CompareItem( LPCOMPAREITEMSTRUCT lpCompareItemStruct )
|
|
{
|
|
//lpCompareItemStruct.
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::PreSubclassWindow()
|
|
{
|
|
CListBox::PreSubclassWindow();
|
|
Init();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
int CLayersListBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CListBox::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
Init();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::Init()
|
|
{
|
|
// Initialization.
|
|
SetItemHeight(0,m_itemHeight);
|
|
// SetFont( CFont::FromHandle( (HFONT)::GetStockObject(SYSTEM_FONT)) );
|
|
//m_imageList.Create( IDB_LAYER_BUTTONS,16,16,RGB(255,0,255) );
|
|
CMFCUtils::LoadTrueColorImageList( m_imageList,IDB_LAYER_BUTTONS,16,RGB(255,0,255) );
|
|
m_hHandCursor = LoadCursor( NULL,MAKEINTRESOURCE(IDC_HAND) );
|
|
|
|
CRect rc;
|
|
GetClientRect(rc);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
inline int CompareLayersInfo( const CLayersListBox::SLayerInfo &layer1,const CLayersListBox::SLayerInfo &layer2 )
|
|
{
|
|
return layer1.name < layer2.name;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CRect CLayersListBox::GetButtonRect( CRect &rcItem,int id )
|
|
{
|
|
int ofsx = 3;
|
|
int ofsy = 3;
|
|
int sz = m_itemHeight-ofsy;
|
|
CRect rc;
|
|
rc.left = rcItem.left + (sz+ofsx)*id + ofsx;
|
|
rc.right = rc.left + sz;
|
|
rc.top = rcItem.top + ofsy;
|
|
rc.bottom = rcItem.top + sz;
|
|
|
|
return rc;
|
|
}
|
|
|
|
CRect CLayersListBox::GetButtonsFrame( CRect &rcItem )
|
|
{
|
|
CRect buttonRc;
|
|
CRect brc = GetButtonRect(rcItem,1);
|
|
buttonRc = rcItem;
|
|
buttonRc.right = brc.right + 4;
|
|
return buttonRc;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::DrawCheckButton( CDC &dc,CRect &rcItem,int id,bool state )
|
|
{
|
|
CRect rc = GetButtonRect( rcItem,id );
|
|
|
|
dc.Draw3dRect(rc,GetSysColor(COLOR_3DDKSHADOW),GetSysColor(COLOR_3DHILIGHT));
|
|
if (state)
|
|
{
|
|
m_imageList.Draw( &dc,id,CPoint(rc.left+2,rc.top+1),ILD_TRANSPARENT );
|
|
}
|
|
else
|
|
{
|
|
//dc.Draw3dRect(rc,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CRect CLayersListBox::GetExpandButtonRect( int item )
|
|
{
|
|
assert( item >= 0 && item < m_layersInfo.size() );
|
|
CRect rcItem;
|
|
GetItemRect( item,rcItem );
|
|
|
|
CRect rcBtn(0,0,0,0);
|
|
|
|
SLayerInfo &layerInfo = m_layersInfo[item];
|
|
if (layerInfo.childs)
|
|
{
|
|
// See if hit expand button.
|
|
rcBtn = GetButtonsFrame(rcItem);
|
|
rcBtn.left = rcBtn.right + 3 + layerInfo.indent*INDENT_SIZE;
|
|
rcBtn.right = rcBtn.left + 14;
|
|
}
|
|
return rcBtn;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
int CLayersListBox::GetButtonFromPoint( CPoint point )
|
|
{
|
|
BOOL bOutside;
|
|
int button = -1;
|
|
// Find item where we clicked.
|
|
int item = ItemFromPoint( point,bOutside );
|
|
if (item != LB_ERR && !bOutside)
|
|
{
|
|
CRect rcItem;
|
|
GetItemRect( item,rcItem );
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
CRect buttonRc = GetButtonRect(rcItem,i);
|
|
buttonRc.InflateRect(0,5);
|
|
if (buttonRc.PtInRect(point))
|
|
{
|
|
button = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (button < 0)
|
|
{
|
|
if (GetExpandButtonRect(item).PtInRect(point))
|
|
button = BUTTON_EXPAND;
|
|
}
|
|
}
|
|
return button;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CLayersListBox::HandleMouseClick( UINT nFlags,CPoint point )
|
|
{
|
|
bool bNoSelect = false;
|
|
BOOL bOutside;
|
|
|
|
// Find item where we clicked.
|
|
int item = ItemFromPoint( point,bOutside );
|
|
if (item != LB_ERR && !bOutside)
|
|
{
|
|
CRect rcItem;
|
|
GetItemRect( item,rcItem );
|
|
|
|
/*
|
|
if (GetSel(item))
|
|
{
|
|
m_layersInfo[item].visible = true;
|
|
m_layersInfo[item].usable = true;
|
|
return true;
|
|
}
|
|
*/
|
|
|
|
CRect buttonRc = GetButtonsFrame(rcItem);
|
|
if (buttonRc.PtInRect(point))
|
|
{
|
|
// Clicked in button.
|
|
bNoSelect = true;
|
|
}
|
|
|
|
int button = GetButtonFromPoint(point);
|
|
if (button == BUTTON_VISIBLE)
|
|
{
|
|
m_mousePaintFlags = (1<<31) | button;
|
|
m_layersInfo[item].visible = !m_layersInfo[item].visible;
|
|
m_mousePaintValue = m_layersInfo[item].visible;
|
|
OnModifyLayer( item );
|
|
}
|
|
else if (button == BUTTON_USABLE)
|
|
{
|
|
m_mousePaintFlags = (1<<31) | button;
|
|
m_layersInfo[item].usable = !m_layersInfo[item].usable;
|
|
m_mousePaintValue = m_layersInfo[item].usable;
|
|
OnModifyLayer( item );
|
|
} else if (button == BUTTON_EXPAND)
|
|
{
|
|
bNoSelect = true;
|
|
m_layersInfo[item].pLayer->Expand( !m_layersInfo[item].pLayer->IsExpanded() );
|
|
ReloadLayers();
|
|
}
|
|
|
|
if (!bNoSelect && (nFlags & MK_CONTROL))
|
|
{
|
|
// Can only drag removable layers.
|
|
if (m_layersInfo[item].pLayer->IsRemovable())
|
|
{
|
|
// Start dragging.
|
|
m_draggingItem = item;
|
|
|
|
CPoint pos;
|
|
GetCursorPos(&pos);
|
|
// Initialize the drag image (usually called from WM_LBUTTONDOWN).
|
|
m_imageList.BeginDrag( ITEM_LEAF_BITMAP, CPoint(-10,-10));
|
|
m_imageList.DragEnter( this,point );
|
|
SetCapture();
|
|
Invalidate();
|
|
}
|
|
}
|
|
}
|
|
return bNoSelect;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
if (!HandleMouseClick(nFlags,point))
|
|
CListBox::OnLButtonDown(nFlags, point);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
m_mousePaintFlags = 0;
|
|
|
|
if (m_draggingItem >= 0)
|
|
{
|
|
m_imageList.DragLeave( this );
|
|
m_imageList.EndDrag();
|
|
ReleaseCapture();
|
|
Invalidate();
|
|
|
|
BOOL bOutside;
|
|
// Find item where we clicked.
|
|
int item = ItemFromPoint( point,bOutside );
|
|
if (item != LB_ERR && !bOutside)
|
|
{
|
|
if (item != m_draggingItem)
|
|
{
|
|
SLayerInfo &src = m_layersInfo[m_draggingItem];
|
|
SLayerInfo &trg = m_layersInfo[item];
|
|
if (!trg.pLayer->IsChildOf(src.pLayer))
|
|
{
|
|
trg.pLayer->AddChild(src.pLayer);
|
|
trg.pLayer->Expand(true);
|
|
ReloadLayers();
|
|
}
|
|
m_draggingItem = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SLayerInfo &src = m_layersInfo[m_draggingItem];
|
|
if (src.pLayer->GetParent())
|
|
{
|
|
src.pLayer->GetParent()->RemoveChild(src.pLayer);
|
|
ReloadLayers();
|
|
}
|
|
}
|
|
m_draggingItem = -1;
|
|
}
|
|
CListBox::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
{
|
|
BOOL bOutside;
|
|
// Find item where we clicked.
|
|
int item = ItemFromPoint( point,bOutside );
|
|
if (item != LB_ERR && !bOutside)
|
|
{
|
|
int button = GetButtonFromPoint(point);
|
|
if (button < 0 || button == BUTTON_EXPAND)
|
|
{
|
|
// Toggle expand status.
|
|
m_layersInfo[item].pLayer->Expand( !m_layersInfo[item].pLayer->IsExpanded() );
|
|
ReloadLayers();
|
|
}
|
|
else if (button == BUTTON_VISIBLE)
|
|
{
|
|
CUndo undo("Layer Modify");
|
|
bool bValue = m_layersInfo[item].visible;
|
|
// Set all layers to this value.
|
|
std::vector<CObjectLayer*> layers;
|
|
GetIEditor()->GetObjectManager()->GetLayersManager()->GetLayers( layers );
|
|
for (int i = 0; i < layers.size(); i++)
|
|
{
|
|
layers[i]->SetVisible(bValue,!layers[i]->IsExpanded() );
|
|
}
|
|
ReloadLayers();
|
|
} else if (button == BUTTON_USABLE)
|
|
{
|
|
CUndo undo("Layer Modify");
|
|
bool bUsable = m_layersInfo[item].usable;
|
|
// Set all layers to this value.
|
|
std::vector<CObjectLayer*> layers;
|
|
GetIEditor()->GetObjectManager()->GetLayersManager()->GetLayers( layers );
|
|
for (int i = 0; i < layers.size(); i++)
|
|
{
|
|
layers[i]->SetFrozen(!bUsable,!layers[i]->IsExpanded());
|
|
}
|
|
ReloadLayers();
|
|
}
|
|
}
|
|
CListBox::OnLButtonDblClk(nFlags, point);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::SetUpdateCallback( UpdateCallback &cb )
|
|
{
|
|
m_updateCalback = cb;
|
|
}
|
|
|
|
BOOL CLayersListBox::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
if (!m_handCursor)
|
|
{
|
|
return CListBox::OnSetCursor(pWnd, nHitTest, message);
|
|
}
|
|
SetCursor( m_hHandCursor );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CLayersListBox::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (m_draggingItem >= 0)
|
|
{
|
|
CPoint pos = point;
|
|
ClientToScreen(&pos);
|
|
m_imageList.DragMove( point );
|
|
return;
|
|
}
|
|
|
|
int button = GetButtonFromPoint(point);
|
|
if (button >= 0)
|
|
{
|
|
m_handCursor = true;
|
|
}
|
|
else
|
|
m_handCursor = false;
|
|
|
|
if (m_mousePaintFlags != 0)
|
|
{
|
|
BOOL bOutside;
|
|
int item = ItemFromPoint( point,bOutside );
|
|
if ((item != LB_ERR && !bOutside) && (m_mousePaintFlags & 0xF) == button)
|
|
{
|
|
if (button == 0)
|
|
{
|
|
m_mousePaintFlags = (1<<31) | button;
|
|
if (m_layersInfo[item].visible != m_mousePaintValue)
|
|
{
|
|
m_layersInfo[item].visible = m_mousePaintValue;
|
|
OnModifyLayer( item );
|
|
}
|
|
}
|
|
else if (button == 1)
|
|
{
|
|
m_mousePaintFlags = (1<<31) | button;
|
|
if (m_layersInfo[item].usable != m_mousePaintValue)
|
|
{
|
|
m_layersInfo[item].usable = m_mousePaintValue;
|
|
OnModifyLayer( item );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CListBox::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::SelectLayer( const CString &layerName )
|
|
{
|
|
for (int i = 0; i < m_layersInfo.size(); i++)
|
|
{
|
|
if (stricmp(layerName,m_layersInfo[i].name) == 0)
|
|
{
|
|
SetCurSel(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline bool CompareLayers( CObjectLayer *l1,CObjectLayer *l2 )
|
|
{
|
|
return stricmp(l1->GetName(),l2->GetName()) < 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::ReloadLayers()
|
|
{
|
|
if (m_noReload)
|
|
return;
|
|
/*
|
|
m_layersInfo.clear();
|
|
for (int i = 0; i < layers.size(); i++)
|
|
{
|
|
}
|
|
*/
|
|
m_layersInfo.clear();
|
|
|
|
CObjectLayerManager *pLayerManager = GetIEditor()->GetObjectManager()->GetLayersManager();
|
|
std::vector<CObjectLayer*> layers;
|
|
pLayerManager->GetLayers( layers );
|
|
|
|
std::sort( layers.begin(),layers.end(),CompareLayers );
|
|
|
|
for (int i = 0; i < layers.size(); i++)
|
|
{
|
|
CObjectLayer *pLayer = layers[i];
|
|
if (!pLayer)
|
|
continue;
|
|
if (pLayer->GetParent())
|
|
continue;
|
|
|
|
AddLayerRecursively( pLayer,0 );
|
|
}
|
|
|
|
ReloadListItems();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::AddLayerRecursively( CObjectLayer *pLayer,int level )
|
|
{
|
|
CLayersListBox::SLayerInfo layerInfo;
|
|
layerInfo.name = pLayer->GetName();
|
|
layerInfo.visible = pLayer->IsVisible();
|
|
layerInfo.usable = !pLayer->IsFrozen();
|
|
layerInfo.pLayer = pLayer;
|
|
layerInfo.indent = level;
|
|
layerInfo.childs = pLayer->GetChildCount() != 0;
|
|
layerInfo.expanded = pLayer->IsExpanded();
|
|
m_layersInfo.push_back(layerInfo);
|
|
|
|
if (pLayer->IsExpanded())
|
|
{
|
|
int numLayers = pLayer->GetChildCount();
|
|
for (int i = 0; i < numLayers; i++)
|
|
{
|
|
CObjectLayer *pChild = pLayer->GetChild(i);
|
|
if (pChild)
|
|
AddLayerRecursively( pChild,level+1 );
|
|
|
|
if (i == numLayers-1)
|
|
{
|
|
m_layersInfo[m_layersInfo.size()-1].lastchild = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::ReloadListItems()
|
|
{
|
|
CObjectLayerManager *pLayerManager = GetIEditor()->GetObjectManager()->GetLayersManager();
|
|
CString selectedLayerName = pLayerManager->GetCurrentLayer()->GetName();
|
|
int sel = LB_ERR;
|
|
SetRedraw(FALSE);
|
|
ResetContent();
|
|
for (int i = 0; i < m_layersInfo.size(); i++)
|
|
{
|
|
int id = AddString( m_layersInfo[i].name );
|
|
if (m_layersInfo[i].name == selectedLayerName)
|
|
sel = id;
|
|
SetItemData(id,i);
|
|
}
|
|
if (sel != LB_ERR)
|
|
{
|
|
SetCurSel(sel);
|
|
}
|
|
SetRedraw(TRUE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::OnModifyLayer( int index )
|
|
{
|
|
assert( index >= 0 && index < m_layersInfo.size() );
|
|
|
|
CUndo undo("Layer Modify");
|
|
m_noReload = true;
|
|
SLayerInfo &li = m_layersInfo[index];
|
|
bool bRecursive = !(li.pLayer->IsExpanded());
|
|
li.pLayer->SetVisible( li.visible,bRecursive );
|
|
li.pLayer->SetFrozen( !li.usable,bRecursive );
|
|
m_noReload = false;
|
|
|
|
CRect rcItem;
|
|
GetItemRect( index,rcItem );
|
|
InvalidateRect( rcItem );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::OnRButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
m_rclickedItem = -1;
|
|
BOOL bOutside;
|
|
int item = ItemFromPoint( point,bOutside );
|
|
if (item != LB_ERR && !bOutside)
|
|
{
|
|
m_rclickedItem = item;
|
|
SetCurSel( item );
|
|
CObjectLayer *pLayer = GetCurrentLayer();
|
|
if (pLayer)
|
|
{
|
|
GetIEditor()->GetObjectManager()->GetLayersManager()->SetCurrentLayer( pLayer );
|
|
}
|
|
}
|
|
|
|
CListBox::OnRButtonDown(nFlags, point);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CLayersListBox::OnRButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
BOOL bOutside;
|
|
int item = ItemFromPoint( point,bOutside );
|
|
if (item != LB_ERR && !bOutside)
|
|
{
|
|
if (item == m_rclickedItem)
|
|
{
|
|
// Show context menu.
|
|
NMHDR hdr;
|
|
hdr.code = LBN_LAYERS_RBUTTON_UP;
|
|
hdr.hwndFrom = m_hWnd;
|
|
hdr.idFrom = GetDlgCtrlID();
|
|
LRESULT hres;
|
|
hres = GetParent()->SendMessage( WM_NOTIFY,(WPARAM)GetDlgCtrlID(),(LPARAM)(&hdr) );
|
|
if (hres != 0)
|
|
{
|
|
m_rclickedItem = -1;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
m_rclickedItem = -1;
|
|
|
|
CListBox::OnRButtonUp(nFlags, point);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CObjectLayer* CLayersListBox::GetCurrentLayer()
|
|
{
|
|
int sel = GetCurSel();
|
|
if (sel != LB_ERR)
|
|
{
|
|
return m_layersInfo[sel].pLayer;
|
|
}
|
|
return 0;
|
|
}
|