/* 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. */ // 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; iItempid_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; iItempid_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; iEnumepet_ctValues; iEnum++) { if( epEnum->epet_aepevValues[ iEnum].epev_strName!="") { ulEditable|=(1UL)<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; iCombopid_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; iCombopid_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;iAnimationGetAnimsCt();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; iCombopid_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 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; iCombom_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; iPropertydec_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; iPropertydec_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; iItemPropertyForName( 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); }