123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- /* 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. */
- // PropertyComboBox.cpp : implementation file
- //
- #include "stdafx.h"
- #include "PropertyComboBox.h"
- #ifdef _DEBUG
- #undef new
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CPropertyComboBox
- CPropertyComboBox::CPropertyComboBox()
- {
- }
- CPropertyComboBox::~CPropertyComboBox()
- {
- // delete current property list
- FORDELETELIST(CPropertyID, pid_lnNode, m_lhProperties, itDel)
- {
- delete &itDel.Current();
- }
- }
- void CPropertyComboBox::SetDialogPtr( CPropertyComboBar *pDialog)
- {
- m_pDialog = pDialog;
- DisableCombo();
- }
- BEGIN_MESSAGE_MAP(CPropertyComboBox, CComboBox)
- //{{AFX_MSG_MAP(CPropertyComboBox)
- ON_WM_CONTEXTMENU()
- ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange)
- ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CPropertyComboBox message handlers
- void CPropertyComboBox::OnContextMenu(CWnd* pWnd, CPoint point)
- {
- INDEX i=0;
- }
- void CPropertyComboBox::JoinProperties( CEntity *penEntity, BOOL bIntersect)
- {
- // if we should add all of this entity's properties (if this is first entity)
- if( !bIntersect)
- {
- // obtain entity class ptr
- CDLLEntityClass *pdecDLLClass = penEntity->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];
- // don't add properties with no name
- if( epProperty.ep_strName != CTString("") )
- {
- CAnimData *pAD = NULL;
- // remember anim data
- if( epProperty.ep_eptType == CEntityProperty::EPT_ANIMATION)
- {
- pAD = penEntity->GetAnimData( epProperty.ep_slOffset);
- }
- // create current CPropertyID
- CPropertyID *pPropertyID = new CPropertyID( epProperty.ep_strName,
- epProperty.ep_eptType, &epProperty, pAD);
- // if we should add all of this entity's properties (if this is first entity)
- // and add it into list
- m_lhProperties.AddTail( pPropertyID->pid_lnNode);
- }
- }
- }
- }
- // in case of intersecting properties we should take one of existing properties in list
- // and see if investigating entity has property with same descriptive name
- // If not, remove it that existing property.
- else
- {
- FORDELETELIST(CPropertyID, pid_lnNode, m_lhProperties, itProp)
- {
- CTString strCurrentName = itProp->pid_strName;
- CEntityProperty::PropertyType eptCurrentType = itProp->pid_eptType;
- // mark that property with same name is not found
- BOOL bSameFound = FALSE;
- // obtain entity class ptr
- CDLLEntityClass *pdecDLLClass = penEntity->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];
- CAnimData *pAD = NULL;
- // remember anim data
- if( epProperty.ep_eptType == CEntityProperty::EPT_ANIMATION)
- {
- pAD = penEntity->GetAnimData( epProperty.ep_slOffset);
- }
- // create current CPropertyID
- CPropertyID PropertyID = CPropertyID( epProperty.ep_strName, epProperty.ep_eptType,
- &epProperty, pAD);
- // is this property same as one we are investigating
- if( (strCurrentName == PropertyID.pid_strName) &&
- (eptCurrentType == PropertyID.pid_eptType) )
- {
- // if propperty is enum, enum ptr must also be the same
- if( itProp->pid_eptType == CEntityProperty::EPT_ENUM)
- {
- // only then,
- if( itProp->pid_penpProperty->ep_pepetEnumType ==
- PropertyID.pid_penpProperty->ep_pepetEnumType)
- {
- // same property is found
- bSameFound = TRUE;
- }
- else
- {
- bSameFound = FALSE;
- }
- goto pcb_OutLoop_JoinProperties;
- }
- // if propperty is animation, anim data ptr must be the same
- else if( itProp->pid_eptType == CEntityProperty::EPT_ANIMATION)
- {
- if(itProp->pid_padAnimData == PropertyID.pid_padAnimData)
- {
- // same property is found
- bSameFound = TRUE;
- }
- else
- {
- bSameFound = FALSE;
- }
- goto pcb_OutLoop_JoinProperties;
- }
- else
- {
- // same property is found
- bSameFound = TRUE;
- goto pcb_OutLoop_JoinProperties;
- }
- }
- }
- }
- pcb_OutLoop_JoinProperties:;
- // if property with same name is not found
- if( !bSameFound)
- {
- // remove our investigating property from list
- itProp->pid_lnNode.Remove();
- // and delete it
- delete &itProp.Current();
- }
- }
- }
- }
- BOOL CPropertyComboBox::OnIdle(LONG lCount)
- {
- // get active document
- CWorldEditorDoc* pDoc = theApp.GetActiveDocument();
- // if document ptr has changed
- // or if document was closed (pDoc == NULL and pLastDoc != NULL)
- // or if mode was changed
- // or if selection was changed from last OnIdle, refresh properties
- if( (m_pLastDoc != pDoc) ||
- ((pDoc == NULL) && (m_pLastDoc != NULL)) ||
- ((pDoc != NULL) && (m_iLastMode != pDoc->m_iMode)) ||
- ((pDoc != NULL) && !pDoc->m_chSelections.IsUpToDate( m_udComboEntries)) )
- {
- // refresh selected members message
- if( (pDoc != NULL))
- {
- pDoc->SetStatusLineModeInfoMessage();
- }
- // remove all combo entries
- ResetContent();
- // if document exists and mode is entities
- if( (pDoc != NULL) && (pDoc->m_iMode == ENTITY_MODE) )
- {
- // delete current property list
- FORDELETELIST(CPropertyID, pid_lnNode, m_lhProperties, itDel)
- {
- delete &itDel.Current();
- }
- // lock selection's dynamic container
- pDoc->m_selEntitySelection.Lock();
- // 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)
- {
- // add all of its properties into joint list but don't intersect with existing ones
- JoinProperties( iten, FALSE);
- }
- else
- {
- // intersect entity's properties with existing ones
- JoinProperties( iten, TRUE);
- }
- }
- // unlock selection's dynamic container
- pDoc->m_selEntitySelection.Unlock();
- if( pDoc->m_selEntitySelection.Count() != 0)
- {
- // ----------------- Add spawn flags property
- CPropertyID *ppidSpawnFlags = new CPropertyID( "Spawn flags (Alt+Shift+S)",
- CEntityProperty::EPT_SPAWNFLAGS, NULL, NULL);
- m_lhProperties.AddTail( ppidSpawnFlags->pid_lnNode);
- // ----------------- Add parent entity property
- CPropertyID *ppidParent = new CPropertyID( "Parent (Alt+Shift+A)",
- CEntityProperty::EPT_PARENT, NULL, NULL);
- m_lhProperties.AddTail( ppidParent->pid_lnNode);
- }
- // if there are some intersecting properties
- if( !m_lhProperties.IsEmpty())
- {
- // add intersecting properties of selected entities into combo box
- FOREACHINLIST(CPropertyID, pid_lnNode, m_lhProperties, itProp)
- {
- char achrShortcutKey[ 64] = "";
- if( itProp->pid_chrShortcutKey != 0)
- {
- sprintf( achrShortcutKey, " (%c)", itProp->pid_chrShortcutKey);
- }
- // add property name and shortcut key
- INDEX iAddedAs = AddString( CString(itProp->pid_strName + achrShortcutKey));
- // set ptr to property ID object
- SetItemData( iAddedAs, (ULONG) &*itProp);
- // enable combo
- EnableWindow();
- }
- }
- // if there are no properties to choose from
- else
- {
- DisableCombo();
- }
- }
- // if there are no document or application is not in edit entitiy mode
- else
- {
- DisableCombo();
- }
- // index of property that is selected (trying to keep the same property active)
- INDEX iSelectedProperty = 0;
- // for all members in combo box
- for( INDEX iMembers = 0; iMembers<GetCount(); iMembers++)
- {
- CPropertyID *ppidPropertyID = (CPropertyID *) GetItemData( iMembers);
- // if this is valid property
- if( ppidPropertyID != NULL)
- {
- // if name of this property is same as last selected property name
- if( ppidPropertyID->pid_strName == m_strLastPropertyName)
- {
- // mark this property as selected by default
- iSelectedProperty = iMembers;
- break;
- }
- }
- }
-
- // select entity 0 by default
- SetCurSel( iSelectedProperty);
- // mark possible document change
- m_pLastDoc = pDoc;
- // set new mode
- if( pDoc != NULL)
- {
- m_iLastMode = pDoc->m_iMode;
- }
- m_pDialog->ArrangeControls();
- // if edit color property is active
- if( m_pDialog->m_EditColorCtrl.IsWindowVisible())
- {
- // invalidate it so it will be refreshed properly
- m_pDialog->m_EditColorCtrl.Invalidate( FALSE);
- }
- m_udComboEntries.MarkUpdated();
- }
- return TRUE;
- }
- void CPropertyComboBox::OnSelchange()
- {
- SelectProperty();
- }
- void CPropertyComboBox::SelectProperty(void)
- {
- CPropertyID *ppidPropertyID = (CPropertyID *) GetItemData( GetCurSel());
- // must be valid property
- ASSERT( ppidPropertyID != NULL);
- // remember name of this property as last selected property name
- m_strLastPropertyName = ppidPropertyID->pid_strName;
- // show/hide appropriate editing propterty controls
- m_pDialog->ArrangeControls();
- }
- void CPropertyComboBox::DisableCombo()
- {
- // remove all combo entries
- ResetContent();
- // set default message
- INDEX iAddedAs = AddString( L"None Available");
- // set invalid ptr
- SetItemData( iAddedAs, NULL);
- // disable combo
- EnableWindow( FALSE);
- }
- void CPropertyComboBox::OnDropdown()
- {
- INDEX ctItems = GetCount();
- if( ctItems == CB_ERR) return;
-
- CRect rectCombo;
- GetWindowRect( &rectCombo);
-
- PIX pixScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
- PIX pixMaxHeight = pixScreenHeight - rectCombo.top;
- m_pDialog->ScreenToClient( &rectCombo);
- PIX pixNewHeight = GetItemHeight(0)*(ctItems+2);
- rectCombo.bottom = rectCombo.top + ClampUp( pixNewHeight, pixMaxHeight);
- MoveWindow( rectCombo);
- }
|