Serious-Engine/Sources/WorldEditor/PropertyComboBar.cpp

2035 lines
77 KiB
C++
Raw Normal View History

2016-03-12 01:20:51 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as published by
the Free Software Foundation
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
2016-03-11 14:57:17 +01:00
// PropertyComboBar.cpp : implementation file
//
#include "stdafx.h"
#include "PropertyComboBar.h"
#ifdef _DEBUG
#undef new
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPropertyComboBar dialog
BOOL CPropertyComboBar::Create( CWnd* pParentWnd, UINT nIDTemplate,
UINT nStyle, UINT nID, BOOL bChange)
{
if(!CDialogBar::Create(pParentWnd,nIDTemplate,nStyle,nID))
{
return FALSE;
}
m_Size = m_sizeDefault;
// subclass property combo box
m_PropertyComboBox.SubclassDlgItem( IDC_PROPERTYCOMBO, this);
// subclass enum combo box
m_EditEnumComboBox.SubclassDlgItem( IDC_EDIT_ENUM, this);
// subclass edit string control
m_EditStringCtrl.SubclassDlgItem( IDC_EDIT_STRING, this);
// subclass edit float control
m_EditFloatCtrl.SubclassDlgItem( IDC_EDIT_FLOAT, this);
// for andgle 3D
m_EditHeading.SubclassDlgItem( IDC_EDIT_HEADING, this);
m_EditPitch.SubclassDlgItem( IDC_EDIT_PITCH, this);
m_EditBanking.SubclassDlgItem( IDC_EDIT_BANKING, this);
// subclass edit BBox control
m_XCtrlAxisRadio.SubclassDlgItem( IDC_AXIS_X, this);
m_YCtrlAxisRadio.SubclassDlgItem( IDC_AXIS_Y, this);
m_ZCtrlAxisRadio.SubclassDlgItem( IDC_AXIS_Z, this);
m_EditBBoxMinCtrl.SubclassDlgItem( IDC_EDIT_BBOX_MIN, this);
m_EditBBoxMaxCtrl.SubclassDlgItem( IDC_EDIT_BBOX_MAX, this);
// subclass edit index control
m_EditIndexCtrl.SubclassDlgItem( IDC_EDIT_INDEX, this);
// subclass edit boolean control
m_EditBoolCtrl.SubclassDlgItem( IDC_EDIT_BOOL, this);
// subclass edit color control
m_EditColorCtrl.SetPickerType( CColoredButton::PT_MFC);
m_EditColorCtrl.SubclassDlgItem( IDC_EDIT_COLOR, this);
// subclass flag field property ctrl
m_ctrlEditFlags.SubclassDlgItem( ID_FLAGS_PROPERTY, this);
// subclass browse file control
m_BrowseFileCtrl.SubclassDlgItem( IDC_BROWSE_FILE, this);
// subclass difficulty spawn flags
m_EditEasySpawn.SubclassDlgItem( IDC_EASY, this);
m_EditNormalSpawn.SubclassDlgItem( IDC_NORMAL, this);
m_EditHardSpawn.SubclassDlgItem( IDC_HARD, this);
m_EditExtremeSpawn.SubclassDlgItem( IDC_EXTREME, this);
m_EditDifficulty_1.SubclassDlgItem( IDC_DIFFICULTY_1, this);
m_EditDifficulty_2.SubclassDlgItem( IDC_DIFFICULTY_2, this);
m_EditDifficulty_3.SubclassDlgItem( IDC_DIFFICULTY_3, this);
m_EditDifficulty_4.SubclassDlgItem( IDC_DIFFICULTY_4, this);
m_EditDifficulty_5.SubclassDlgItem( IDC_DIFFICULTY_5, this);
// subclass game mode spawn flags
m_EditSingleSpawn.SubclassDlgItem( IDC_SINGLE, this);
m_EditCooperativeSpawn.SubclassDlgItem( IDC_COOPERATIVE, this);
m_EditDeathMatchSpawn.SubclassDlgItem( IDC_DEATHMATCH, this);
m_EditGameMode_1.SubclassDlgItem( IDC_GAME_MODE_1, this);
m_EditGameMode_2.SubclassDlgItem( IDC_GAME_MODE_2, this);
m_EditGameMode_3.SubclassDlgItem( IDC_GAME_MODE_3, this);
m_EditGameMode_4.SubclassDlgItem( IDC_GAME_MODE_4, this);
m_EditGameMode_5.SubclassDlgItem( IDC_GAME_MODE_5, this);
m_EditGameMode_6.SubclassDlgItem( IDC_GAME_MODE_6, this);
// set dialog ptrs to controls
m_PropertyComboBox.SetDialogPtr( this);
m_EditEnumComboBox.SetDialogPtr( this);
m_EditStringCtrl.SetDialogPtr( this);
m_EditFloatCtrl.SetDialogPtr( this);
m_EditHeading.SetDialogPtr( this);
m_EditPitch.SetDialogPtr( this);
m_EditBanking.SetDialogPtr( this);
m_EditIndexCtrl.SetDialogPtr( this);
m_EditBBoxMinCtrl.SetDialogPtr( this);
m_EditBBoxMaxCtrl.SetDialogPtr( this);
m_XCtrlAxisRadio.SetDialogPtr( this);
m_YCtrlAxisRadio.SetDialogPtr( this);
m_ZCtrlAxisRadio.SetDialogPtr( this);
m_EditBoolCtrl.SetDialogPtr( this);
m_BrowseFileCtrl.SetDialogPtr( this);
m_EditEasySpawn.SetDialogPtr( this);
m_EditNormalSpawn.SetDialogPtr( this);
m_EditHardSpawn.SetDialogPtr( this);
m_EditExtremeSpawn.SetDialogPtr( this);
m_EditDifficulty_1.SetDialogPtr( this);
m_EditDifficulty_2.SetDialogPtr( this);
m_EditDifficulty_3.SetDialogPtr( this);
m_EditDifficulty_4.SetDialogPtr( this);
m_EditDifficulty_5.SetDialogPtr( this);
m_EditSingleSpawn.SetDialogPtr( this);
m_EditCooperativeSpawn.SetDialogPtr( this);
m_EditDeathMatchSpawn.SetDialogPtr( this);
m_EditGameMode_1.SetDialogPtr( this);
m_EditGameMode_2.SetDialogPtr( this);
m_EditGameMode_3.SetDialogPtr( this);
m_EditGameMode_4.SetDialogPtr( this);
m_EditGameMode_5.SetDialogPtr( this);
m_EditGameMode_6.SetDialogPtr( this);
m_ctrlEditFlags.SetDialogPtr( this);
// set font for properties combo
m_PropertyComboBox.SetFont(&theApp.m_Font);
// set font for enum combo
m_EditEnumComboBox.SetFont(&theApp.m_Font);
return TRUE;
}
BEGIN_MESSAGE_MAP(CPropertyComboBar, CDialogBar)
//{{AFX_MSG_MAP(CPropertyComboBar)
ON_WM_HSCROLL()
//}}AFX_MSG_MAP
ON_UPDATE_COMMAND_UI(IDC_BROWSE_FILE, OnUpdateBrowseFile)
ON_UPDATE_COMMAND_UI(IDC_NO_FILE, OnUpdateNoFile)
ON_UPDATE_COMMAND_UI(IDC_NO_TARGET, OnUpdateNoTarget)
ON_UPDATE_COMMAND_UI(IDC_EDIT_COLOR, OnUpdateEditColor)
ON_UPDATE_COMMAND_UI(ID_FLAGS_PROPERTY, OnUpdateEditFlags)
ON_COMMAND(IDC_NO_FILE, OnNoFile)
ON_COMMAND(IDC_NO_TARGET, OnNoTarget)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPropertyComboBar message handlers
//--------------------------------------------------------------------------------------------
void CPropertyComboBar::SelectAxisRadio(CWnd *pwndToSelect)
{
// deselect all three axis radios
m_XCtrlAxisRadio.SetCheck( 0);
m_YCtrlAxisRadio.SetCheck( 0);
m_ZCtrlAxisRadio.SetCheck( 0);
// select right one
if( pwndToSelect == &m_XCtrlAxisRadio) {m_XCtrlAxisRadio.SetCheck( 1); m_iXYZAxis=1;};
if( pwndToSelect == &m_YCtrlAxisRadio) {m_YCtrlAxisRadio.SetCheck( 1); m_iXYZAxis=2;};
if( pwndToSelect == &m_ZCtrlAxisRadio) {m_ZCtrlAxisRadio.SetCheck( 1); m_iXYZAxis=3;};
}
void CPropertyComboBar::DoDataExchange(CDataExchange* pDX)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL)
{
return;
}
// if dialog is recieving data
if( pDX->m_bSaveAndValidate == FALSE)
{
SetIntersectingEntityClassName();
SetIntersectingFileName();
// set spawn flags...
// obtain selected property ID ptr
CPropertyID *ppidProperty = GetSelectedProperty();
// if there is valid property selected
if( ppidProperty != NULL)
{
// reset selection entities spawn on and off masks
ULONG ulSpawnOn = MAX_ULONG;
ULONG ulSpawnOff = MAX_ULONG;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// intersect current mask with spawn mask of all selected entities
ulSpawnOn &= iten->GetSpawnFlags();
ulSpawnOff&= ~iten->GetSpawnFlags();
}
#define SET_SPAWN_FLAG( flag, ctrl) \
if((ulSpawnOn & (flag)) && !(ulSpawnOff & (flag))) ctrl.SetCheck( 1); \
else if(!(ulSpawnOn & (flag)) && (ulSpawnOff & (flag))) ctrl.SetCheck( 0); \
else ctrl.SetCheck( 2);
// set states of all spawn flags using calculated selected entities masks
SET_SPAWN_FLAG( SPF_EASY, m_EditEasySpawn);
SET_SPAWN_FLAG( SPF_NORMAL, m_EditNormalSpawn);
SET_SPAWN_FLAG( SPF_HARD, m_EditHardSpawn);
SET_SPAWN_FLAG( SPF_EXTREME, m_EditExtremeSpawn);
SET_SPAWN_FLAG( SPF_EXTREME<<1, m_EditDifficulty_1);
SET_SPAWN_FLAG( SPF_EXTREME<<2, m_EditDifficulty_2);
SET_SPAWN_FLAG( SPF_EXTREME<<3, m_EditDifficulty_3);
SET_SPAWN_FLAG( SPF_EXTREME<<4, m_EditDifficulty_4);
SET_SPAWN_FLAG( SPF_EXTREME<<5, m_EditDifficulty_5);
SET_SPAWN_FLAG( SPF_SINGLEPLAYER, m_EditSingleSpawn);
SET_SPAWN_FLAG( SPF_DEATHMATCH, m_EditDeathMatchSpawn);
SET_SPAWN_FLAG( SPF_COOPERATIVE, m_EditCooperativeSpawn);
SET_SPAWN_FLAG( SPF_COOPERATIVE<<1, m_EditGameMode_1);
SET_SPAWN_FLAG( SPF_COOPERATIVE<<2, m_EditGameMode_2);
SET_SPAWN_FLAG( SPF_COOPERATIVE<<3, m_EditGameMode_3);
SET_SPAWN_FLAG( SPF_COOPERATIVE<<4, m_EditGameMode_4);
SET_SPAWN_FLAG( SPF_COOPERATIVE<<5, m_EditGameMode_5);
SET_SPAWN_FLAG( SPF_COOPERATIVE<<6, m_EditGameMode_6);
}
}
DDX_Text(pDX, IDC_FLOAT_RANGE_T, m_strFloatRange);
DDX_Text(pDX, IDC_INDEX_RANGE_T, m_strIndexRange);
DDX_Text(pDX, IDC_CHOOSE_COLOR_T, m_strChooseColor);
DDX_Text(pDX, IDC_FILE_NAME_T, m_strFileName);
DDX_Text(pDX, IDC_ENTITY_CLASS, m_strEntityClass);
DDX_Text(pDX, IDC_ENTITY_NAME, m_strEntityName);
DDX_Text(pDX, IDC_ENTITY_DESCRIPTION, m_strEntityDescription);
if( m_EditBBoxMinCtrl.IsWindowVisible())
{
DDX_SkyFloat(pDX, IDC_EDIT_BBOX_MIN, m_fEditingBBoxMin);
DDX_SkyFloat(pDX, IDC_EDIT_BBOX_MAX, m_fEditingBBoxMax);
}
if( m_EditStringCtrl.IsWindowVisible())
{
DDX_Text(pDX, IDC_EDIT_STRING, m_strEditingString);
}
if( m_EditFloatCtrl.IsWindowVisible())
{
DDX_SkyFloat(pDX, IDC_EDIT_FLOAT, m_fEditingFloat);
}
if( m_EditHeading.IsWindowVisible())
{
DDX_SkyFloat(pDX, IDC_EDIT_HEADING, m_fEditingHeading);
}
if( m_EditPitch.IsWindowVisible())
{
DDX_SkyFloat(pDX, IDC_EDIT_PITCH, m_fEditingPitch);
}
if( m_EditBanking.IsWindowVisible())
{
DDX_SkyFloat(pDX, IDC_EDIT_BANKING, m_fEditingBanking);
}
if( m_EditIndexCtrl.IsWindowVisible())
{
DDX_Text(pDX, IDC_EDIT_INDEX, m_iEditingIndex);
}
// if dialog is giving data
if( pDX->m_bSaveAndValidate != FALSE)
{
// obtain selected property ID ptr
CPropertyID *ppidProperty = GetSelectedProperty();
// if there is valid property selected
if( ppidProperty != NULL)
{
// see type of changing property
switch( ppidProperty->pid_eptType)
{
// if we are changing flag field
case CEntityProperty::EPT_FLAGS:
{
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new flag value
m_ctrlEditFlags.ApplyChange( ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ULONG));
// apply new entity settings
iten->Initialize();
}
break;
}
// if we are changing enum property
case CEntityProperty::EPT_ENUM:
{
// get currently selected combo member
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
// it must exist
if( iSelectedComboMember == CB_ERR) return;
// get enum ID to be set for all entities
INDEX iSelectedEnumID = m_EditEnumComboBox.GetItemData(iSelectedComboMember);
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new enum value
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iSelectedEnumID;
// apply new entity settings
iten->Initialize();
}
break;
}
case CEntityProperty::EPT_ANIMATION:
{
// get currently selected combo member
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
// it must exist
if( iSelectedComboMember == CB_ERR) return;
// get animation to be set for all entities
INDEX iSelectedAnimation = m_EditEnumComboBox.GetItemData(iSelectedComboMember);
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new animation
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iSelectedAnimation;
// apply new entity settings
iten->Initialize();
}
break;
}
// if we are changing illumination type property
case CEntityProperty::EPT_ILLUMINATIONTYPE:
{
// get currently selected combo member
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
// it must exist
if( iSelectedComboMember == CB_ERR) return;
// get illumination type to be set for all entities
INDEX iIlluminationType = m_EditEnumComboBox.GetItemData(iSelectedComboMember);
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new illumination type value
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iIlluminationType;
// apply new entity settings
iten->Initialize();
}
break;
}
// if we are changing string property
case CEntityProperty::EPT_STRING:
case CEntityProperty::EPT_STRINGTRANS:
{
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new string
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTString) = CStringA(m_strEditingString);
// apply new entity settings
iten->Initialize();
}
// mark that document changed so that OnIdle on CSG destination combo would
// refresh combo entries (because we could be changing world name)
pDoc->m_chDocument.MarkChanged();
break;
}
// if we are changing float, range or angle property
case CEntityProperty::EPT_FLOAT:
case CEntityProperty::EPT_RANGE:
case CEntityProperty::EPT_ANGLE:
case CEntityProperty::EPT_ANGLE3D:
{
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// discard old entity settings
iten->End();
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if we are editing angle property
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE3D)
{
// set new angle 3d
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D) =
ANGLE3D(AngleDeg(m_fEditingHeading), AngleDeg(m_fEditingPitch),
AngleDeg(m_fEditingBanking));
}
else if(ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE)
{
// set new angle
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT) = AngleDeg(m_fEditingFloat);
}
else
{
// set new float or range
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT) = m_fEditingFloat;
}
// apply new entity settings
iten->Initialize();
}
break;
}
case CEntityProperty::EPT_FLOATAABBOX3D:
{
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// get old (pre-changed) value for bounding box
FLOATaabbox3D bboxOld = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset,
FLOATaabbox3D);
// get its min and max vectors
FLOAT3D vMin = bboxOld.Min();
FLOAT3D vMax = bboxOld.Max();
// set new min and max bbox values for currently selected axis
vMin( m_iXYZAxis) = m_fEditingBBoxMin;
vMax( m_iXYZAxis) = m_fEditingBBoxMax;
// create new bbox and set it into property
FLOATaabbox3D bboxNew( vMin, vMax);
// discard old entity settings
iten->End();
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOATaabbox3D) = bboxNew;
// apply new entity settings
iten->Initialize();
}
break;
}
case CEntityProperty::EPT_INDEX:
{
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
INDEX iNewValue = m_iEditingIndex;
// discard old entity settings
iten->End();
// set new index
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) = iNewValue;
// apply new entity settings
iten->Initialize();
}
break;
}
// if we are changing file name property
case CEntityProperty::EPT_FILENAME:
{
// file name changing function is done inside CBrowseFile.cpp
break;
}
case CEntityProperty::EPT_COLOR:
{
break;
}
// if we are changing bool property
case CEntityProperty::EPT_BOOL:
{
// get state of check box
INDEX iCheckBox = m_EditBoolCtrl.GetCheck();
// must be 0 or 1
if( iCheckBox != 2)
{
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new boolean value
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, BOOL) = iCheckBox;
// apply new entity settings
iten->Initialize();
}
}
break;
}
// if we are changing entity ptr property
case CEntityProperty::EPT_ENTITYPTR:
case CEntityProperty::EPT_PARENT:
{
// get currently selected combo member
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
// it must exist
if( iSelectedComboMember == CB_ERR) return;
// get entity ptr to be set for all entities
CEntity *penEntity = (CEntity *)m_EditEnumComboBox.GetItemData(iSelectedComboMember);
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
if( ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT)
{
iten->SetParent( penEntity);
}
else
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new entity ptr value
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer) = penEntity;
// apply new entity settings
iten->Initialize();
}
}
break;
}
// if we are changing entity ptr property
case CEntityProperty::EPT_SPAWNFLAGS:
{
// obtain spawn on and off masks
ULONG ulBitsToClear = MAX_ULONG;
ULONG ulBitsToSet = 0;
#define GET_SPAWN_MASKS( flag, ctrl) \
if( ctrl.GetCheck() == 0) ulBitsToClear &= ~(flag); \
if( ctrl.GetCheck() == 1) ulBitsToSet |= (flag);
// look at spawn checks and create masks of bits to set and to clear
GET_SPAWN_MASKS( SPF_EASY, m_EditEasySpawn);
GET_SPAWN_MASKS( SPF_NORMAL, m_EditNormalSpawn);
GET_SPAWN_MASKS( SPF_HARD, m_EditHardSpawn);
GET_SPAWN_MASKS( SPF_EXTREME, m_EditExtremeSpawn);
GET_SPAWN_MASKS( SPF_EXTREME<<1, m_EditDifficulty_1);
GET_SPAWN_MASKS( SPF_EXTREME<<2, m_EditDifficulty_2);
GET_SPAWN_MASKS( SPF_EXTREME<<3, m_EditDifficulty_3);
GET_SPAWN_MASKS( SPF_EXTREME<<4, m_EditDifficulty_4);
GET_SPAWN_MASKS( SPF_EXTREME<<5, m_EditDifficulty_5);
GET_SPAWN_MASKS( SPF_SINGLEPLAYER, m_EditSingleSpawn);
GET_SPAWN_MASKS( SPF_DEATHMATCH, m_EditDeathMatchSpawn);
GET_SPAWN_MASKS( SPF_COOPERATIVE, m_EditCooperativeSpawn);
GET_SPAWN_MASKS( SPF_COOPERATIVE<<1, m_EditGameMode_1);
GET_SPAWN_MASKS( SPF_COOPERATIVE<<2, m_EditGameMode_2);
GET_SPAWN_MASKS( SPF_COOPERATIVE<<3, m_EditGameMode_3);
GET_SPAWN_MASKS( SPF_COOPERATIVE<<4, m_EditGameMode_4);
GET_SPAWN_MASKS( SPF_COOPERATIVE<<5, m_EditGameMode_5);
GET_SPAWN_MASKS( SPF_COOPERATIVE<<6, m_EditGameMode_6);
// for each of the selected entities set spawn flags
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// clear and set curently selected spawn flags to all selected entities
iten->SetSpawnFlags(iten->GetSpawnFlags() & ulBitsToClear);
iten->SetSpawnFlags(iten->GetSpawnFlags() | ulBitsToSet);
}
break;
}
default:
{
ASSERTALWAYS("Unknown property type");
}
}
// mark that document is changed
pDoc->SetModifiedFlag( TRUE);
// redraw all views
pDoc->UpdateAllViews( NULL);
}
}
CDialogBar::DoDataExchange(pDX);
}
//--------------------------------------------------------------------------------------------
CSize CPropertyComboBar::CalcDynamicLayout(int nLength, DWORD nMode)
{
CSize csResult;
// Return default if it is being docked or floated
if ((nMode & LM_VERTDOCK) || (nMode & LM_HORZDOCK))
{
if (nMode & LM_STRETCH) // if not docked stretch to fit
{
csResult = CSize((nMode & LM_HORZ) ? 32767 : m_Size.cx,
(nMode & LM_HORZ) ? m_Size.cy : 32767);
}
else
{
csResult = m_Size;
}
}
else if (nMode & LM_MRUWIDTH)
{
csResult = m_Size;
}
// In all other cases, accept the dynamic length
else
{
if (nMode & LM_LENGTHY)
{
// Note that we don't change m_Size.cy because we disabled vertical sizing
csResult = CSize( m_Size.cx, m_Size.cy = nLength);
}
else
{
csResult = CSize( m_Size.cx = nLength, m_Size.cy);
}
}
#define CTRLS_LINE_H 22
#define CTRLS_RW 40
#define CTRLS_RH 44
#define CTRLS_YS 38+CTRLS_RH
#define CTRLS_YE (CTRLS_YS+CTRLS_LINE_H)
#define CTRLS_YRS 28+CTRLS_RH
#define CTRLS_YRE (CTRLS_YRS+CTRLS_RH)
#define CTRLS_YTS 44+CTRLS_RH
#define CTRLS_YTE (CTRLS_YTS+CTRLS_LINE_H)
#define CTRLS_YCMRS CTRLS_YS-4 // y color radio mode start
#define CTRLS_YCSS CTRLS_YCMRS+26 // y color sliders start
#define CTRLS_YNTS 64+CTRLS_RH // no target button
#define CTRLS_YNTE (CTRLS_YNTS+CTRLS_LINE_H)
#define CTRLS_BUTTONW 40
// set entity class text position
GetDlgItem( IDC_ENTITY_CLASS)->MoveWindow( CRect( 8, 4, csResult.cx - 8, 4+14));
// set entity name text position
GetDlgItem( IDC_ENTITY_NAME)->MoveWindow( CRect( 8, 18, csResult.cx - 8, 18+14));
// set entity description text position
GetDlgItem( IDC_ENTITY_DESCRIPTION)->MoveWindow( CRect( 8, 32, csResult.cx - 8, 32+14));
// set property combo size and position
m_PropertyComboBox.MoveWindow( CRect( 8, 5+CTRLS_RH, csResult.cx - 8, 120+CTRLS_RH));
// set enum combo size and position
m_EditEnumComboBox.MoveWindow( CRect( 8, CTRLS_YS, csResult.cx - 8, 120+CTRLS_RH));
// set edit string control size and position
m_EditStringCtrl.MoveWindow( CRect( 8, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
// set edit float control size and position
m_EditFloatCtrl.MoveWindow( CRect( csResult.cx/2, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
// set edit BBox controls size and position
GetDlgItem( IDC_AXIS_X)->MoveWindow( CRect( csResult.cx/2-CTRLS_RW*3/2, CTRLS_YRS,
csResult.cx/2-CTRLS_RW/2, CTRLS_YRE));
GetDlgItem( IDC_AXIS_Y)->MoveWindow( CRect( csResult.cx/2-CTRLS_RW/2, CTRLS_YRS,
csResult.cx/2+CTRLS_RW/2, CTRLS_YRE) );
GetDlgItem( IDC_AXIS_Z)->MoveWindow( CRect( csResult.cx/2+CTRLS_RW/2, CTRLS_YRS,
csResult.cx/2+CTRLS_RW*3/2, CTRLS_YRE) );
m_EditBBoxMinCtrl.MoveWindow( CRect( 8, CTRLS_YRE,
csResult.cx/2-8, CTRLS_YRE+CTRLS_LINE_H) );
m_EditBBoxMaxCtrl.MoveWindow( CRect( csResult.cx/2+8, CTRLS_YRE,
csResult.cx-8, CTRLS_YRE+CTRLS_LINE_H) );
// select x axis by default for editing bbox
SelectAxisRadio( &m_XCtrlAxisRadio);
// set edit index control size and position
m_EditIndexCtrl.MoveWindow( CRect( csResult.cx/2, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
// set float range description message size and position
GetDlgItem( IDC_FLOAT_RANGE_T)->MoveWindow( CRect( 8, CTRLS_YTS, csResult.cx/2, CTRLS_YTE));
// set index range description message size and position
GetDlgItem( IDC_INDEX_RANGE_T)->MoveWindow( CRect( 8, CTRLS_YTS, csResult.cx/2, csResult.cy));
// set edit boolean control size and position
m_EditBoolCtrl.MoveWindow( CRect( 8, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
// set float range description message size and position
GetDlgItem( IDC_ANGLE3D_T)->MoveWindow( CRect( 8, CTRLS_YTS+4, csResult.cx/4-4, CTRLS_YTE+4));
GetDlgItem( IDC_EDIT_HEADING)->MoveWindow( CRect( csResult.cx/4-4, CTRLS_YTS, csResult.cx/4*2-4, CTRLS_YTE));
GetDlgItem( IDC_EDIT_PITCH)->MoveWindow( CRect( csResult.cx/4*2-4, CTRLS_YTS, csResult.cx/4*3-4, CTRLS_YTE));
GetDlgItem( IDC_EDIT_BANKING)->MoveWindow( CRect( csResult.cx/4*3-4, CTRLS_YTS, csResult.cx-4, CTRLS_YTE));
// set size and position of color picker
m_EditColorCtrl.MoveWindow( CRect( 8, CTRLS_YCMRS, 128, CTRLS_YCMRS+(CTRLS_LINE_H*1.25)));
// set size and position of flags array
m_ctrlEditFlags.MoveWindow( CRect( 8, CTRLS_YCMRS+12, csResult.cx-4, CTRLS_YCMRS+(CTRLS_LINE_H*1.0)+12));
// set color description message size and position
GetDlgItem( IDC_CHOOSE_COLOR_T)->MoveWindow( CRect( 4, CTRLS_YCSS-4, 16, csResult.cy-4));
// set browse file button size and position
m_BrowseFileCtrl.MoveWindow( CRect( csResult.cx-CTRLS_BUTTONW-16, CTRLS_YS, csResult.cx - 24, CTRLS_YE));
GetDlgItem( IDC_NO_FILE)->MoveWindow( CRect( csResult.cx-24, CTRLS_YS, csResult.cx - 8, CTRLS_YE));
GetDlgItem( IDC_NO_TARGET)->MoveWindow( CRect( 8, CTRLS_YNTS, csResult.cx - 8, CTRLS_YNTE));
// set browse file description message size and position
GetDlgItem( IDC_FILE_NAME_T)->MoveWindow( CRect( 8, CTRLS_YTS, csResult.cx - CTRLS_BUTTONW-16, CTRLS_YTE));
return csResult;
}
CPropertyID *CPropertyComboBar::GetSelectedProperty()
{
INDEX iSelectedProperty = m_PropertyComboBox.GetCurSel();
if( (iSelectedProperty == CB_ERR) || ( iSelectedProperty < 0) )
{
//ASSERTALWAYS( "GetSelectedProperty() must not be called if there are no joined properties");
return NULL;
}
CPropertyID *ppidProperty = (CPropertyID *)
m_PropertyComboBox.GetItemData( iSelectedProperty);
ASSERT( ppidProperty != (CPropertyID *) -1);
return ppidProperty;
}
void CPropertyComboBar::SetFirstValidEmptyTargetProperty(CEntity *penTarget)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
for( INDEX iItem=0; iItem<m_PropertyComboBox.GetCount(); iItem++)
{
CPropertyID *ppidProperty = (CPropertyID *) m_PropertyComboBox.GetItemData( iItem);
ASSERT( ppidProperty != (CPropertyID *) -1);
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR)
{
// for each of the selected entities
{FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// check that all entities with this property target NULL and that supposed target is valid
CEntity *penOldTarget = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer);
BOOL bValidTarget = iten->IsTargetValid( penpProperty->ep_slOffset, penTarget);
// if this ptr is already set
if( penOldTarget==penTarget)
{
// don't do anything
return;
}
// stop checking if ptr isn't NULL or if not valid target
if( penOldTarget!=NULL || !bValidTarget)
{
continue;
}
// for each of the selected entities
{FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// discard old entity settings
iten->End();
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// set clicked entity as one that selected entity points to
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer) = penTarget;
// apply new entity settings
iten->Initialize();
}}
m_PropertyComboBox.SetCurSel(iItem);
m_PropertyComboBox.SelectProperty();
pDoc->m_chSelections.MarkChanged();
return;
}}
}
}
}
void CPropertyComboBar::SelectPreviousEmptyTarget(void)
{
CircleTargetProperties( -1, TRUE);
}
void CPropertyComboBar::SelectPreviousProperty(void)
{
CircleTargetProperties( -1, FALSE);
}
void CPropertyComboBar::SelectNextEmptyTarget(void)
{
CircleTargetProperties( 1, TRUE);
}
void CPropertyComboBar::SelectNextProperty(void)
{
CircleTargetProperties( 1, FALSE);
}
void CPropertyComboBar::CircleTargetProperties(INDEX iDirection, BOOL bOnlyEmptyTargets)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL)
{
return;
}
INDEX ctProperties = m_PropertyComboBox.GetCount();
// if no properties
if( ctProperties == 0) return;
// if selected is invalid
INDEX iSelectedProperty = m_PropertyComboBox.GetCurSel();
if( (iSelectedProperty == CB_ERR) || ( iSelectedProperty < 0) ) return;
// set invalid result
INDEX iToSelect = -1;
// browse trough entities
for( INDEX iItem=1; iItem<ctProperties; iItem++)
{
// we will use next/previos item for selecting
INDEX iToTest = (iSelectedProperty+ctProperties+iDirection*iItem)%ctProperties;
// if there is valid property selected
CPropertyID *ppidProperty = (CPropertyID *) m_PropertyComboBox.GetItemData( iToTest);
if( ppidProperty == NULL)
{
ASSERTALWAYS("Null property found!");
return;
}
// if null-ptr target is requested
if( bOnlyEmptyTargets)
{
// if this is entity pointer property
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR)
{
// obtain property ptr
CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
CEntityProperty *penpProperty = ppidProperty->pid_penpProperty;
CEntity *penTarget = ENTITYPROPERTY( pen, penpProperty->ep_slOffset, CEntityPointer);
// if it is NULL
if( penTarget == NULL)
{
// set this property as one to select
iToSelect = iToTest;
continue;
}
}
}
else
{
// if null-ptr target isn't requested, each property is valid
iToSelect = iToTest;
continue;
}
}
// if we have valid result
if( iToSelect != -1)
{
// select it
m_PropertyComboBox.SetCurSel( iToSelect);
m_PropertyComboBox.SelectProperty();
}
}
void CPropertyComboBar::SetIntersectingFileName()
{
if( m_BrowseFileCtrl.IsWindowVisible())
{
// get entity selection's intesecting file name
CTFileName fnIntersectingFile = m_BrowseFileCtrl.GetIntersectingFile();
if( fnIntersectingFile != "")
{
m_strFileName = "...\\" + fnIntersectingFile.FileName() + fnIntersectingFile.FileExt();
}
else
{
m_strFileName = "";
}
}
}
void CPropertyComboBar::SetColorPropertyToEntities( COLOR colNewColor)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
// obtain curently selected property ID
CPropertyID *ppidProperty = GetSelectedProperty();
if( ppidProperty == NULL) return;
// change curently selected color property in the selected entities
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
// set new color value
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, COLOR) = colNewColor;
// apply new entity settings
iten->Initialize();
}
// mark that document is changed
pDoc->SetModifiedFlag( TRUE);
}
BOOL CPropertyComboBar::OnIdle(LONG lCount)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
m_PropertyComboBox.OnIdle( lCount);
// if we are curently changing color
if( m_EditColorCtrl.IsWindowVisible())
{
COLOR colCurrentColor = m_EditColorCtrl.GetColor();
if( colCurrentColor != m_colLastColor)
{
SetColorPropertyToEntities( colCurrentColor);
m_colLastColor = colCurrentColor;
// update all views
pDoc->UpdateAllViews( NULL);
}
}
return TRUE;
}
/*
* Arranges (using show/hide) controls depending upon editing property type
*/
void CPropertyComboBar::ArrangeControls()
{
// array to receive description message
char strMessage[ 128];
// spawn flags are grayed
BOOL bEnableSpawn = FALSE;
// mark all controls for hiding
int iEnum = SW_HIDE;
int iString = SW_HIDE;
int iFloat = SW_HIDE;
int iBBox = SW_HIDE;
int iIndex = SW_HIDE;
int iBool = SW_HIDE;
int iColor = SW_HIDE;
int iBrowse = SW_HIDE;
int iX = SW_HIDE;
int iNoTarget = SW_HIDE;
int iFloatRangeText = SW_HIDE;
int iAngle3D = SW_HIDE;
int iIndexRangeText = SW_HIDE;
int iChooseColorText = SW_HIDE;
int iFileNameText = SW_HIDE;
int iFlags = SW_HIDE;
// get active document
CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
// if view does not exist, return
if( pDoc != NULL)
{
m_strFloatRange = "";
m_strChooseColor = "";
m_strFileName = "";
// obtain selected property ID ptr
INDEX iSelectedProperty = m_PropertyComboBox.GetCurSel();
CPropertyID *ppidProperty = (CPropertyID *) m_PropertyComboBox.GetItemData( iSelectedProperty);
// if there is valid property selected
if( ppidProperty != NULL)
{
// show controls acording to property type
switch( ppidProperty->pid_eptType)
{
case CEntityProperty::EPT_FLAGS:
{
iFlags = SW_SHOW;
CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
CEntityProperty *penpProperty = pen->PropertyForName( ppidProperty->pid_strName);
m_ctrlEditFlags.SetFlags( ENTITYPROPERTY( pen, penpProperty->ep_slOffset, ULONG));
// obtain enum property description object
CEntityPropertyEnumType *epEnum = penpProperty->ep_pepetEnumType;
// create mask of editable bits
ULONG ulEditable=0;
// for all enumerated members
for( INDEX iEnum = 0; iEnum<epEnum->epet_ctValues; iEnum++)
{
if( epEnum->epet_aepevValues[ iEnum].epev_strName!="")
{
ulEditable|=(1UL)<<epEnum->epet_aepevValues[ iEnum].epev_iValue;
CTString strBitName=epEnum->epet_aepevValues[ iEnum].epev_strName;
m_ctrlEditFlags.SetBitDescription(iEnum, strBitName);
}
}
m_ctrlEditFlags.SetEditableMask(ulEditable);
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// it is, get string as one that others will compare with
m_ctrlEditFlags.MergeFlags( ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ULONG));
}
break;
}
case CEntityProperty::EPT_ENUM:
case CEntityProperty::EPT_ENTITYPTR:
case CEntityProperty::EPT_PARENT:
case CEntityProperty::EPT_ANIMATION:
case CEntityProperty::EPT_ILLUMINATIONTYPE:
{
// obtain property ptr
CEntityProperty *penpProperty = ppidProperty->pid_penpProperty;
// remove all combo entries
m_EditEnumComboBox.ResetContent();
// combo control is to be shown
iEnum = SW_SHOW;
// for enum type of property
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ENUM)
{
// obtain enum property description object
CEntityPropertyEnumType *epEnum = penpProperty->ep_pepetEnumType;
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
BOOL bAllEntitiesHaveSameEnum = TRUE;
INDEX iCurrentEnumID;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, set its value as one that others will compare with
iCurrentEnumID = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
}
else
{
// if value of entity enum variable is different from first one
if( iCurrentEnumID != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
{
// mark that all entities do not have same enum
bAllEntitiesHaveSameEnum = FALSE;
break;
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
// invalid choosed enum ID
INDEX iSelectedEnumID = -1;
// for all enumerated members
for( INDEX iEnum = 0; iEnum< epEnum->epet_ctValues; iEnum++)
{
// add enum member into combo box
// add descriptive string
INDEX iAddedAs = m_EditEnumComboBox.AddString(
CString(epEnum->epet_aepevValues[ iEnum].epev_strName));
// get looping enum id
INDEX iLoopingEnumID = epEnum->epet_aepevValues[ iEnum].epev_iValue;
// connect descriptive string with enum value itself
m_EditEnumComboBox.SetItemData( iAddedAs, iLoopingEnumID);
// if all entities have same enum and this is joint enumerated value
if( bAllEntitiesHaveSameEnum && (iCurrentEnumID == iLoopingEnumID) )
{
// remember its index to set as selected combo value
iSelectedEnumID = iCurrentEnumID;
}
}
// if entities have same enum there must be valid selected enum ID
if( bAllEntitiesHaveSameEnum)
{
ASSERT(iSelectedEnumID != -1);
}
// if all entities have same enum
if( bAllEntitiesHaveSameEnum)
{
// after inserting combo members, they can be sorted so adding order does not work
// any more, combo member indices are not same any more
// mark invalid combo entry as selected
INDEX iSelectedCombo = -1;
// for all combo members
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
{
// if this entry has same enum ID as selected one
if( m_EditEnumComboBox.GetItemData( iCombo) == (DWORD) iSelectedEnumID)
{
// set its index as one to be selected
iSelectedCombo = iCombo;
break;
}
}
// there must be selected entry
ASSERT( iSelectedCombo != -1);
// select combo member
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
}
}
// else if this is entity ptr property
else if( (ppidProperty->pid_eptType == CEntityProperty::EPT_ENTITYPTR) ||
(ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT) )
{
BOOL bParentProperty = ppidProperty->pid_eptType == CEntityProperty::EPT_PARENT;
// for all entities in the world
{FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten)
{
CTString strEntityName = iten->GetName();
CBrushSector *pbscSector = iten->GetFirstSector();
BOOL bSectorVisible = (pbscSector == NULL) ||
!(pbscSector->bsc_ulFlags & BSCF_HIDDEN);
BOOL bValidTarget = TRUE;
// for each entity in selection
{FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, itenSel)
{
CEntityProperty *penpProperty = ppidProperty->pid_penpProperty;
if(penpProperty != NULL)
{
// see if target is valid
if( !itenSel->IsTargetValid( penpProperty->ep_slOffset, iten))
{
bValidTarget = FALSE;
break;
}
}
}}
// if entity is targetable, not hidden, and is not selected
if( (iten->IsTargetable() || bParentProperty) &&
(bSectorVisible) &&
bValidTarget &&
//(!iten->IsSelected(ENF_SELECTED)) &&
!(iten->en_ulFlags&ENF_HIDDEN))
{
INDEX iAddedAs;
if( strEntityName != "")
{
// add it to combo
iAddedAs = m_EditEnumComboBox.AddString( CString(strEntityName));
}
else
{
// add it to combo
iAddedAs = m_EditEnumComboBox.AddString( L"Unnamed");
}
// set entity ptr as item's data
m_EditEnumComboBox.SetItemData( iAddedAs, (ULONG) &*iten);
}
}}
// set NULL entity name
INDEX iAddedAs = m_EditEnumComboBox.InsertString( 0, L"None");
// set NULL entity ptr as item's data
m_EditEnumComboBox.SetItemData( iAddedAs, NULL);
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
// to hold intersecting entity ptr
CEntity *penEntity;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, set its value as one that others will compare with
if( bParentProperty)
penEntity = iten->GetParent();
else
penEntity = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer);
}
else
{
// get current entity ptr
CEntity *penCurrent;
if( bParentProperty) penCurrent = iten->GetParent();
else penCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer);
// if value of entity ptr is different from first one
if( penEntity != penCurrent)
{
// mark that all entities do not have same entity ptr
penEntity = (CEntity *) -1;
break;
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
if( penEntity != (CEntity *)-1)
{
INDEX iSelectedCombo = 0;
// for all combo members
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
{
// if this entry has same entity ptr as selected one
if( penEntity == (CEntity *) m_EditEnumComboBox.GetItemData( iCombo) )
{
// set its index as one to be selected
iSelectedCombo = iCombo;
break;
}
}
// select combo member
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
}
// show x button
iNoTarget = SW_SHOW;
}
// else if we should initialize animation property
else if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANIMATION)
{
// get first selected entity
pDoc->m_selEntitySelection.Lock();
CEntity *penFirst = pDoc->m_selEntitySelection.Pointer(0);
pDoc->m_selEntitySelection.Unlock();
CAnimData *pAD = penFirst->GetAnimData( penpProperty->ep_slOffset);
if( pAD != NULL)
{
// add all animations into combo box
for( INDEX iAnimation=0;iAnimation<pAD->GetAnimsCt();iAnimation++)
{
// obtain information about animation
CAnimInfo aiInfo;
pAD->GetAnimInfo(iAnimation, aiInfo);
// add animation to combo
INDEX iAddedAs = m_EditEnumComboBox.AddString( CString(aiInfo.ai_AnimName));
// set animation number as item's data
m_EditEnumComboBox.SetItemData( iAddedAs, (ULONG) iAnimation);
}
}
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
INDEX iJointAnimation = -1;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, get light animation as one that others will compare with
iJointAnimation = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
}
else
{
if( iJointAnimation!=ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
{
iJointAnimation = -1;
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
if( iJointAnimation != -1)
{
INDEX iSelectedCombo = -1;
// for all combo members
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
{
// if this entry has same entity ptr as selected one
if( iJointAnimation == (INDEX) m_EditEnumComboBox.GetItemData( iCombo) )
{
// set its index as one to be selected
iSelectedCombo = iCombo;
break;
}
}
// if there is joint animation but is not found in combo
if( iSelectedCombo == -1)
{
iSelectedCombo = 0;
}
// select combo member
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
}
}
// else if we should initialize illumination type property
else if( ppidProperty->pid_eptType == CEntityProperty::EPT_ILLUMINATIONTYPE)
{
// add all illumination types into combo box
for( INDEX iIllumination=0;iIllumination<255; iIllumination++)
{
// get illumination name
CTString strIlluminationName =
pDoc->m_woWorld.wo_aitIlluminationTypes[iIllumination].it_strName;
// name must not be <none> except for first illumination
if(strIlluminationName == "")
{
break;
}
// add illumination type to combo
INDEX iAddedAs = m_EditEnumComboBox.AddString( CString(strIlluminationName));
// set illumination type number as item's data
m_EditEnumComboBox.SetItemData( iAddedAs, (ULONG) iIllumination);
}
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
INDEX iJointIllumination = -1;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, get illumination as one that others will compare with
iJointIllumination = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
}
else
{
if( iJointIllumination!=ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
{
iJointIllumination = -1;
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
if( iJointIllumination != -1)
{
INDEX iSelectedCombo = -1;
// for all combo members
for( INDEX iCombo = 0; iCombo<m_EditEnumComboBox.GetCount(); iCombo++)
{
// if this entry has same entity ptr as selected one
if( iJointIllumination == (INDEX) m_EditEnumComboBox.GetItemData( iCombo) )
{
// set its index as one to be selected
iSelectedCombo = iCombo;
break;
}
}
// if there is joint illumination but is not found in combo
if( iSelectedCombo == -1)
{
iSelectedCombo = 0;
}
// select combo member
m_EditEnumComboBox.SetCurSel( iSelectedCombo);
}
}
else
{
ASSERTALWAYS("Illegal entity \"combo\"-type property found !");
}
break;
}
case CEntityProperty::EPT_STRING:
case CEntityProperty::EPT_STRINGTRANS:
{
// edit string control is to be shown
iString = SW_SHOW;
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, get string as one that others will compare with
m_strEditingString = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTString);
}
else
{
CTString strString = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTString);
// if string is different from first one
if( CTString( CStringA(m_strEditingString)) != strString)
{
// all selected entities do not share same string
m_strEditingString = "";
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
break;
}
case CEntityProperty::EPT_FLOAT:
case CEntityProperty::EPT_RANGE:
case CEntityProperty::EPT_ANGLE:
{
iFloat = SW_SHOW;
iFloatRangeText = SW_SHOW;
pDoc->m_selEntitySelection.Lock();
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE)
{
m_fEditingFloat = DegAngle( ENTITYPROPERTY(
&*iten, penpProperty->ep_slOffset, ANGLE));
}
else
{
m_fEditingFloat = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT);
}
}
else
{
FLOAT fCurrentFloat;
if( ppidProperty->pid_eptType == CEntityProperty::EPT_ANGLE)
{
fCurrentFloat = DegAngle( ENTITYPROPERTY(
&*iten, penpProperty->ep_slOffset, ANGLE));
}
else
{
fCurrentFloat = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, FLOAT);
}
if( m_fEditingFloat != fCurrentFloat )
{
m_fEditingFloat = 0.0f;
break;
}
}
}
pDoc->m_selEntitySelection.Unlock();
sprintf( strMessage, "Float");
m_strFloatRange = strMessage;
if( ppidProperty->pid_eptType == CEntityProperty::EPT_RANGE)
{
pDoc->UpdateAllViews( NULL);
}
break;
}
case CEntityProperty::EPT_ANGLE3D:
{
iAngle3D = SW_SHOW;
pDoc->m_selEntitySelection.Lock();
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
ANGLE3D aAngle = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D);
m_fEditingHeading = DegAngle( aAngle(1));
m_fEditingPitch = DegAngle( aAngle(2));
m_fEditingBanking = DegAngle( aAngle(3));
}
else
{
ANGLE3D aCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, ANGLE3D);
if( m_fEditingHeading != DegAngle( aCurrent(1))) m_fEditingHeading = 0.0f;
if( m_fEditingPitch != DegAngle( aCurrent(2))) m_fEditingPitch = 0.0f;
if( m_fEditingBanking != DegAngle( aCurrent(3))) m_fEditingBanking = 0.0f;
}
}
pDoc->m_selEntitySelection.Unlock();
break;
}
case CEntityProperty::EPT_FLOATAABBOX3D:
{
iBBox = SW_SHOW;
// mark that all entities have same value for current bbox axis
BOOL bAllHaveSameBBoxValue = TRUE;
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// get first entity's bbox min and max values for selected axis
FLOATaabbox3D bboxCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset,
FLOATaabbox3D);
// get its min and max vectors
FLOAT3D vMin = bboxCurrent.Min();
FLOAT3D vMax = bboxCurrent.Max();
// remember min and max ranges for current axis for other entities in selection
// to compare with
m_fEditingBBoxMin = vMin( m_iXYZAxis);
m_fEditingBBoxMax = vMax( m_iXYZAxis);
}
else
{
// get first entity's bbox min and max values for selected axis
FLOATaabbox3D bboxCurrent = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset,
FLOATaabbox3D);
// get its min and max vectors
FLOAT3D vMin = bboxCurrent.Min();
FLOAT3D vMax = bboxCurrent.Max();
// compare min and max ranges for current axis with those from first entity
if( (m_fEditingBBoxMin != vMin( m_iXYZAxis)) ||
(m_fEditingBBoxMax != vMax( m_iXYZAxis)) )
{
// all selected entities do not share same number so mark it
bAllHaveSameBBoxValue = FALSE;
m_fEditingBBoxMin = 0.0f;
m_fEditingBBoxMax = 0.0f;
break;
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
// refresh views
pDoc->UpdateAllViews( NULL);
break;
}
case CEntityProperty::EPT_INDEX:
{
iIndex = SW_SHOW;
iIndexRangeText = SW_SHOW;
// mark that all entities have same index property value
BOOL bAllHaveSameIndex = TRUE;
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, get this number as one that others will compare with
m_iEditingIndex = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX);
}
else
{
// if number is different from first one
if( m_iEditingIndex != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, INDEX) )
{
// all selected entities do not share same number so mark it
bAllHaveSameIndex = FALSE;
m_iEditingIndex = 0;
break;
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
sprintf( strMessage, "Integer");
m_strIndexRange = strMessage;
break;
}
case CEntityProperty::EPT_BOOL:
{
m_EditBoolCtrl.SetWindowText( CString(ppidProperty->pid_strName));
iBool = SW_SHOW;
// variable to receive state of check box
INDEX iCheckBox;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, get boolean as one that others will compare with
iCheckBox = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, BOOL);
}
else
{
// if this boolean is different from first one
if( iCheckBox != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, BOOL) )
{
// selected entities do not share same boolean, set undefined state
iCheckBox = 2;
break;
}
}
}
// set calculated boolean state (or undefined)
m_EditBoolCtrl.SetCheck( iCheckBox);
break;
}
case CEntityProperty::EPT_COLOR:
{
// intersecting color
COLOR colIntersected;
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, get this color as one that others will compare with
colIntersected = ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, COLOR);
// set button's color
m_EditColorCtrl.SetColor( colIntersected);
// remember this color as the last
m_colLastColor = colIntersected;
}
else
{
// if color is different from first one
if( colIntersected != ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, COLOR) )
{
// all selected entities do not share same color
m_EditColorCtrl.SetMixedColor();
break;
}
}
}
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
iChooseColorText = SW_SHOW;
iColor = SW_SHOW;
break;
}
case CEntityProperty::EPT_FILENAME:
case CEntityProperty::EPT_FILENAMENODEP:
{
SetIntersectingFileName();
iFileNameText = SW_SHOW;
iBrowse = SW_SHOW;
iX = SW_SHOW;
m_BrowseFileCtrl.m_bFileNameNoDep =
(ppidProperty->pid_eptType == CEntityProperty::EPT_FILENAMENODEP);
break;
}
case CEntityProperty::EPT_SPAWNFLAGS:
{
bEnableSpawn = TRUE;
break;
}
default:
{
ASSERTALWAYS("Unknown property type");
}
}
}
// update all views
pDoc->UpdateAllViews( NULL);
}
m_EditEasySpawn.EnableWindow( bEnableSpawn);
m_EditNormalSpawn.EnableWindow( bEnableSpawn);
m_EditHardSpawn.EnableWindow( bEnableSpawn);
m_EditExtremeSpawn.EnableWindow( bEnableSpawn);
m_EditDifficulty_1.EnableWindow( bEnableSpawn);
m_EditDifficulty_2.EnableWindow( bEnableSpawn);
m_EditDifficulty_3.EnableWindow( bEnableSpawn);
m_EditDifficulty_4.EnableWindow( bEnableSpawn);
m_EditDifficulty_5.EnableWindow( bEnableSpawn);
m_EditSingleSpawn.EnableWindow( bEnableSpawn);
m_EditCooperativeSpawn.EnableWindow( bEnableSpawn);
m_EditDeathMatchSpawn.EnableWindow( bEnableSpawn);
m_EditGameMode_1.EnableWindow( bEnableSpawn);
m_EditGameMode_2.EnableWindow( bEnableSpawn);
m_EditGameMode_3.EnableWindow( bEnableSpawn);
m_EditGameMode_4.EnableWindow( bEnableSpawn);
m_EditGameMode_5.EnableWindow( bEnableSpawn);
m_EditGameMode_6.EnableWindow( bEnableSpawn);
GetDlgItem( IDC_EASY_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_NORMAL_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_HARD_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_EXTREME_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_1_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_2_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_3_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_4_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_5_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_SINGLE_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_COOPERATIVE_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_DEATHMATCH_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_1_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_2_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_3_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_4_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_5_T)->EnableWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_6_T)->EnableWindow( bEnableSpawn);
m_EditEasySpawn.ShowWindow( bEnableSpawn);
m_EditNormalSpawn.ShowWindow( bEnableSpawn);
m_EditHardSpawn.ShowWindow( bEnableSpawn);
m_EditExtremeSpawn.ShowWindow( bEnableSpawn);
m_EditDifficulty_1.ShowWindow( bEnableSpawn);
m_EditDifficulty_2.ShowWindow( bEnableSpawn);
m_EditDifficulty_3.ShowWindow( bEnableSpawn);
m_EditDifficulty_4.ShowWindow( bEnableSpawn);
m_EditDifficulty_5.ShowWindow( bEnableSpawn);
m_EditSingleSpawn.ShowWindow( bEnableSpawn);
m_EditCooperativeSpawn.ShowWindow( bEnableSpawn);
m_EditDeathMatchSpawn.ShowWindow( bEnableSpawn);
m_EditGameMode_1.ShowWindow( bEnableSpawn);
m_EditGameMode_2.ShowWindow( bEnableSpawn);
m_EditGameMode_3.ShowWindow( bEnableSpawn);
m_EditGameMode_4.ShowWindow( bEnableSpawn);
m_EditGameMode_5.ShowWindow( bEnableSpawn);
m_EditGameMode_6.ShowWindow( bEnableSpawn);
GetDlgItem( IDC_EASY_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_NORMAL_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_HARD_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_EXTREME_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_1_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_2_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_3_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_4_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_DIFFICULTY_5_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_SINGLE_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_DEATHMATCH_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_COOPERATIVE_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_1_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_2_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_3_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_4_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_5_T)->ShowWindow( bEnableSpawn);
GetDlgItem( IDC_GAME_MODE_6_T)->ShowWindow( bEnableSpawn);
// show controls that are necessary to edit current property
m_EditEnumComboBox.ShowWindow( iEnum);
m_EditStringCtrl.ShowWindow( iString);
m_EditFloatCtrl.ShowWindow( iFloat);
m_EditBBoxMinCtrl.ShowWindow( iBBox);
m_EditBBoxMaxCtrl.ShowWindow( iBBox);
GetDlgItem( IDC_AXIS_X)->ShowWindow( iBBox);
GetDlgItem( IDC_AXIS_Y)->ShowWindow( iBBox);
GetDlgItem( IDC_AXIS_Z)->ShowWindow( iBBox);
m_EditIndexCtrl.ShowWindow( iIndex);
m_EditBoolCtrl.ShowWindow( iBool);
m_BrowseFileCtrl.ShowWindow( iBrowse);
GetDlgItem( IDC_NO_FILE)->ShowWindow( iX);
GetDlgItem( IDC_NO_TARGET)->ShowWindow( iNoTarget);
m_EditColorCtrl.ShowWindow( iColor);
m_ctrlEditFlags.ShowWindow( iFlags);
GetDlgItem( IDC_FLOAT_RANGE_T)->ShowWindow( iFloatRangeText);
GetDlgItem( IDC_INDEX_RANGE_T)->ShowWindow( iIndexRangeText);
GetDlgItem( IDC_FILE_NAME_T)->ShowWindow( iFileNameText);
GetDlgItem( IDC_ANGLE3D_T)->ShowWindow( iAngle3D);
GetDlgItem( IDC_EDIT_HEADING)->ShowWindow( iAngle3D);
GetDlgItem( IDC_EDIT_PITCH)->ShowWindow( iAngle3D);
GetDlgItem( IDC_EDIT_BANKING)->ShowWindow( iAngle3D);
GetDlgItem( IDC_ENTITY_CLASS)->ShowWindow( SW_SHOW);
GetDlgItem( IDC_ENTITY_NAME)->ShowWindow( SW_SHOW);
GetDlgItem( IDC_ENTITY_DESCRIPTION)->ShowWindow( SW_SHOW);
GetDlgItem( IDC_ENTITY_CLASS)->EnableWindow( m_PropertyComboBox.IsWindowEnabled());
GetDlgItem( IDC_ENTITY_NAME)->EnableWindow( m_PropertyComboBox.IsWindowEnabled());
GetDlgItem( IDC_ENTITY_DESCRIPTION)->EnableWindow( m_PropertyComboBox.IsWindowEnabled());
// update dialog data (so new data could be loaded into dialog)
UpdateData( FALSE);
}
void CPropertyComboBar::OnUpdateBrowseFile(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE);
}
void CPropertyComboBar::OnUpdateEditColor(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE);
}
void CPropertyComboBar::OnUpdateEditFlags(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE);
}
void CPropertyComboBar::SetIntersectingEntityClassName(void)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
// lock selection's dynamic container
pDoc->m_selEntitySelection.Lock();
// string to contain intersecting class name
CTString strIntersectingClass = "No entity class";
CTString strIntersectingName = "No name";
CTString strIntersectingDescription = "No description";
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// get class of this entity
CEntityClass *pencEntityClass = iten->GetClass();
// get file name of clas file
CTFileName fnClassFileName = pencEntityClass->GetName().FileName();
// get name
CTString strEntityName = iten->GetName();
// get description
CTString strEntityDescription = iten->GetDescription();
// if this is first entity in dynamic container
if( pDoc->m_selEntitySelection.Pointer(0) == iten)
{
// it is, get file name as one that others will compare with
strIntersectingClass = fnClassFileName;
// remember name
strIntersectingName = strEntityName;
// and description
strIntersectingDescription = strEntityDescription;
}
else
{
// if any of the selected entities has different class
if( strIntersectingClass != fnClassFileName)
{
// set multi class message
strIntersectingClass = "Multi class";
}
if( strIntersectingName != iten->GetName())
{
// set multi class message
strIntersectingName = "Multi name";
}
// if any of the selected entities has different class description
if( strIntersectingDescription != iten->GetDescription())
{
// set multi class description message
strIntersectingDescription = "Multi description";
}
}
}
m_strEntityClass = strIntersectingClass;
m_strEntityName = strIntersectingName;
m_strEntityDescription = strIntersectingDescription;
// unlock selection's dynamic container
pDoc->m_selEntitySelection.Unlock();
}
void CPropertyComboBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CDialogBar::OnHScroll(nSBCode, nPos, pScrollBar);
// copy color to selected entities
SetColorPropertyToEntities( m_EditColorCtrl.GetColor());
// refresh views
CWorldEditorDoc *pDoc = theApp.GetDocument();
// mark that document is changed
pDoc->SetModifiedFlag( TRUE);
// redraw all views
pDoc->UpdateAllViews( NULL);
}
CEntity *CPropertyComboBar::GetSelectedEntityPtr(void)
{
// obtain selected property ID ptr
CPropertyID *ppidProperty = GetSelectedProperty();
// if there is valid property selected
if( (ppidProperty == NULL) ||
(ppidProperty->pid_eptType != CEntityProperty::EPT_ENTITYPTR) ||
(ppidProperty->pid_eptType != CEntityProperty::EPT_PARENT) )
{
return NULL;
}
// get currently selected combo member
INDEX iSelectedComboMember = m_EditEnumComboBox.GetCurSel();
// it must exist
ASSERT( iSelectedComboMember != CB_ERR);
// get entity ptr to be set for all entities
CEntity *penEntity = (CEntity *)m_EditEnumComboBox.GetItemData(iSelectedComboMember);
return penEntity;
}
void CPropertyComboBar::OnUpdateNoFile(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE);
}
void CPropertyComboBar::OnUpdateNoTarget(CCmdUI* pCmdUI)
{
pCmdUI->Enable( TRUE);
}
void CPropertyComboBar::OnNoFile(void)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
// obtain curently selected property ID
CPropertyID *ppidProperty = GetSelectedProperty();
if( ppidProperty == NULL) return;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
switch( ppidProperty->pid_eptType)
{
case CEntityProperty::EPT_FILENAMENODEP:
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTFileNameNoDep) = CTFileNameNoDep("");
break;
case CEntityProperty::EPT_FILENAME:
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CTFileName) = CTFileName(CTString(""));
break;
}
// apply new entity settings
iten->Initialize();
}
// mark that document is changed
pDoc->SetModifiedFlag( TRUE);
pDoc->UpdateAllViews( NULL);
pDoc->m_chSelections.MarkChanged();
// reload data to dialog
UpdateData( FALSE);
}
void CPropertyComboBar::ClearAllTargets(CEntity *penClicked)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
if( penClicked == NULL) return;
// if it is selected
if( penClicked->IsSelected( ENF_SELECTED))
{
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// discard old entity settings
iten->End();
// obtain entity class ptr
CDLLEntityClass *pdecDLLClass = iten->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 &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
if( epProperty.ep_eptType == CEntityProperty::EPT_ENTITYPTR)
{
// clear entity ptr
ENTITYPROPERTY( &*iten, epProperty.ep_slOffset, CEntityPointer) = NULL;
}
}
}
// apply new entity settings
iten->Initialize();
}
}
// if is not selected
else
{
// discard old entity settings
penClicked->End();
// obtain entity class ptr
CDLLEntityClass *pdecDLLClass = penClicked->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 &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
if( epProperty.ep_eptType == CEntityProperty::EPT_ENTITYPTR)
{
// clear entity ptr
ENTITYPROPERTY( &*penClicked, epProperty.ep_slOffset, CEntityPointer) = NULL;
}
}
}
// apply new entity settings
penClicked->Initialize();
}
pDoc->m_chSelections.MarkChanged();
UpdateData( FALSE);
}
void CPropertyComboBar::SelectProperty(CEntityProperty *penpToMatch)
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
if( pDoc->m_selEntitySelection.Count() != 1)return;
CEntity *pen = pDoc->m_selEntitySelection.GetFirstInSelection();
if( pen == NULL) return;
// note selection change
m_PropertyComboBox.OnIdle( 0);
for( INDEX iItem=0; iItem<m_PropertyComboBox.GetCount(); iItem++)
{
CPropertyID *ppid = (CPropertyID *) m_PropertyComboBox.GetItemData( iItem);
CEntityProperty *penpProperty = pen->PropertyForName( ppid->pid_strName);
if( penpProperty == penpToMatch)
{
m_PropertyComboBox.SetCurSel(iItem);
m_PropertyComboBox.SelectProperty();
return;
}
}
}
void CPropertyComboBar::OnNoTarget()
{
CWorldEditorDoc *pDoc = theApp.GetDocument();
if( pDoc == NULL) return;
// obtain curently selected property ID
CPropertyID *ppidProperty = GetSelectedProperty();
if( ppidProperty == NULL) return;
// for each of the selected entities
FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
{
// obtain property ptr
CEntityProperty *penpProperty = iten->PropertyForName( ppidProperty->pid_strName);
// discard old entity settings
iten->End();
switch( ppidProperty->pid_eptType)
{
case CEntityProperty::EPT_ENTITYPTR:
ENTITYPROPERTY( &*iten, penpProperty->ep_slOffset, CEntityPointer) = NULL;
break;
case CEntityProperty::EPT_PARENT:
iten->SetParent( NULL);
break;
}
// apply new entity settings
iten->Initialize();
}
// mark that document is changed
pDoc->SetModifiedFlag( TRUE);
pDoc->UpdateAllViews( NULL);
pDoc->m_chSelections.MarkChanged();
// reload data to dialog
UpdateData( FALSE);
}