2016-03-11 14:57:17 +01:00
|
|
|
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
|
|
|
|
|
|
|
// DlgBrowseByClass.cpp : implementation file
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "DlgBrowseByClass.h"
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
#undef new
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
#undef THIS_FILE
|
|
|
|
static char THIS_FILE[] = __FILE__;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CDlgBrowseByClass dialog
|
|
|
|
|
|
|
|
CDynamicContainer<CEntity> dcEntities;
|
|
|
|
|
|
|
|
// property description formats
|
|
|
|
#define PDF_STRING 0
|
|
|
|
#define PDF_FLOAT 1
|
|
|
|
#define PDF_INDEX 2
|
|
|
|
#define PDF_COLOR 3
|
|
|
|
|
|
|
|
#define COLUMN_CLASS 0
|
|
|
|
#define COLUMN_NAME 1
|
|
|
|
#define COLUMN_DESCRIPTION 2
|
|
|
|
#define COLUMN_SECTOR_NAME 3
|
|
|
|
#define COLUMN_INDEX 4
|
|
|
|
#define COLUMN_SPAWN_FLAGS 5
|
|
|
|
#define COLUMN_DISTANCE 6
|
|
|
|
#define COLUMN_X 7
|
|
|
|
#define COLUMN_Y 8
|
|
|
|
#define COLUMN_Z 9
|
|
|
|
#define COLUMN_H 10
|
|
|
|
#define COLUMN_P 11
|
|
|
|
#define COLUMN_B 12
|
|
|
|
#define COLUMN_PROPERTY_START 13
|
|
|
|
|
|
|
|
CEntity *_penForDistanceSort = NULL;
|
|
|
|
BOOL _bOfSameClass=FALSE;
|
|
|
|
INDEX _ctProperties=0;
|
|
|
|
CDynamicContainer<class CEntity> _tempContainer;
|
|
|
|
BOOL _bTempContainer=FALSE;
|
|
|
|
|
|
|
|
BOOL AreAllEntitiesOfTheSameClass(CDynamicContainer<class CEntity> *penContainer)
|
|
|
|
{
|
|
|
|
// obtain this entity's class ptr
|
|
|
|
CEntityClass *pdecClass = NULL;
|
|
|
|
// add each entity in container
|
|
|
|
{FOREACHINDYNAMICCONTAINER(*penContainer, CEntity, iten)
|
|
|
|
{
|
|
|
|
// obtain this entity's class ptr
|
|
|
|
CEntityClass *pdecCurrentClass = iten->GetClass();
|
|
|
|
if( pdecClass==NULL)
|
|
|
|
{
|
|
|
|
pdecClass=pdecCurrentClass;
|
|
|
|
}
|
|
|
|
if( pdecClass!=pdecCurrentClass)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CTString GetPropertyValue(CEntity *pen, CEntityProperty *pepProperty, INDEX &iFormat)
|
|
|
|
{
|
|
|
|
CTString strResult="";
|
|
|
|
iFormat=PDF_STRING;
|
|
|
|
// see type of changing property
|
|
|
|
switch( pepProperty->ep_eptType)
|
|
|
|
{
|
|
|
|
case CEntityProperty::EPT_FLAGS:
|
|
|
|
{
|
|
|
|
strResult.PrintF("0x%08x", ENTITYPROPERTY( pen, pepProperty->ep_slOffset, ULONG));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_ENUM:
|
|
|
|
{
|
|
|
|
// obtain enum property description object
|
|
|
|
CEntityPropertyEnumType *epEnum = pepProperty->ep_pepetEnumType;
|
|
|
|
INDEX iEnum = ENTITYPROPERTY( pen, pepProperty->ep_slOffset, INDEX);
|
|
|
|
// search for selected enum
|
|
|
|
BOOL bEnumFound=FALSE;
|
|
|
|
for(INDEX iEnumItem=0; iEnumItem<epEnum->epet_ctValues; iEnumItem++)
|
|
|
|
{
|
|
|
|
if(iEnum==epEnum->epet_aepevValues[ iEnumItem].epev_iValue)
|
|
|
|
{
|
|
|
|
strResult=epEnum->epet_aepevValues[ iEnumItem].epev_strName;
|
|
|
|
bEnumFound=TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( !bEnumFound)
|
|
|
|
{
|
|
|
|
strResult="Invalid enum value!!!";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_ANIMATION:
|
|
|
|
{
|
|
|
|
iFormat=PDF_INDEX;
|
|
|
|
INDEX iAnim = ENTITYPROPERTY( pen, pepProperty->ep_slOffset, INDEX);
|
|
|
|
CAnimData *pAD = pen->GetAnimData( pepProperty->ep_slOffset);
|
|
|
|
if( pAD != NULL)
|
|
|
|
{
|
|
|
|
CAnimInfo aiInfo;
|
|
|
|
pAD->GetAnimInfo(iAnim, aiInfo);
|
|
|
|
strResult=aiInfo.ai_AnimName;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_ENTITYPTR:
|
|
|
|
case CEntityProperty::EPT_PARENT:
|
|
|
|
{
|
|
|
|
CEntity *penPtr = ENTITYPROPERTY( pen, pepProperty->ep_slOffset, CEntityPointer);
|
|
|
|
if( penPtr!=NULL)
|
|
|
|
{
|
|
|
|
strResult="->"+penPtr->GetName();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strResult="No target";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_FLOAT:
|
|
|
|
case CEntityProperty::EPT_RANGE:
|
|
|
|
case CEntityProperty::EPT_ANGLE:
|
|
|
|
{
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
strResult.PrintF("%g", ENTITYPROPERTY( pen, pepProperty->ep_slOffset, FLOAT));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_ILLUMINATIONTYPE:
|
|
|
|
{
|
|
|
|
INDEX iIllumination = ENTITYPROPERTY( pen, pepProperty->ep_slOffset, INDEX);
|
|
|
|
strResult=pen->en_pwoWorld->wo_aitIlluminationTypes[iIllumination].it_strName;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_STRING:
|
|
|
|
case CEntityProperty::EPT_STRINGTRANS:
|
|
|
|
{
|
|
|
|
strResult=ENTITYPROPERTY( pen, pepProperty->ep_slOffset, CTString);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_FLOATAABBOX3D:
|
|
|
|
{
|
|
|
|
FLOATaabbox3D box=ENTITYPROPERTY( pen, pepProperty->ep_slOffset, FLOATaabbox3D);
|
|
|
|
strResult.PrintF("(%g,%g,%g)-(%g,%g,%g)",
|
|
|
|
box.Min()(1),box.Min()(2),box.Min()(3),
|
|
|
|
box.Max()(1),box.Max()(2),box.Max()(3));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_ANGLE3D:
|
|
|
|
{
|
|
|
|
ANGLE3D ang=ENTITYPROPERTY( pen, pepProperty->ep_slOffset, ANGLE3D);
|
|
|
|
strResult.PrintF("%g,%g,%g",ang(1),ang(2),ang(3));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_INDEX:
|
|
|
|
{
|
|
|
|
iFormat=PDF_INDEX;
|
|
|
|
strResult.PrintF("%d", ENTITYPROPERTY( pen, pepProperty->ep_slOffset, INDEX));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_BOOL:
|
|
|
|
{
|
|
|
|
if(ENTITYPROPERTY( pen, pepProperty->ep_slOffset, BOOL))
|
|
|
|
{
|
|
|
|
strResult="Yes";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strResult="No";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_COLOR:
|
|
|
|
{
|
|
|
|
iFormat=PDF_COLOR;
|
|
|
|
COLOR col=ENTITYPROPERTY( pen, pepProperty->ep_slOffset, COLOR);
|
|
|
|
UBYTE ubR, ubG, ubB;
|
|
|
|
UBYTE ubH, ubS, ubV;
|
|
|
|
ColorToHSV( col, ubH, ubS, ubV);
|
|
|
|
ColorToRGB( col, ubR, ubG, ubB);
|
|
|
|
UBYTE ubA = (UBYTE) (col&255);
|
|
|
|
strResult.PrintF( "RGB=(%d,%d,%d) HSV=(%d,%d,%d) Alpha=%d", ubR, ubG, ubB, ubH, ubS, ubV, ubA);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_FILENAME:
|
|
|
|
{
|
|
|
|
strResult = ENTITYPROPERTY( pen, pepProperty->ep_slOffset, CTFileName);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CEntityProperty::EPT_FILENAMENODEP:
|
|
|
|
{
|
|
|
|
strResult = ENTITYPROPERTY( pen, pepProperty->ep_slOffset, CTFileNameNoDep);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return strResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
CTString GetItemValue(CEntity *pen, INDEX iColumn, INDEX &iFormat)
|
|
|
|
{
|
|
|
|
ASSERT(pen!=NULL);
|
|
|
|
if(pen==NULL) return CTString("");
|
|
|
|
CEntityClass *pecEntityClass = pen->GetClass();
|
|
|
|
CDLLEntityClass *pdllecDllEntityClass = pecEntityClass->ec_pdecDLLClass;
|
|
|
|
FLOAT3D vOrigin = pen->GetPlacement().pl_PositionVector;
|
|
|
|
ANGLE3D vAngles = pen->GetPlacement().pl_OrientationAngle;
|
|
|
|
CTString strResult="";
|
|
|
|
iFormat=PDF_STRING;
|
|
|
|
|
|
|
|
switch( iColumn)
|
|
|
|
{
|
|
|
|
case COLUMN_INDEX:
|
|
|
|
{
|
|
|
|
INDEX iIndex=dcEntities.GetIndex(pen);
|
2016-03-12 00:26:30 +01:00
|
|
|
strResult.PrintF("%d", iIndex);
|
2016-03-11 14:57:17 +01:00
|
|
|
iFormat=PDF_INDEX;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_CLASS:
|
|
|
|
{
|
|
|
|
strResult=pdllecDllEntityClass->dec_strName;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_NAME:
|
|
|
|
{
|
|
|
|
strResult=pen->GetName();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_DESCRIPTION:
|
|
|
|
{
|
|
|
|
strResult=pen->GetDescription();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_SECTOR_NAME:
|
|
|
|
{
|
|
|
|
CBrushSector *pbsc = pen->GetFirstSectorWithName();
|
|
|
|
if( pbsc!=NULL)
|
|
|
|
{
|
|
|
|
strResult=pbsc->bsc_strName;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_X:
|
|
|
|
{
|
|
|
|
strResult.PrintF("%g", vOrigin(1));
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_Y:
|
|
|
|
{
|
|
|
|
strResult.PrintF("%g", vOrigin(2));
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_Z:
|
|
|
|
{
|
|
|
|
strResult.PrintF("%g", vOrigin(3));
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_H:
|
|
|
|
{
|
|
|
|
strResult.PrintF("%g", vAngles(1));
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_P:
|
|
|
|
{
|
|
|
|
strResult.PrintF("%g", vAngles(2));
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_B:
|
|
|
|
{
|
|
|
|
strResult.PrintF("%g", vAngles(3));
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_DISTANCE:
|
|
|
|
{
|
|
|
|
if( _penForDistanceSort != NULL)
|
|
|
|
{
|
|
|
|
FLOAT3D vSelectedOrigin = _penForDistanceSort->GetPlacement().pl_PositionVector;
|
|
|
|
FLOAT3D fDistance = vOrigin-vSelectedOrigin;
|
|
|
|
strResult.PrintF("%g", fDistance.Length());
|
|
|
|
iFormat=PDF_FLOAT;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case COLUMN_SPAWN_FLAGS:
|
|
|
|
{
|
|
|
|
strResult.PrintF("0x%08X", pen->GetSpawnFlags());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// entity properties
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
CDLLEntityClass *pdecDLLClass = pen->GetClass()->ec_pdecDLLClass;
|
|
|
|
// for all classes in hierarchy of this entity
|
|
|
|
INDEX iPropertyOrder=0;
|
|
|
|
for(;pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
|
|
|
|
{
|
|
|
|
// for all properties
|
|
|
|
for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
|
|
|
|
{
|
|
|
|
CEntityProperty *pepProperty = &pdecDLLClass->dec_aepProperties[iProperty];
|
|
|
|
if( pepProperty->ep_strName!=CTString(""))
|
|
|
|
{
|
|
|
|
if( iPropertyOrder==iColumn-COLUMN_PROPERTY_START)
|
|
|
|
{
|
|
|
|
strResult=GetPropertyValue(pen, pepProperty, iFormat);
|
|
|
|
return strResult;
|
|
|
|
}
|
|
|
|
iPropertyOrder++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return strResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CALLBACK SortEntities(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
|
|
|
|
{
|
|
|
|
int iResult = 0;
|
|
|
|
CEntity *pen1 = (CEntity *) lParam1;
|
|
|
|
CEntity *pen2 = (CEntity *) lParam2;
|
|
|
|
|
|
|
|
INDEX iFormat;
|
|
|
|
CTString strEn1=GetItemValue(pen1, lParamSort, iFormat);
|
|
|
|
CTString strEn2=GetItemValue(pen2, lParamSort, iFormat);
|
|
|
|
|
|
|
|
if( iFormat==PDF_STRING)
|
|
|
|
{
|
|
|
|
iResult = stricmp( strEn1, strEn2);
|
|
|
|
}
|
|
|
|
else if( iFormat==PDF_COLOR)
|
|
|
|
{
|
|
|
|
INDEX ubR, ubG, ubB;
|
|
|
|
INDEX ubH, ubS, ubV;
|
|
|
|
INDEX ubA;
|
|
|
|
strEn1.ScanF( "RGB=(%d,%d,%d) HSV=(%d,%d,%d) Alpha=%d", &ubR, &ubG, &ubB, &ubH, &ubS, &ubV, &ubA);
|
|
|
|
INDEX iVal1=ubV;
|
|
|
|
strEn2.ScanF( "RGB=(%d,%d,%d) HSV=(%d,%d,%d) Alpha=%d", &ubR, &ubG, &ubB, &ubH, &ubS, &ubV, &ubA);
|
|
|
|
INDEX iVal2=ubV;
|
|
|
|
iResult=iVal1>iVal2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( iFormat==PDF_FLOAT)
|
|
|
|
{
|
|
|
|
FLOAT fEn1=0;
|
|
|
|
FLOAT fEn2=0;
|
|
|
|
strEn1.ScanF("%g", &fEn1);
|
|
|
|
strEn2.ScanF("%g", &fEn2);
|
|
|
|
if( fEn1>fEn2) iResult=1; else iResult=-1;
|
|
|
|
}
|
|
|
|
else if( iFormat==PDF_INDEX)
|
|
|
|
{
|
|
|
|
INDEX iEn1=0;
|
|
|
|
INDEX iEn2=0;
|
|
|
|
strEn1.ScanF("%d", &iEn1);
|
|
|
|
strEn2.ScanF("%d", &iEn2);
|
|
|
|
if( iEn1>iEn2) iResult=1; else iResult=-1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( theApp.m_bInvertClassSort) return -iResult; else return iResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
CDlgBrowseByClass::CDlgBrowseByClass(CWnd* pParent /*=NULL*/)
|
|
|
|
: CDialog(CDlgBrowseByClass::IDD, pParent)
|
|
|
|
{
|
|
|
|
//{{AFX_DATA_INIT(CDlgBrowseByClass)
|
|
|
|
m_strEntitiesInVolume = _T("");
|
|
|
|
m_bShowVolume = FALSE;
|
|
|
|
m_bShowImportants = FALSE;
|
|
|
|
//}}AFX_DATA_INIT
|
|
|
|
|
|
|
|
m_bCenterSelected = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CDlgBrowseByClass::~CDlgBrowseByClass()
|
|
|
|
{
|
|
|
|
dcEntities.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::DoDataExchange(CDataExchange* pDX)
|
|
|
|
{
|
|
|
|
CDialog::DoDataExchange(pDX);
|
|
|
|
|
|
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
|
|
|
|
|
|
// if dialog is recieving data
|
|
|
|
if( (pDX->m_bSaveAndValidate == FALSE) && (::IsWindow(m_listEntities.m_hWnd)) )
|
|
|
|
{
|
|
|
|
INDEX ctEntities = m_listEntities.GetItemCount();
|
|
|
|
INDEX ctSelectedEntities = m_listEntities.GetSelectedCount();
|
|
|
|
char achrEntitiesCount[ 64];
|
|
|
|
sprintf( achrEntitiesCount, "Selected entities: %d Total entities: %d", ctSelectedEntities, ctEntities);
|
|
|
|
m_strEntitiesInVolume = achrEntitiesCount;
|
|
|
|
|
|
|
|
INDEX iSelectedItem = m_listEntities.GetNextItem( -1, LVNI_ALL|LVNI_SELECTED);
|
|
|
|
if( iSelectedItem != -1) m_listEntities.EnsureVisible( iSelectedItem, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
//{{AFX_DATA_MAP(CDlgBrowseByClass)
|
|
|
|
DDX_Control(pDX, IDC_PLUGGINS, m_ctrlPluggins);
|
|
|
|
DDX_Control(pDX, IDC_ENTITY_LIST, m_listEntities);
|
|
|
|
DDX_Text(pDX, IDC_ENTITIES_IN_VOLUME_T, m_strEntitiesInVolume);
|
|
|
|
DDX_Check(pDX, IDC_DISPLAY_VOLUME, m_bShowVolume);
|
|
|
|
DDX_Check(pDX, IDC_DISPLAY_IMPORTANTS, m_bShowImportants);
|
|
|
|
//}}AFX_DATA_MAP
|
|
|
|
|
|
|
|
// if dialog is giving data
|
|
|
|
if( pDX->m_bSaveAndValidate != FALSE)
|
|
|
|
{
|
|
|
|
// clear document selection
|
|
|
|
pDoc->m_selEntitySelection.Clear();
|
|
|
|
// mark all selected entities in list as selected in document's entity selection
|
|
|
|
INDEX iSelectedItem = -1;
|
|
|
|
FOREVER
|
|
|
|
{
|
|
|
|
iSelectedItem = m_listEntities.GetNextItem( iSelectedItem, LVNI_ALL|LVNI_SELECTED);
|
|
|
|
if( iSelectedItem == -1)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// get selected entity
|
|
|
|
CEntity *penEntity = (CEntity *) m_listEntities.GetItemData(iSelectedItem);
|
|
|
|
// add entity into normal selection
|
|
|
|
pDoc->m_selEntitySelection.Select( *penEntity);
|
|
|
|
}
|
|
|
|
if( pDoc->m_bBrowseEntitiesMode)
|
|
|
|
{
|
|
|
|
// clear volume container
|
|
|
|
pDoc->m_cenEntitiesSelectedByVolume.Clear();
|
|
|
|
// go out of browse by volume mode
|
|
|
|
pDoc->OnBrowseEntitiesMode();
|
|
|
|
}
|
|
|
|
// mark that selections have been changed
|
|
|
|
pDoc->m_chSelections.MarkChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgBrowseByClass, CDialog)
|
|
|
|
//{{AFX_MSG_MAP(CDlgBrowseByClass)
|
|
|
|
ON_NOTIFY(NM_DBLCLK, IDC_ENTITY_LIST, OnDblclkEntityList)
|
|
|
|
ON_NOTIFY(LVN_COLUMNCLICK, IDC_ENTITY_LIST, OnColumnclickEntityList)
|
|
|
|
ON_NOTIFY(NM_RCLICK, IDC_ENTITY_LIST, OnRclickEntityList)
|
|
|
|
ON_NOTIFY(NM_CLICK, IDC_ENTITY_LIST, OnClickEntityList)
|
|
|
|
ON_BN_CLICKED(ID_REMOVE, OnRemove)
|
|
|
|
ON_BN_CLICKED(ID_LEAVE, OnLeave)
|
|
|
|
ON_BN_CLICKED(ID_SELECT_ALL, OnSelectAll)
|
|
|
|
ON_BN_CLICKED(ID_FEED_VOLUME, OnFeedVolume)
|
|
|
|
ON_BN_CLICKED(ID_REVERT, OnRevert)
|
|
|
|
ON_BN_CLICKED(ID_SELECT_SECTORS, OnSelectSectors)
|
|
|
|
ON_BN_CLICKED(ID_DELETE_BROWSE_BY_CLASS, OnDeleteBrowseByClass)
|
|
|
|
ON_BN_CLICKED(IDC_DISPLAY_VOLUME, OnDisplayVolume)
|
|
|
|
ON_CBN_SELENDOK(IDC_PLUGGINS, OnSelendokPluggins)
|
|
|
|
ON_BN_CLICKED(IDC_DISPLAY_IMPORTANTS, OnDisplayImportants)
|
|
|
|
//}}AFX_MSG_MAP
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CDlgBrowseByClass message handlers
|
|
|
|
|
|
|
|
#define INDEX_PERCENTAGE 4
|
|
|
|
#define CLASS_PERCENTAGE 12
|
|
|
|
#define NAME_PERCENTAGE 16
|
|
|
|
#define DESCRIPTION_PERCENTAGE 16
|
|
|
|
#define SECTOR_NAME_PERCENTAGE 6
|
|
|
|
#define FLAGS_PERCENTAGE 8
|
|
|
|
#define DISTANCE_PERCENTAGE 6
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::AddEntity( CEntity *pen)
|
|
|
|
{
|
|
|
|
dcEntities.Add( pen);
|
|
|
|
// one item to serve for all entities
|
|
|
|
LV_ITEM itItem;
|
|
|
|
memset(&itItem, 0, sizeof(itItem));
|
|
|
|
// all items will be of text type
|
|
|
|
itItem.mask = LVIF_TEXT;
|
|
|
|
|
|
|
|
// add entity
|
|
|
|
wchar_t achrTemp[256];
|
|
|
|
INDEX iEntity = m_listEntities.GetItemCount();
|
|
|
|
itItem.iSubItem = COLUMN_CLASS;
|
|
|
|
itItem.pszText = achrTemp;
|
|
|
|
itItem.iItem = m_listEntities.InsertItem( &itItem);
|
|
|
|
m_listEntities.SetItemData( itItem.iItem, (DWORD) pen);
|
|
|
|
|
|
|
|
for( INDEX iColumn=COLUMN_CLASS; iColumn<COLUMN_PROPERTY_START+_ctProperties; iColumn++)
|
|
|
|
{
|
|
|
|
itItem.iSubItem = iColumn;
|
|
|
|
INDEX iFormat;
|
|
|
|
CTString strValue=::GetItemValue(pen, iColumn, iFormat);
|
|
|
|
swprintf( achrTemp, L"%s", CString(strValue));
|
|
|
|
itItem.pszText = achrTemp;
|
|
|
|
m_listEntities.SetItem( &itItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CDynamicContainer<class CEntity> *CDlgBrowseByClass::GetCurrentContainer(void)
|
|
|
|
{
|
|
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
|
|
// if should create and use temp container
|
|
|
|
if( _bTempContainer)
|
|
|
|
{
|
|
|
|
_tempContainer.Clear();
|
|
|
|
INDEX ctItems = m_listEntities.GetItemCount();
|
|
|
|
for( INDEX iItem=0; iItem<ctItems; iItem++)
|
|
|
|
{
|
|
|
|
CEntity *pen = (CEntity *) m_listEntities.GetItemData( iItem);
|
|
|
|
_tempContainer.Add(pen);
|
|
|
|
}
|
|
|
|
return &_tempContainer;
|
|
|
|
}
|
|
|
|
else if( m_bShowVolume)
|
|
|
|
{
|
|
|
|
return &pDoc->m_cenEntitiesSelectedByVolume;
|
|
|
|
}
|
|
|
|
else if( pDoc->m_selEntitySelection.Count() > 1)
|
|
|
|
{
|
|
|
|
return &pDoc->m_selEntitySelection;
|
|
|
|
}
|
|
|
|
return &pDoc->m_woWorld.wo_cenEntities;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::FillListWithEntities(void)
|
|
|
|
{
|
|
|
|
// initialize list columns
|
|
|
|
InitializeListColumns();
|
|
|
|
|
|
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
|
|
|
|
|
|
CDynamicContainer<class CEntity> *penContainer=GetCurrentContainer();
|
|
|
|
_bOfSameClass=AreAllEntitiesOfTheSameClass(penContainer);
|
|
|
|
|
|
|
|
// empty entities list
|
|
|
|
m_listEntities.DeleteAllItems();
|
|
|
|
dcEntities.Clear();
|
|
|
|
m_listEntities.SetRedraw(FALSE);
|
|
|
|
|
|
|
|
// add each entity in container
|
|
|
|
{FOREACHINDYNAMICCONTAINER(*penContainer, CEntity, iten)
|
|
|
|
{
|
|
|
|
// for all non-hidden entities that are not classified into hidden sectors, filter importants if requested
|
|
|
|
CBrushSector *pbscSector = iten->GetFirstSector();
|
|
|
|
if(!(iten->en_ulFlags&ENF_HIDDEN) &&
|
|
|
|
((pbscSector == NULL) || !(pbscSector->bsc_ulFlags & BSCF_HIDDEN)) &&
|
|
|
|
(!m_bShowImportants || iten->IsImportant()))
|
|
|
|
{
|
|
|
|
AddEntity( &iten.Current());
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
|
|
|
|
// sort items
|
|
|
|
m_listEntities.SortItems( SortEntities, theApp.m_iLastClassSortAplied);
|
|
|
|
|
|
|
|
// select one that was selected before calling dialog
|
|
|
|
if( pDoc->m_selEntitySelection.Count() == 1)
|
|
|
|
{
|
|
|
|
pDoc->m_selEntitySelection.Lock();
|
|
|
|
CEntity *penOnly = pDoc->m_selEntitySelection.Pointer(0);
|
|
|
|
pDoc->m_selEntitySelection.Unlock();
|
|
|
|
|
|
|
|
INDEX ctItems = m_listEntities.GetItemCount();
|
|
|
|
for( INDEX iItem=0; iItem<ctItems; iItem++)
|
|
|
|
{
|
|
|
|
CEntity *pen = (CEntity *) m_listEntities.GetItemData( iItem);
|
|
|
|
if( pen == penOnly)
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( iItem, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
|
|
|
m_listEntities.EnsureVisible( iItem, FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// select first in the list
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( 0, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
|
|
|
m_listEntities.EnsureVisible( 0, FALSE);
|
|
|
|
}
|
|
|
|
m_listEntities.SetRedraw(TRUE);
|
|
|
|
m_listEntities.Invalidate(TRUE);
|
|
|
|
m_listEntities.UpdateWindow();
|
|
|
|
|
|
|
|
_bTempContainer=FALSE;
|
|
|
|
UpdateData( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::InitializeListColumns(void)
|
|
|
|
{
|
|
|
|
while( m_listEntities.DeleteColumn(0)) {};
|
|
|
|
// initialize list headers
|
|
|
|
CRect rectListControl;
|
|
|
|
m_listEntities.GetClientRect( rectListControl);
|
|
|
|
PIX pixEntityClassName = rectListControl.Width()*CLASS_PERCENTAGE/100;
|
|
|
|
PIX pixInstanceName = rectListControl.Width()*NAME_PERCENTAGE/100;
|
|
|
|
PIX pixDescription = rectListControl.Width()*DESCRIPTION_PERCENTAGE/100;
|
|
|
|
PIX pixSectorName = rectListControl.Width()*SECTOR_NAME_PERCENTAGE/100;
|
|
|
|
PIX pixEntityIndex = rectListControl.Width()*INDEX_PERCENTAGE/100;
|
|
|
|
PIX pixSpawnFlags = rectListControl.Width()*FLAGS_PERCENTAGE/100;
|
|
|
|
PIX pixDistance = rectListControl.Width()*DISTANCE_PERCENTAGE/100;
|
|
|
|
m_listEntities.InsertColumn( COLUMN_CLASS, L"Class", LVCFMT_LEFT, pixEntityClassName);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_NAME, L"Name", LVCFMT_LEFT, pixInstanceName);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_DESCRIPTION, L"Description", LVCFMT_LEFT, pixDescription);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_SECTOR_NAME, L"Sector name", LVCFMT_LEFT, pixSectorName);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_INDEX, L"No", LVCFMT_LEFT, pixEntityIndex);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_SPAWN_FLAGS, L"Spawn Flags", LVCFMT_LEFT, pixSpawnFlags);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_DISTANCE, L"Distance", LVCFMT_LEFT, pixDistance);
|
|
|
|
PIX pixPlacement = (rectListControl.Width()-
|
|
|
|
(pixEntityIndex+pixEntityClassName+pixInstanceName+
|
|
|
|
pixDescription+pixSectorName+pixSpawnFlags+pixDistance))/6;
|
|
|
|
m_listEntities.InsertColumn( COLUMN_X, L"X", LVCFMT_LEFT, pixPlacement);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_Y, L"Y", LVCFMT_LEFT, pixPlacement);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_Z, L"Z", LVCFMT_LEFT, pixPlacement);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_H, L"H", LVCFMT_LEFT, pixPlacement);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_P, L"P", LVCFMT_LEFT, pixPlacement);
|
|
|
|
m_listEntities.InsertColumn( COLUMN_B, L"B", LVCFMT_LEFT, pixPlacement);
|
|
|
|
|
|
|
|
// add properties if of the same class and not empty selection
|
|
|
|
CDynamicContainer<class CEntity> *penContainer=GetCurrentContainer();
|
|
|
|
_bOfSameClass=AreAllEntitiesOfTheSameClass(penContainer);
|
|
|
|
if( _bOfSameClass && penContainer->Count()!=0)
|
|
|
|
{
|
|
|
|
_ctProperties=0;
|
|
|
|
CEntity *pen = &penContainer->GetFirst();
|
|
|
|
CDLLEntityClass *pdecDLLClass = pen->GetClass()->ec_pdecDLLClass;
|
|
|
|
// for all classes in hierarchy of this entity
|
|
|
|
for(;pdecDLLClass!=NULL; pdecDLLClass = pdecDLLClass->dec_pdecBase)
|
|
|
|
{
|
|
|
|
// for all properties
|
|
|
|
for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++)
|
|
|
|
{
|
|
|
|
CEntityProperty *pepProperty = &pdecDLLClass->dec_aepProperties[iProperty];
|
|
|
|
if( pepProperty->ep_strName!=CTString(""))
|
|
|
|
{
|
|
|
|
CSize szText=GetDC()->GetTextExtent(pepProperty->ep_strName);
|
|
|
|
PIX pixProperty=szText.cx+8;
|
|
|
|
m_listEntities.InsertColumn( COLUMN_PROPERTY_START+_ctProperties, CString(pepProperty->ep_strName), LVCFMT_LEFT, pixProperty);
|
|
|
|
_ctProperties++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CDlgBrowseByClass::OnInitDialog()
|
|
|
|
{
|
|
|
|
CDialog::OnInitDialog();
|
|
|
|
|
|
|
|
int iScreenX = ::GetSystemMetrics(SM_CXSCREEN); // screen size
|
|
|
|
int iScreenY = ::GetSystemMetrics(SM_CYSCREEN) - 32;
|
|
|
|
|
|
|
|
PIX pixSX = 8;
|
|
|
|
PIX pixSY = 16;
|
|
|
|
|
|
|
|
PIX pixButtonsY = iScreenY-64;
|
|
|
|
PIX pixButtonSpacing = 16;
|
|
|
|
PIX pixButtonOccupies = (iScreenX-pixSX*2)/9;
|
|
|
|
PIX pixButtonHeight = 24;
|
|
|
|
|
|
|
|
MoveWindow( 0, 0, iScreenX, iScreenY);
|
|
|
|
|
|
|
|
// obtain placement of selected entities text ctrl' window
|
|
|
|
WINDOWPLACEMENT wpl;
|
|
|
|
GetDlgItem( IDC_ENTITIES_IN_VOLUME_T)->GetWindowPlacement( &wpl);
|
|
|
|
CRect rect=wpl.rcNormalPosition;
|
|
|
|
|
|
|
|
PIX pixx=rect.left;
|
|
|
|
PIX pixw=(iScreenX-pixx-pixSX*2)/4;
|
|
|
|
GetDlgItem( IDC_ENTITIES_IN_VOLUME_T)->MoveWindow(pixx, rect.top, pixw, rect.bottom);
|
|
|
|
GetDlgItem( IDC_DISPLAY_VOLUME)->MoveWindow(pixx+pixw*1, rect.top, pixw, rect.bottom);
|
|
|
|
GetDlgItem( IDC_DISPLAY_IMPORTANTS)->MoveWindow(pixx+pixw*2, rect.top, pixw, rect.bottom);
|
|
|
|
GetDlgItem( IDC_PLUGGINS_T)->MoveWindow(pixx+pixw*3, rect.top, pixw/4, rect.bottom);
|
|
|
|
GetDlgItem( IDC_PLUGGINS)->MoveWindow(pixx+pixw*3+pixw/4, rect.top-4, pixw*3/4, rect.bottom-4);
|
|
|
|
|
|
|
|
pixSY+=24;
|
|
|
|
|
|
|
|
m_listEntities.MoveWindow(pixSX, pixSY, iScreenX-pixSX*2, (pixButtonsY-16)-pixSY);
|
|
|
|
|
|
|
|
#define MOVE_BUTTON( id, button_collumn)\
|
|
|
|
GetDlgItem( id)->MoveWindow( \
|
|
|
|
iScreenX-pixButtonOccupies*button_collumn, pixButtonsY,\
|
|
|
|
pixButtonOccupies-pixButtonSpacing, pixButtonHeight);
|
|
|
|
|
|
|
|
MOVE_BUTTON( ID_DELETE_BROWSE_BY_CLASS, 9);
|
|
|
|
MOVE_BUTTON( ID_REMOVE, 8);
|
|
|
|
MOVE_BUTTON( ID_LEAVE, 7);
|
|
|
|
MOVE_BUTTON( ID_SELECT_ALL, 6);
|
|
|
|
MOVE_BUTTON( ID_FEED_VOLUME, 5);
|
|
|
|
MOVE_BUTTON( ID_REVERT, 4);
|
|
|
|
MOVE_BUTTON( ID_SELECT_SECTORS, 3);
|
|
|
|
MOVE_BUTTON( IDOK, 2);
|
|
|
|
MOVE_BUTTON( IDCANCEL, 1);
|
|
|
|
|
|
|
|
FillListWithEntities();
|
|
|
|
InitializePluggins();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnDblclkEntityList(NMHDR* pNMHDR, LRESULT* pResult)
|
|
|
|
{
|
|
|
|
CRect rcItem;
|
|
|
|
POINT ptMouse;
|
|
|
|
GetCursorPos( &ptMouse);
|
|
|
|
m_listEntities.ScreenToClient( &ptMouse);
|
|
|
|
|
|
|
|
LVHITTESTINFO htInfo;
|
|
|
|
htInfo.pt = ptMouse;
|
|
|
|
m_listEntities.SubItemHitTest( &htInfo);
|
|
|
|
if( htInfo.iItem != -1)
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( htInfo.iItem, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_bCenterSelected = FALSE;
|
|
|
|
*pResult = 0;
|
|
|
|
CDialog::OnOK();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnOK()
|
|
|
|
{
|
|
|
|
m_bCenterSelected = FALSE;
|
|
|
|
CDialog::OnOK();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnColumnclickEntityList(NMHDR* pNMHDR, LRESULT* pResult)
|
|
|
|
{
|
|
|
|
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
|
|
|
if( theApp.m_iLastClassSortAplied == pNMListView->iSubItem) theApp.m_bInvertClassSort = !theApp.m_bInvertClassSort;
|
|
|
|
else theApp.m_bInvertClassSort = FALSE;
|
|
|
|
|
|
|
|
// if sorting by distance
|
|
|
|
if( pNMListView->iSubItem == COLUMN_DISTANCE)
|
|
|
|
{
|
|
|
|
INDEX iSelectedItem = m_listEntities.GetNextItem( -1, LVNI_ALL|LVNI_SELECTED);
|
|
|
|
if( iSelectedItem != -1)
|
|
|
|
{
|
|
|
|
_penForDistanceSort = (CEntity *) m_listEntities.GetItemData( iSelectedItem);
|
|
|
|
FLOAT3D vSelectedOrigin = _penForDistanceSort->GetPlacement().pl_PositionVector;
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
CEntity *penEntity = (CEntity *) m_listEntities.GetItemData(iItem);
|
|
|
|
FLOAT3D vCurrentOrigin = penEntity->GetPlacement().pl_PositionVector;
|
|
|
|
FLOAT3D fDistance = vSelectedOrigin-vCurrentOrigin;
|
|
|
|
|
|
|
|
char achrNumber[16];
|
|
|
|
itoa( (int)fDistance.Length(), achrNumber, 10);
|
|
|
|
m_listEntities.SetItemText( iItem, COLUMN_DISTANCE, CString(achrNumber));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_penForDistanceSort = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_listEntities.SortItems( SortEntities, pNMListView->iSubItem);
|
|
|
|
theApp.m_iLastClassSortAplied = pNMListView->iSubItem;
|
|
|
|
|
|
|
|
*pResult = 0;
|
|
|
|
UpdateData( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnRclickEntityList(NMHDR* pNMHDR, LRESULT* pResult)
|
|
|
|
{
|
|
|
|
BOOL bShift = (GetKeyState( VK_SHIFT)&0x8000) != 0;
|
|
|
|
|
|
|
|
*pResult = 0;
|
|
|
|
|
|
|
|
CRect rcItem;
|
|
|
|
POINT ptMouse;
|
|
|
|
GetCursorPos( &ptMouse);
|
|
|
|
m_listEntities.ScreenToClient( &ptMouse);
|
|
|
|
|
|
|
|
LVHITTESTINFO htInfo;
|
|
|
|
htInfo.pt = ptMouse;
|
|
|
|
m_listEntities.SubItemHitTest( &htInfo);
|
|
|
|
if( htInfo.iItem != -1)
|
|
|
|
{
|
|
|
|
CString strText = m_listEntities.GetItemText( htInfo.iItem, htInfo.iSubItem);
|
|
|
|
|
|
|
|
m_listEntities.SetRedraw(FALSE);
|
|
|
|
INDEX ctItems = m_listEntities.GetItemCount();
|
|
|
|
for( INDEX iItem = 0; iItem<ctItems; iItem++)
|
|
|
|
{
|
|
|
|
if( ((m_listEntities.GetItemText( iItem, htInfo.iSubItem) != strText) && !bShift) ||
|
|
|
|
((m_listEntities.GetItemText( iItem, htInfo.iSubItem) == strText) && bShift) )
|
|
|
|
{
|
|
|
|
m_listEntities.DeleteItem( iItem);
|
|
|
|
iItem--;
|
|
|
|
ctItems--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_listEntities.SetRedraw(TRUE);
|
|
|
|
}
|
|
|
|
_bTempContainer=TRUE;
|
|
|
|
FillListWithEntities();
|
|
|
|
|
|
|
|
m_listEntities.Invalidate(TRUE);
|
|
|
|
m_listEntities.UpdateWindow();
|
|
|
|
UpdateData( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnClickEntityList(NMHDR* pNMHDR, LRESULT* pResult)
|
|
|
|
{
|
|
|
|
CRect rcItem;
|
|
|
|
POINT ptMouse;
|
|
|
|
GetCursorPos( &ptMouse);
|
|
|
|
m_listEntities.ScreenToClient( &ptMouse);
|
|
|
|
|
|
|
|
LVHITTESTINFO htInfo;
|
|
|
|
htInfo.pt = ptMouse;
|
|
|
|
m_listEntities.SubItemHitTest( &htInfo);
|
|
|
|
if( htInfo.iItem != -1)
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( htInfo.iItem, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
}
|
|
|
|
UpdateData( FALSE);
|
|
|
|
*pResult = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnRemove()
|
|
|
|
{
|
|
|
|
m_listEntities.SetRedraw(FALSE);
|
|
|
|
INDEX iSelectedItem = -1;
|
|
|
|
FOREVER
|
|
|
|
{
|
|
|
|
iSelectedItem = m_listEntities.GetNextItem( -1, LVNI_ALL|LVNI_SELECTED);
|
|
|
|
if( iSelectedItem == -1)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
m_listEntities.DeleteItem( iSelectedItem);
|
|
|
|
}
|
|
|
|
_bTempContainer=TRUE;
|
|
|
|
FillListWithEntities();
|
|
|
|
|
|
|
|
m_listEntities.SetRedraw(TRUE);
|
|
|
|
m_listEntities.Invalidate(TRUE);
|
|
|
|
m_listEntities.UpdateWindow();
|
|
|
|
UpdateData( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnLeave()
|
|
|
|
{
|
|
|
|
m_listEntities.SetRedraw(FALSE);
|
|
|
|
INDEX ctItems = m_listEntities.GetItemCount();
|
|
|
|
INDEX iItem = 0;
|
|
|
|
for( ; iItem<ctItems; iItem++)
|
|
|
|
{
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) != LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
m_listEntities.DeleteItem( iItem);
|
|
|
|
iItem--;
|
|
|
|
ctItems--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for( iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( iItem, 0, LVIS_SELECTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
_bTempContainer=TRUE;
|
|
|
|
FillListWithEntities();
|
|
|
|
|
|
|
|
m_listEntities.SetRedraw(TRUE);
|
|
|
|
m_listEntities.Invalidate(TRUE);
|
|
|
|
m_listEntities.UpdateWindow();
|
|
|
|
m_listEntities.SetFocus();
|
|
|
|
UpdateData( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnSelectAll()
|
|
|
|
{
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( iItem, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
}
|
|
|
|
m_listEntities.SetFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnFeedVolume()
|
|
|
|
{
|
|
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
|
|
|
|
|
|
if( pDoc->m_bBrowseEntitiesMode)
|
|
|
|
{
|
|
|
|
// go out of browse by volume mode
|
|
|
|
pDoc->OnBrowseEntitiesMode();
|
|
|
|
pDoc->m_bBrowseEntitiesMode = FALSE;
|
|
|
|
}
|
|
|
|
pDoc->m_cenEntitiesSelectedByVolume.Clear();
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) == LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
// get selected entity
|
|
|
|
CEntity *penEntity = (CEntity *) m_listEntities.GetItemData(iItem);
|
|
|
|
// add entity into volume container
|
|
|
|
pDoc->m_cenEntitiesSelectedByVolume.Add( penEntity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnRevert()
|
|
|
|
{
|
|
|
|
FillListWithEntities();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnSelectSectors()
|
|
|
|
{
|
|
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) == LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
// get selected entity
|
|
|
|
CEntity *penEntity = (CEntity *) m_listEntities.GetItemData(iItem);
|
|
|
|
CBrushSector *pbscSector = penEntity->GetFirstSectorWithName();
|
|
|
|
if( pbscSector != NULL)
|
|
|
|
{
|
|
|
|
if( !pbscSector->IsSelected( BSCF_SELECTED))
|
|
|
|
{
|
|
|
|
pDoc->m_selSectorSelection.Select( *pbscSector);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pDoc->SetEditingMode( SECTOR_MODE);
|
|
|
|
EndDialog( 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CDlgBrowseByClass::PreTranslateMessage(MSG* pMsg)
|
|
|
|
{
|
|
|
|
BOOL bCtrl = (GetKeyState( VK_CONTROL)&0x8000) != 0;
|
|
|
|
if( ((pMsg->message==WM_KEYDOWN) || (pMsg->message==WM_SYSKEYDOWN)) &&
|
|
|
|
((int)pMsg->wParam=='A') && bCtrl)
|
|
|
|
{
|
|
|
|
OnSelectAll();
|
|
|
|
}
|
|
|
|
return CDialog::PreTranslateMessage(pMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnDeleteBrowseByClass()
|
|
|
|
{
|
|
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
|
|
|
|
|
|
pDoc->RememberUndo();
|
|
|
|
pDoc->ClearSelections();
|
|
|
|
|
|
|
|
CDynamicContainer<CEntity> dcEntitiesToDelete;
|
|
|
|
|
|
|
|
m_listEntities.SetRedraw(FALSE);
|
|
|
|
INDEX iSelectedItem = -1;
|
|
|
|
FOREVER
|
|
|
|
{
|
|
|
|
iSelectedItem = m_listEntities.GetNextItem( -1, LVNI_ALL|LVNI_SELECTED);
|
|
|
|
if( iSelectedItem == -1)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CEntity *penEntity = (CEntity *) m_listEntities.GetItemData(iSelectedItem);
|
|
|
|
dcEntitiesToDelete.Add( penEntity);
|
|
|
|
m_listEntities.DeleteItem( iSelectedItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
// check for deleting terrain
|
|
|
|
{FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
|
|
|
|
{
|
|
|
|
CEntity &en=*iten;
|
|
|
|
// if it is terrain
|
|
|
|
if(en.GetRenderType()==CEntity::RT_TERRAIN)
|
|
|
|
{
|
|
|
|
// if it is selected terrain
|
|
|
|
if(pDoc->m_ptrSelectedTerrain==en.GetTerrain())
|
|
|
|
{
|
|
|
|
pDoc->m_ptrSelectedTerrain=NULL;
|
|
|
|
theApp.m_ctTerrainPage.MarkChanged();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
|
|
|
|
{FOREACHINDYNAMICCONTAINER(dcEntitiesToDelete, CEntity, itenToDelete)
|
|
|
|
{
|
|
|
|
dcEntities.Remove( itenToDelete);
|
|
|
|
// select it
|
|
|
|
pDoc->m_selEntitySelection.Select( *itenToDelete);
|
|
|
|
}}
|
|
|
|
|
|
|
|
// delete all selected entities
|
|
|
|
pDoc->m_woWorld.DestroyEntities( pDoc->m_selEntitySelection);
|
|
|
|
pDoc->m_selEntitySelection.Clear();
|
|
|
|
pDoc->SetModifiedFlag( TRUE);
|
|
|
|
pDoc->m_chDocument.MarkChanged();
|
|
|
|
|
|
|
|
m_listEntities.SetRedraw(TRUE);
|
|
|
|
m_listEntities.Invalidate(TRUE);
|
|
|
|
m_listEntities.UpdateWindow();
|
|
|
|
|
|
|
|
// fill again list with non-deleted entities
|
|
|
|
FillListWithEntities();
|
|
|
|
|
|
|
|
UpdateData( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnDisplayVolume()
|
|
|
|
{
|
|
|
|
m_bShowVolume = !m_bShowVolume;
|
|
|
|
m_bShowImportants = FALSE;
|
|
|
|
UpdateData( FALSE);
|
|
|
|
FillListWithEntities();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::InitializePluggins(void)
|
|
|
|
{
|
|
|
|
m_ctrlPluggins.AddString(L"None");
|
|
|
|
m_ctrlPluggins.AddString(L"Random select");
|
|
|
|
m_ctrlPluggins.AddString(L"Random deselect");
|
|
|
|
m_ctrlPluggins.AddString(L"Random heading");
|
|
|
|
m_ctrlPluggins.AddString(L"Random pitch");
|
|
|
|
m_ctrlPluggins.AddString(L"Random banking");
|
|
|
|
m_ctrlPluggins.SetCurSel(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnSelendokPluggins()
|
|
|
|
{
|
|
|
|
CWorldEditorDoc *pDoc = theApp.GetDocument();
|
|
|
|
INDEX isel=m_ctrlPluggins.GetCurSel();
|
|
|
|
switch(isel)
|
|
|
|
{
|
|
|
|
// random select
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) != LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
if( rand()>RAND_MAX/2)
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( iItem, LVIS_SELECTED, LVIS_SELECTED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// random deselect
|
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) == LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
if( rand()>RAND_MAX/2)
|
|
|
|
{
|
|
|
|
m_listEntities.SetItemState( iItem, 0, LVIS_SELECTED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// random heading
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
pDoc->RememberUndo();
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
// if is selected
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) == LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
CEntity *pen = (CEntity *) m_listEntities.GetItemData( iItem);
|
|
|
|
// if it can be rotated
|
|
|
|
if( (pen->GetFlags() & ENF_ANCHORED) == 0)
|
|
|
|
{
|
|
|
|
CPlacement3D pl=pen->GetPlacement();
|
|
|
|
pl.pl_OrientationAngle(1)=((FLOAT)rand())/RAND_MAX*360.0f;
|
|
|
|
pen->SetPlacement(pl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// random pitch
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
pDoc->RememberUndo();
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
// if is selected
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) == LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
CEntity *pen = (CEntity *) m_listEntities.GetItemData( iItem);
|
|
|
|
// if it can be rotated
|
|
|
|
if( (pen->GetFlags() & ENF_ANCHORED) == 0)
|
|
|
|
{
|
|
|
|
CPlacement3D pl=pen->GetPlacement();
|
|
|
|
pl.pl_OrientationAngle(2)=((FLOAT)rand())/RAND_MAX*360.0f;
|
|
|
|
pen->SetPlacement(pl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// random banking
|
|
|
|
case 5:
|
|
|
|
{
|
|
|
|
pDoc->RememberUndo();
|
|
|
|
for( INDEX iItem = 0; iItem<m_listEntities.GetItemCount(); iItem++)
|
|
|
|
{
|
|
|
|
// if is selected
|
|
|
|
if( m_listEntities.GetItemState( iItem, LVIS_SELECTED) == LVIS_SELECTED)
|
|
|
|
{
|
|
|
|
CEntity *pen = (CEntity *) m_listEntities.GetItemData( iItem);
|
|
|
|
// if it can be rotated
|
|
|
|
if( (pen->GetFlags() & ENF_ANCHORED) == 0)
|
|
|
|
{
|
|
|
|
CPlacement3D pl=pen->GetPlacement();
|
|
|
|
pl.pl_OrientationAngle(3)=((FLOAT)rand())/RAND_MAX*360.0f;
|
|
|
|
pen->SetPlacement(pl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Invalidate(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDlgBrowseByClass::OnDisplayImportants()
|
|
|
|
{
|
|
|
|
m_bShowImportants = !m_bShowImportants;
|
|
|
|
m_bShowVolume = FALSE;
|
|
|
|
UpdateData( FALSE);
|
|
|
|
FillListWithEntities();
|
|
|
|
}
|