csgo-2018-source/hammer/op_groups.cpp
2021-07-24 21:11:47 -07:00

318 lines
7.7 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Implements the groups page of the Object Properties dialog. This
// allows the user to edit which visgroups the selected objects belong to.
//
//=============================================================================//
#include "stdafx.h"
#include "hammer.h"
#include "MapWorld.h"
#include "OP_Groups.h"
#include "EditGroups.h"
#include "GlobalFunctions.h"
#include "CustomMessages.h"
#include "ObjectProperties.h"
#include "VisGroup.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
const char *NO_GROUP_STRING = "(no group)";
const DWORD NO_GROUP_ID = 0xffff;
const DWORD VALUE_DIFFERENT_ID = 0xfffe;
static const unsigned int g_uToggleStateMsg = ::RegisterWindowMessage(GROUPLIST_MSG_TOGGLE_STATE);
BEGIN_MESSAGE_MAP(COP_Groups, CObjectPage)
//{{AFX_MSG_MAP(COP_Groups)
ON_BN_CLICKED(IDC_EDITGROUPS, OnEditgroups)
ON_REGISTERED_MESSAGE(g_uToggleStateMsg, OnListToggleState)
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_WM_SETFOCUS()
END_MESSAGE_MAP()
IMPLEMENT_DYNCREATE(COP_Groups, CObjectPage)
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
COP_Groups::COP_Groups()
: CObjectPage(COP_Groups::IDD)
{
//{{AFX_DATA_INIT(COP_Groups)
//}}AFX_DATA_INIT
m_pEditObjectRuntimeClass = RUNTIME_CLASS(editCMapClass);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
COP_Groups::~COP_Groups()
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pDX -
//-----------------------------------------------------------------------------
void COP_Groups::DoDataExchange(CDataExchange* pDX)
{
CObjectPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(COP_Model)
DDX_Control(pDX, IDC_EDITGROUPS, m_EditGroupsControl);
//}}AFX_DATA_MAP
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : b -
//-----------------------------------------------------------------------------
void COP_Groups::SetMultiEdit(bool b)
{
CObjectPage::SetMultiEdit(b);
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool COP_Groups::SaveData( SaveData_Reason_t reason )
{
if (!IsWindow(m_hWnd))
{
return false;
}
int nCount = m_cGroups.GetVisGroupCount();
for (int i = 0; i < nCount; i++)
{
CVisGroup *pVisGroup = m_cGroups.GetVisGroup(i);
// Don't let users edit Auto VisGroup membership!
if ( pVisGroup->IsAutoVisGroup() )
continue;
int nCheck = m_cGroups.GetCheck(pVisGroup);
if (nCheck != -1)
{
FOR_EACH_OBJ( *m_pObjectList, pos )
{
CMapClass *pObject = (CUtlReference< CMapClass >)m_pObjectList->Element(pos);
if (nCheck)
{
pObject->AddVisGroup(pVisGroup);
}
else
{
pObject->RemoveVisGroup(pVisGroup);
}
}
}
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : Mode -
// pData -
//-----------------------------------------------------------------------------
void COP_Groups::UpdateData( int Mode, void *pData, bool bCanEdit )
{
__super::UpdateData( Mode, pData, bCanEdit );
if ( !IsWindow(m_hWnd) )
{
return;
}
static int s_checkState[128];
if (Mode == LoadData || Mode == LoadFirstData)
{
CMapClass *pObject = (CMapClass *)pData;
if (Mode == LoadFirstData)
{
UpdateGroupList();
//
// Loading the first object. check each group this object is in.
//
int nCount = m_cGroups.GetVisGroupCount();
for (int i = 0; i < nCount; i++)
{
CVisGroup *pVisGroup = m_cGroups.GetVisGroup(i);
s_checkState[i] = pObject->IsInVisGroup(pVisGroup);
}
}
else
{
//
// Loading subsequent objects.
//
int nCount = m_cGroups.GetVisGroupCount();
for (int i = 0; i < nCount; i++)
{
if ( s_checkState[i] != -1)
{
CVisGroup *pVisGroup = m_cGroups.GetVisGroup(i);
if ( pObject->IsInVisGroup(pVisGroup) != s_checkState[i] )
{
s_checkState[i] = -1;
}
}
}
}
}
else if ( Mode == LoadFinished )
{
int nCount = m_cGroups.GetVisGroupCount();
for (int i = 0; i < nCount; i++)
{
CVisGroup *pVisGroup = m_cGroups.GetVisGroup(i);
m_cGroups.SetCheck(pVisGroup, s_checkState[i]);
}
}
m_cGroups.EnableWindow( ( m_bCanEdit ? TRUE : FALSE ) );
m_EditGroupsControl.EnableWindow( ( m_bCanEdit ? TRUE : FALSE ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void COP_Groups::UpdateGroupList(void)
{
if (!IsWindow(m_hWnd))
{
return;
}
m_cGroups.SetRedraw(false);
m_cGroups.DeleteAllItems();
CVisGroup *pAuto = NULL;
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
if (pDoc != NULL)
{
int nCount = pDoc->VisGroups_GetRootCount();
for (int i = 0; i < nCount; i++)
{
CVisGroup *pGroup = pDoc->VisGroups_GetRootVisGroup(i);
if (stricmp(pGroup->GetName(), "Auto") != 0)
{
m_cGroups.AddVisGroup(pGroup);
}
else
{
pAuto = pGroup;
}
}
// We can't reassign membership to auto visgroups, and rarely need to check membership,
// so add the "Auto" visgroup last so that it doesn't get in the way.
if (pAuto)
{
m_cGroups.AddVisGroup(pAuto);
}
}
m_cGroups.ExpandAll();
// If this ever gets slow we could pass a param into ExpandAll to not expand "Auto"
if (pAuto)
{
m_cGroups.CollapseItem(pAuto);
}
m_cGroups.SetRedraw(true);
m_cGroups.Invalidate();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void COP_Groups::OnEditgroups()
{
CEditGroups dlg;
dlg.DoModal();
UpdateGroupList();
// dvs: TODO: update the check state for all groups
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
BOOL COP_Groups::OnInitDialog()
{
CObjectPage::OnInitDialog();
m_cGroups.SubclassDlgItem(IDC_GROUPS, this);
m_cGroups.EnableChecks();
CAnchorDef anchorDefs[] =
{
CAnchorDef( IDC_GROUPS, k_eSimpleAnchorAllSides ),
CAnchorDef( IDC_EDITGROUPS, k_eSimpleAnchorBottomRight )
};
m_AnchorMgr.Init( GetSafeHwnd(), anchorDefs, ARRAYSIZE( anchorDefs ) );
return TRUE;
}
//-----------------------------------------------------------------------------
// Purpose: Called when the check state of a group is toggled in the groups list.
// Input : wParam - Index of item in the groups list that was toggled.
// lParam - New check state.
// Output : Returns zero.
//-----------------------------------------------------------------------------
LRESULT COP_Groups::OnListToggleState(WPARAM wParam, LPARAM lParam)
{
CVisGroup *pVisGroup = (CVisGroup *)wParam;
// Don't let users edit Auto VisGroup membership!
if ( pVisGroup->IsAutoVisGroup() )
return 0;
m_cGroups.SetCheck(pVisGroup, (int)lParam);
return 0;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOld -
//-----------------------------------------------------------------------------
void COP_Groups::OnSetFocus(CWnd *pOld)
{
// fixme:
//UpdateGrouplist();
CPropertyPage::OnSetFocus(pOld);
}
void COP_Groups::OnSize( UINT nType, int cx, int cy )
{
m_AnchorMgr.OnSize();
}