summaryrefslogtreecommitdiff
path: root/hammer/op_entity.h
blob: e8db2db21a8380876e0ea3fa69e191446c565d22 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================//

#ifndef OP_ENTITY_H
#define OP_ENTITY_H
#ifdef _WIN32
#pragma once
#endif

#include "AutoSelCombo.h"
#include "ChunkFile.h"
#include "ListBoxEx.h"
#include "AngleBox.h"
#include "fgdlib/WCKeyValues.h"
#include "MapFace.h"
#include "ObjectPage.h"
#include "ToolPickAngles.h"
#include "ToolPickEntity.h"
#include "ToolPickFace.h"
#include "FilteredComboBox.h"
#include "AnchorMgr.h"
#include "ModelBrowser.h"

class CEditGameClass;
class COP_Entity;
class COP_Flags;
class CMyComboBox;

//-----------------------------------------------------------------------------
// Owner-draw list control that uses cool colors to show 
// the state of items.
//-----------------------------------------------------------------------------
class CColoredListCtrl : public CListCtrl
{
public:

	class IItemColorCallback
	{
	public:
		// This is called for every item to get its colors.
		virtual void GetItemColor( int iItem, COLORREF *pBackgroundColor, COLORREF *pTextColor ) = 0;
		
		// This is called for every item so you can draw custom stuff in its value column.
		// The RECT inside the DRAWITEMSTRUCT contains the whole row, and pRect contains the rect for the value column only.
		// Return true if you don't want CColoredListControl to draw its value.
		virtual bool CustomDrawItemValue( const LPDRAWITEMSTRUCT p, const RECT *pRect ) = 0;
	};

public:
	CColoredListCtrl( IItemColorCallback *pCallback );
	
	virtual void DrawItem( LPDRAWITEMSTRUCT p );

private:
	IItemColorCallback *m_pCallback;
};


//-----------------------------------------------------------------------------
// Purpose: A little glue object that connects the angles picker tool to our dialog.
//-----------------------------------------------------------------------------
class CPickAnglesTarget : public IPickAnglesTarget
{
	public:

		void AttachEntityDlg(COP_Entity *pDlg) { m_pDlg = pDlg; }
		void OnNotifyPickAngles(const Vector &vecPos);
	
	private:

		COP_Entity *m_pDlg;
};


//-----------------------------------------------------------------------------
// Purpose: A little glue object that connects the entity picker tool to our dialog.
//			Currently this gets the value of a given key and puts that into the smart
//			control.
//-----------------------------------------------------------------------------
class CPickEntityTarget : public IPickEntityTarget
{
	public:

		inline CPickEntityTarget();
		void AttachEntityDlg(COP_Entity *pDlg) { m_pDlg = pDlg; }
		inline void SetKeyToRetrieve(const char *pszKey);
		void OnNotifyPickEntity(CToolPickEntity *pTool);
	
	private:

		char m_szKey[MAX_KEYVALUE_LEN];		// The name of the key we are going to slurp out of the entity.
		COP_Entity *m_pDlg;					// The dialog to receive the key value.
};


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CPickEntityTarget::CPickEntityTarget()
{
	m_szKey[0] = '\0';
	m_pDlg = NULL;
}


//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pszKey - 
//-----------------------------------------------------------------------------
void CPickEntityTarget::SetKeyToRetrieve(const char *pszKey)
{
	strncpy(m_szKey, pszKey, sizeof(m_szKey) - 1);
}


//-----------------------------------------------------------------------------
// Purpose: A little glue object that connects the face picker tool to our dialog.
//-----------------------------------------------------------------------------
class CPickFaceTarget : public IPickFaceTarget
{
	public:

		void AttachEntityDlg(COP_Entity *pDlg) { m_pDlg = pDlg; }
		void OnNotifyPickFace(CToolPickFace *pTool);
	
	private:

		COP_Entity *m_pDlg;
};


enum EKeyState
{
	k_EKeyState_DefaultFGDValue=0,	// This key is unmodified from its default value in the FGD.
	k_EKeyState_Modified=1,			// This key is in the FGD, and its value has been modified.
	k_EKeyState_AddedManually,		// This key was added manually (i.e. it does not exist in the FGD).
	k_EKeyState_InstanceParm,
};


class CInstanceParmData
{
public:
	GDinputvariable		*m_ParmVariable;
	CString				m_ParmKey;
	CString				m_VariableName;
};


// This class just routes the OnTextChanged call into COP_Entity.
class CSmartControlTargetNameRouter : public CFilteredComboBox::ICallbacks
{
public:
	CSmartControlTargetNameRouter( COP_Entity *pDlg );

	virtual void OnTextChanged( const char *pText );
	
private:
	COP_Entity *m_pDlg;
};


class COP_Entity : public CObjectPage, CFilteredComboBox::ICallbacks, public CColoredListCtrl::IItemColorCallback
{
	DECLARE_DYNCREATE(COP_Entity)
	typedef CObjectPage BaseClass;
	
	friend int InternalSortByColumn( COP_Entity *pDlg, const char *pShortName1, const char *pShortName2, int iColumn );
	friend int CALLBACK SortByItemEditedState( LPARAM iItem1, LPARAM iItem2, LPARAM lpParam );
	friend class CColoredListCtrl;

	// Construction
	public:

		COP_Entity();
		~COP_Entity();

		virtual void MarkDataDirty();

		//
		// Interface for property sheet.
		//
		virtual bool SaveData(void);
		virtual void UpdateData( int Mode, PVOID pData, bool bCanEdit );
		virtual void RememberState(void);

		//
		// Interface for custom edit control.
		//
		void SetNextVar(int cmd);

		void SetFlagsPage( COP_Flags *pFlagsPage );
		void OnUpdateSpawnFlags( unsigned long preserveMask, unsigned long newValues );
		
		//{{AFX_DATA(COP_Entity)
		enum { IDD = IDD_OBJPAGE_ENTITYKV };
		CAngleCombo m_AngleEdit;
		CAngleCombo m_SmartAngleEdit;
		CEdit m_cValue;
		CColoredListCtrl m_VarList;
		CEdit m_cKey;
		CFilteredComboBox m_cClasses;
		CEdit m_Comments;
		CEdit m_KeyValueHelpText;
		CButton	m_PasteControl;
		//}}AFX_DATA

		// ClassWizard generate virtual function overrides
		//{{AFX_VIRTUAL(COP_Entity)
		protected:
		virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
		virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
		//}}AFX_VIRTUAL

	protected:

	// Implementation of CFilteredComboBox::ICallbacks for m_cClasses.
	
		virtual void OnTextChanged( const char *pText );
		virtual bool OnUnknownEntry( const char *pText );

	// This gets routed from m_pSmartControl (for target names).
		
		virtual void OnSmartControlTargetNameChanged( const char *pText );

	// Implementation of CColoredListCtrl::IItemColorCallback.

		virtual void GetItemColor( int iItem, COLORREF *pBackgroundColor, COLORREF *pTextColor );
		virtual bool CustomDrawItemValue( const LPDRAWITEMSTRUCT p, const RECT *pRect );


	// Other functions.

		// If pMissingTarget is set to true, then it is a 
		void GetKeyState( const char *pShortName, EKeyState *pState, bool *pMissingTarget );
		void ResortItems();
		void LoadClassList();
		void SetSmartedit(bool bSet);
		void RemoveBlankKeys();

		void EnableAnglesControl(bool bEnable);

		void CreateSmartControls(GDinputvariable *pVar, CUtlVector<const char *> *pHelperType);
		void DestroySmartControls(void);

		CRect CalculateSmartControlRect();
		void CreateSmartControls_Angle( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont, bool *bShowSmartAngles );
		void CreateSmartControls_Choices( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont );
		void CreateSmartControls_TargetName( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont );
		void CreateSmartControls_BasicEditControl( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont, CUtlVector<const char *> *pHelperType );
		void CreateSmartControls_BrowseAndPlayButtons( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont );
		void CreateSmartControls_MarkAndEyedropperButtons( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont );
		void CreateSmartControls_PickButton( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont );
		void CreateSmartControls_InstanceVariable( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont );
		void CreateSmartControls_InstanceParm( GDinputvariable *pVar, CRect &ctrlrect, HFONT hControlFont );

		void UpdateDisplayClass(const char *pszClass);
		void UpdateDisplayClass(GDclass *pClass);

		void UpdateEditClass(const char *pszClass, bool bForce);
		void UpdateKeyValue(const char *szKey, const char *szValue);

		virtual void UpdatePickFaceText(CToolPickFace *pTool);
		void GetFaceIDListsForKey(CMapFaceIDList &FullFaces, CMapFaceIDList &PartialFaces, const char *pszKey);
		void GetFaceListsForKey(CMapFaceList &FullFaces, CMapFaceList &PartialFaces, const char *pszKey);
		void ApplyKeyValueToObject(CEditGameClass *pObject, const char *pszKey, const char *pszValue);

		void InternalOnChangeSmartcontrol( const char *szValue );

		// Generated message map functions
		//{{AFX_MSG(COP_Entity)
		afx_msg void OnAddkeyvalue();
		afx_msg BOOL OnApply(void);
		afx_msg void OnBrowse(void);
		afx_msg void OnBrowseInstance(void);
		afx_msg void OnPlaySound(void);
		virtual BOOL OnInitDialog();
		afx_msg void OnSelchangeKeyvalues();
		afx_msg void OnRemovekeyvalue();
		afx_msg void OnSelChangeAngleEdit(void);
		afx_msg void OnChangeAngleedit();
		afx_msg void OnSmartedit();
		afx_msg void OnChangeKeyorValue();
		afx_msg void OnCopy();
		afx_msg void OnPaste();
		afx_msg void OnSetfocusKey();
		afx_msg void OnKillfocusKey();
		afx_msg LRESULT OnChangeAngleBox(WPARAM, LPARAM);
		afx_msg void OnChangeSmartcontrol();
		afx_msg void OnChangeSmartcontrolSel();
		afx_msg void OnChangeInstanceVariableControl();
		afx_msg void OnChangeInstanceParmControl();
		afx_msg void OnPickFaces(void);
		afx_msg void OnPickColor();
		afx_msg void OnMark();
		afx_msg void OnSize( UINT nType, int cx, int cy );
		afx_msg void OnMarkAndAdd();
		afx_msg void OnEntityHelp(void);
		afx_msg void OnPickAngles(void);
		afx_msg void OnPickEntity(void);
		afx_msg void OnCameraDistance(void);
		afx_msg void OnItemChangedKeyValues(NMHDR* pNMHDR, LRESULT* pResult);
		afx_msg void OnDblClickKeyValues(NMHDR* pNMHDR, LRESULT* pResult);
		//}}AFX_MSG

		void BrowseTextures( const char *szFilter, bool bIsSprite = false ); 
		bool BrowseModels( char *szModelName, int length, int &nSkin );
		void MergeObjectKeyValues(CEditGameClass *pEdit);
		void MergeKeyValue(char const *pszKey);
		void SetCurKey(LPCTSTR pszKey);
		void GetCurKey(CString& strKey);

		void SetCurVarListSelection( int iSel );
		int GetCurVarListSelection();

		void OnShowPropertySheet(BOOL bShow, UINT nStatus);
		void StopPicking(void);

		DECLARE_MESSAGE_MAP()

	private:

		void UpdateAnchors();
		void AssignClassDefaults(GDclass *pClass, GDclass *pOldClass);
		
		int GetKeyValueRowByShortName( const char *pShortName );		// Find the row in the listctrl that the var is at. Returns -1 if not found.
		
		void RefreshKVListValues( const char *pOnlyThisVar = NULL );
		void PresentProperties();
		void ClearVarList();
		void SetReadOnly(bool bReadOnly);

		void SetSmartControlText(const char *pszText);
		void PerformMark(const char *pTargetName, bool bClear, bool bNameOrClass);

		void LoadCustomColors();
		void SaveCustomColors();
		
		GDinputvariable *GetVariableAt( int index );

	private:
	
		CAnchorMgr m_AnchorMgr;
		
		CString m_szOldKeyName;
		bool m_bWantSmartedit;
		bool m_bEnableControlUpdate;	// Whether to reflect changes to the edit control into other controls.

		CAngleBox m_Angle;
		CAngleBox m_SmartAngle;

		CButton m_cPickColor;
		bool m_bSmartedit;
		int m_nNewKeyCount;

		CEdit		*m_pEditInstanceVariable, *m_pEditInstanceValue;
		CMyComboBox	*m_pComboInstanceParmType;

		// Used to prevent unnecessary calls to PresentProperties.
		int m_nPresentPropertiesCalls;
		bool m_bAllowPresentProperties;

		GDclass *m_pDisplayClass;		// The class that the dialog is showing. Can be different from m_pEditClass
										// until the user hits Apply.
		GDinputvariable *m_pInstanceVar;

		short m_VarMap[GD_MAX_VARIABLES];
		
		CWnd *m_pSmartControl;			// current smartedit control
		CButton *m_pSmartBrowseButton;
		CUtlVector<CWnd *> m_SmartControls;
		
		// The last variable we setup smart controls for.
		GDinputvariable *m_pLastSmartControlVar;
		CString m_LastSmartControlVarValue;
		
		CString m_strLastKey;			// Active key when SaveData was called.

		GDclass *m_pEditClass;			// The class of the object that we are editing.
		WCKeyValues m_kv;				// Our kv storage. Holds merged keyvalues for multiselect.
		WCKeyValues m_kvAdded;			// Corresponding keys set to value "1" if they were added

		GDIV_TYPE m_eEditType;			// The type of the currently selected key when SmartEdit is enabled.

		bool	 m_bIgnoreKVChange;			// Set to ignore Windows notifications when setting up controls.
		bool	 m_bChangingKeyName;
		
		int		m_iLastClassListSolidClasses;	// Used to prevent reinitializing the class list unnecessarily.

		bool m_bPicking;					// A picking tool is currently active.
		ToolID_t m_ToolPrePick;				// The tool that was active before we activated the picking tool.

		int m_iSortColumn;					// Which column we're sorting the keyvalues by.

		CPickAnglesTarget m_PickAnglesTarget;
		CPickEntityTarget m_PickEntityTarget;
		CPickFaceTarget m_PickFaceTarget;
		
		COP_Flags *m_pFlagsPage;
		
		CSmartControlTargetNameRouter m_SmartControlTargetNameRouter;

		CUtlMap<CString, CInstanceParmData> m_InstanceParmData; 
		
		// Used when multiselecting classes to remember whether they've selected a class
		// or not yet.
		bool m_bClassSelectionEmpty;
		CModelBrowser *pModelBrowser; 

	friend class CPickAnglesTarget;
	friend class CPickEntityTarget;
	friend class CPickFaceTarget;
	friend class CSmartControlTargetNameRouter;

	COLORREF CustomColors[16];
	bool m_bCustomColorsLoaded;
};

// These are used to load the filesystem open dialog.
void LoadFileSystemDialogModule();
void UnloadFileSystemDialogModule();

#endif // OP_ENTITY_H