summaryrefslogtreecommitdiff
path: root/public/dme_controls/attributeslider.h
blob: 1f68dbf009ef61890ee579ec119b65cb3068fc00 (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
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================

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

#include "vgui_controls/EditablePanel.h"
#include "dme_controls/AnimSetAttributeValue.h"
#include "materialsystem/MaterialSystemUtil.h"
#include "datamodel/dmehandle.h"

using namespace vgui;


//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CBaseAnimSetAttributeSliderPanel;
class CDmElement;
class CAttributeSliderTextEntry;
class CSubRectImage;


//-----------------------------------------------------------------------------
// CAttributeSlider
//-----------------------------------------------------------------------------

// THIS CODE IS KIND OF A MESS WRT THE VARIOUS STATES WE CAN BE IN:
// we can be driven by the preset pane or by dragging on any individual control
// we can also be driven by ctrl hovering over the preset pane or an individual control
// if we move from control to control in the preset or here, we need to be able to decay into/out of the various individual sliders
class CAttributeSlider : public EditablePanel 
{
	DECLARE_CLASS_SIMPLE( CAttributeSlider, EditablePanel );

	// Overridden methods of EditablePanel
public:
	virtual void Paint();
	virtual void PaintBackground();
	virtual void ApplySchemeSettings( IScheme *scheme );
	virtual void PerformLayout();
	virtual void OnCursorMoved(int x, int y);
	virtual void OnMousePressed(MouseCode code);
	virtual void OnMouseDoublePressed(MouseCode code);
	virtual void OnMouseReleased(MouseCode code);
	virtual void OnCursorEntered();
	virtual void OnCursorExited();
	virtual void OnKeyCodeTyped( KeyCode code );

	// Other public methods
public:
	CAttributeSlider( CBaseAnimSetAttributeSliderPanel *parent, const char *panelName, CDmElement *control );
	virtual ~CAttributeSlider();

	// Returns the control we're modifying
	CDmElement *GetControl();

	// Activates/deactivates a slider control
	// NOTE: Slider control 'value' defaults to active, 'balance' and 'multilevel' defaults to inactive
	void ActivateControl( AnimationControlType_t type, bool bActive );
	bool IsControlActive( AnimationControlType_t type );

	// Gets/sets the slider value. 
	// NOTE: This may not match the value pushed into the control because of fading
	void SetValue( AnimationControlType_t type, float flValue );
	float GetValue( AnimationControlType_t type ) const;
	void SetValue( const AttributeValue_t& value );
	const AttributeValue_t& GetValue() const;

	// Is this slider manipulating a transform control? 
	// [NOTE: This is a utility method; the control contains these states]
	bool IsTransform() const;

	// Returns the default value for a control
	// [NOTE: These is a utility method; the control contains these states]
	float GetControlDefaultValue( AnimationControlType_t type ) const;

	// Are we dragging? If so, what control is being dragged?
	bool IsDragging() const;
	AnimationControlType_t GetDragControl() const;

	// Are we in text entry mode? If so, what control is having text entered?
	bool IsInTextEntry() const;
	AnimationControlType_t GetTextEntryControl() const;

	// Estimates the value of the control given a local coordinate
	float EstimateValueAtPos( int nLocalX, int nLocalY ) const;

	void		SetPreview( const AttributeValue_t &value, const AttributeValue_t &full, bool instantaneous, bool startfromcurrent );
	float		GetPreview( AnimationControlType_t type ) const;
	const AttributeValue_t &GetPreview() const;

	void		EnablePreview( bool state, bool simple, bool faderdrag );
	bool		IsPreviewEnabled() const;
	bool		IsSimplePreview() const; 

	void		UpdateTime( float dt );
	void		UpdateFaderAmount( float amount );

	bool		IsRampingTowardPreview() const;
	void		RampDown();

	bool		IsFaderBeingDragged();

	void		SetIsLogPreviewControl( bool state );

	void		SetSelected( bool state );
	bool		IsSelected() const;

private:
	// Various slider modes
	enum SliderMode_t
	{
		SLIDER_MODE_FIRST_DRAG_MODE = 0x0,
		SLIDER_MODE_FIRST_TEXT_MODE = 0x4,
		SLIDER_MODE_LAST_DRAG_MODE = SLIDER_MODE_FIRST_DRAG_MODE + ANIM_CONTROL_COUNT - 1,
		SLIDER_MODE_LAST_TEXT_MODE = SLIDER_MODE_FIRST_TEXT_MODE + ANIM_CONTROL_COUNT - 1,

		SLIDER_MODE_NONE = -1,

		SLIDER_MODE_DRAG_VALUE = SLIDER_MODE_FIRST_DRAG_MODE + ANIM_CONTROL_VALUE,
		SLIDER_MODE_DRAG_BALANCE = SLIDER_MODE_FIRST_DRAG_MODE + ANIM_CONTROL_BALANCE,
		SLIDER_MODE_DRAG_MULTILEVEL = SLIDER_MODE_FIRST_DRAG_MODE + ANIM_CONTROL_MULTILEVEL,

		SLIDER_MODE_TEXT_VALUE = SLIDER_MODE_FIRST_TEXT_MODE + ANIM_CONTROL_VALUE,
		SLIDER_MODE_TEXT_BALANCE = SLIDER_MODE_FIRST_TEXT_MODE + ANIM_CONTROL_BALANCE,
		SLIDER_MODE_TEXT_MULTILEVEL = SLIDER_MODE_FIRST_TEXT_MODE + ANIM_CONTROL_MULTILEVEL,
	};

	struct Preview_t
	{
		AttributeValue_t m_Current;
		AttributeValue_t m_Full;
	};

private:
	// Returns the location of a particular control
	void GetControlRect( Rect_t *pRect, AnimationControlType_t type ) const;

	// Given a mouse position in (x,y) in local coordinates, which animation control is it over?
	AnimationControlType_t DetermineControl( int x, int y );

	// Draws a tick on a circular control
	void DrawCircularTick( const Color& clr, float flValue, int nCenterX, int nCenterY, float flRadius );

	// Draws a preview of a circular control
	void DrawCircularPreview( AnimationControlType_t type, bool bMainTick, float flRadius );

	// Paints the a circular control
	void PaintCircularControl( float flValue, const Rect_t& rect );

	// Called by the text entry code to enter the value into the logs
	void StampValueIntoLogs( AnimationControlType_t type, float flValue );

	// Methods related to rendering
	void DrawMidpoint( int x, int ty, int ttall );
	void DrawPreviewTick( bool mainTick );
	void DrawTick( const Color& clr, float frac, int width, int inset );
	void DrawNameLabel();
	void DrawValueLabel( float flValue );
	float GetPreviewAlphaScale() const;

	// Methods related to text entry mode
	void EnterTextEntryMode( AnimationControlType_t type, bool bRelatchValues );
	void AcceptTextEntryValue();
	void DiscardTextEntryValue();

private:
	CBaseAnimSetAttributeSliderPanel *m_pParent;
	TextImage *m_pName;
	TextImage *m_pValues[ 3 ];
	CSubRectImage *m_pCircleImage;	// The background for the balance + multilevel controls

	// This is the control we're modifying
	CDmeHandle< CDmElement > m_hControl;

	// White material used for drawing non-textured things
	CMaterialReference m_pWhite;

	// The current mode of the slider
	SliderMode_t m_SliderMode;

	// The slider value; it may not match the control attribute value due to blending
	AttributeValue_t m_Control;

	// Is the slider control active?
	bool m_bIsControlActive[ANIM_CONTROL_COUNT];

	// Info used when in text entry mode
	AttributeValue_t m_InitialTextEntryValue;
	CAttributeSliderTextEntry *m_pTextField; // if this is a stereo control, then this will be the left text field
	CAttributeSliderTextEntry *m_pRightTextField;

	Preview_t		m_Next;
	Preview_t		m_Previous;
	Preview_t		m_Preview;
	float			m_flPreviewGoalTime;
	float			m_flFaderAmount;

	// Fields used to help with drag
	int				m_nDragStartPosition[2];	// Where was the mouse clicked?
	int				m_nAccum[2];				// What's the total mouse movement during the drag?
	float			m_flDragStartValue;			// What was the value of the slider before the drag started?
	float			m_flDragStartBalance;		// What was the balance of the slider before the drag started?

	bool			m_bCursorInsidePanel : 1;	// Used to 
	bool			m_bRampUp : 1;
	bool			m_bPreviewEnabled : 1;
	bool			m_bSimplePreviewOnly : 1;
	bool			m_bFaderBeingDragged : 1;
	bool			m_bIsLogPreviewControl : 1;
	bool			m_bTransform : 1;
	bool			m_bSelected : 1;

	friend class CAttributeSliderTextEntry;
};


//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Returns the control
//-----------------------------------------------------------------------------
inline CDmElement *CAttributeSlider::GetControl()
{
	return m_hControl;
}


//-----------------------------------------------------------------------------
// Returns information about the control
//-----------------------------------------------------------------------------
inline bool CAttributeSlider::IsTransform() const
{
	// NOTE: We may well not wish to cache this off in the constructor.
	// It's done purely for efficiency reasons.
	// Uncomment the line to make it read from the control.
	// return m_hControl->GetValue< bool >( "transform" )
	return m_bTransform;
}


//-----------------------------------------------------------------------------
// Are we dragging?
//-----------------------------------------------------------------------------
inline bool CAttributeSlider::IsDragging() const
{
	COMPILE_TIME_ASSERT( ANIM_CONTROL_COUNT < 4 );
	return ( m_SliderMode >= SLIDER_MODE_FIRST_DRAG_MODE && m_SliderMode <= SLIDER_MODE_LAST_DRAG_MODE ); 
}

inline AnimationControlType_t CAttributeSlider::GetDragControl() const
{
	if ( IsDragging() )
		return (AnimationControlType_t)( m_SliderMode - SLIDER_MODE_FIRST_DRAG_MODE );
	return ANIM_CONTROL_INVALID;
}


//-----------------------------------------------------------------------------
// Are we in text entry mode?
//-----------------------------------------------------------------------------
inline bool CAttributeSlider::IsInTextEntry() const
{
	COMPILE_TIME_ASSERT( ANIM_CONTROL_COUNT < 4 );
	return ( m_SliderMode >= SLIDER_MODE_FIRST_TEXT_MODE && m_SliderMode <= SLIDER_MODE_LAST_TEXT_MODE ); 
}

inline AnimationControlType_t CAttributeSlider::GetTextEntryControl() const
{
	if ( IsInTextEntry() )
		return (AnimationControlType_t)( m_SliderMode - SLIDER_MODE_FIRST_TEXT_MODE );
	return ANIM_CONTROL_INVALID;
}

#endif // ATTRIBUTESLIDER_H