You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
5.2 KiB
200 lines
5.2 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//===========================================================================// |
|
|
|
#include "matsys_controls/curveeditorpanel.h" |
|
#include "matsys_controls/matsyscontrols.h" |
|
#include "tier1/KeyValues.h" |
|
#include "vgui/ISurface.h" |
|
#include "vgui/IInput.h" |
|
#include "vgui/MouseCode.h" |
|
|
|
using namespace vgui; |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CCurveEditorPanel::CCurveEditorPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName ) |
|
{ |
|
m_nSelectedPoint = -1; |
|
SetMouseInputEnabled( true ); |
|
SetKeyBoardInputEnabled( true ); |
|
m_nHighlightedPoint = -1; |
|
} |
|
|
|
CCurveEditorPanel::~CCurveEditorPanel() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Converts screen location to normalized values |
|
//----------------------------------------------------------------------------- |
|
void CCurveEditorPanel::ScreenToValue( int x, int y, float *pIn, float *pOut ) |
|
{ |
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
*pIn = (float)x / (w-1); |
|
*pOut = 1.0f - ((float)y / (h-1)); |
|
} |
|
|
|
void CCurveEditorPanel::ValueToScreen( float flIn, float flOut, int *x, int *y ) |
|
{ |
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
*x = (int)(flIn * (w-1) + 0.5f); |
|
*y = (h-1) - (int)(flOut * (h-1) + 0.5f); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Handle input |
|
//----------------------------------------------------------------------------- |
|
void CCurveEditorPanel::OnMousePressed( vgui::MouseCode code ) |
|
{ |
|
BaseClass::OnMousePressed( code ); |
|
|
|
int x, y; |
|
input()->GetCursorPos( x, y ); |
|
ScreenToLocal( x, y ); |
|
|
|
if ( code == MOUSE_LEFT ) |
|
{ |
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
float flIn, flOut; |
|
ScreenToValue( x, y, &flIn, &flOut ); |
|
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point |
|
m_nSelectedPoint = FindOrAddControlPoint( flIn, flTolerance, flOut ); |
|
} |
|
} |
|
|
|
void CCurveEditorPanel::OnMouseReleased( vgui::MouseCode code ) |
|
{ |
|
BaseClass::OnMouseReleased( code ); |
|
|
|
if ( code == MOUSE_LEFT ) |
|
{ |
|
m_nSelectedPoint = -1; |
|
} |
|
} |
|
|
|
void CCurveEditorPanel::OnCursorMoved( int x, int y ) |
|
{ |
|
BaseClass::OnCursorMoved( x, y ); |
|
|
|
float flIn, flOut; |
|
ScreenToValue( x, y, &flIn, &flOut ); |
|
|
|
int w, h; |
|
GetSize( w, h ); |
|
float flTolerance = 5.0f / (w-1); // +/- 3 pixels to select the point |
|
m_nHighlightedPoint = FindControlPoint( flIn, flTolerance ); |
|
|
|
if ( m_nSelectedPoint < 0 ) |
|
return; |
|
m_nSelectedPoint = ModifyControlPoint( m_nSelectedPoint, flIn, flOut ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Handles keypresses |
|
//----------------------------------------------------------------------------- |
|
void CCurveEditorPanel::OnKeyCodePressed( vgui::KeyCode code ) |
|
{ |
|
BaseClass::OnKeyCodePressed( code ); |
|
|
|
if ( m_nSelectedPoint >= 0 ) |
|
{ |
|
RemoveControlPoint( m_nSelectedPoint ); |
|
m_nSelectedPoint = -1; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// This paints the grid behind the curves |
|
//----------------------------------------------------------------------------- |
|
void CCurveEditorPanel::PaintBackground( void ) |
|
{ |
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
vgui::surface()->DrawSetColor( 255, 255, 255, 255 ); |
|
vgui::surface()->DrawFilledRect( 0, 0, w, h ); |
|
|
|
vgui::surface()->DrawSetColor( 128, 128, 128, 255 ); |
|
vgui::surface()->DrawLine( 0, h/4, w, h/4 ); |
|
vgui::surface()->DrawLine( 0, h/2, w, h/2 ); |
|
vgui::surface()->DrawLine( 0, 3*h/4, w, 3*h/4 ); |
|
|
|
vgui::surface()->DrawLine( w/4, 0, w/4, h ); |
|
vgui::surface()->DrawLine( w/2, 0, w/2, h ); |
|
vgui::surface()->DrawLine( 3*w/4, 0, 3*w/4, h ); |
|
|
|
vgui::surface()->DrawSetColor( 0, 0, 0, 255 ); |
|
vgui::surface()->DrawLine( 0, 0, w, 0 ); |
|
vgui::surface()->DrawLine( w, 0, w, h ); |
|
vgui::surface()->DrawLine( w, h, 0, h ); |
|
vgui::surface()->DrawLine( 0, h, 0, 0 ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the color curves operation to edit |
|
//----------------------------------------------------------------------------- |
|
void CCurveEditorPanel::Paint( void ) |
|
{ |
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
int x0 = 0, y0 = 0; |
|
|
|
// FIXME: Add method to draw multiple lines DrawPolyLine connects the 1st and last points... bleah |
|
vgui::surface()->DrawSetColor( 0, 0, 0, 255 ); |
|
for ( int i = 0; i < w; ++i ) |
|
{ |
|
float flIn = (float)i / (w-1); |
|
float flOut = GetValue( flIn ); |
|
int x = i; |
|
int y = (h-1) - (int)(flOut * (h-1) + 0.5f); |
|
y = clamp( y, 0, h-1 ); |
|
|
|
if ( i != 0 ) |
|
{ |
|
vgui::surface()->DrawLine( x0, y0, x, y ); |
|
} |
|
|
|
x0 = x; y0 = y; |
|
} |
|
|
|
|
|
// This will paint the control points |
|
// The currently selected one will be painted red and filled. |
|
for ( int i = ControlPointCount(); --i >= 0; ) |
|
{ |
|
float flIn, flOut; |
|
GetControlPoint( i, &flIn, &flOut ); |
|
|
|
int cx, cy; |
|
ValueToScreen( flIn, flOut, &cx, &cy ); |
|
|
|
if ( (i == m_nSelectedPoint) || ((m_nSelectedPoint == -1) && (i == m_nHighlightedPoint)) ) |
|
{ |
|
vgui::surface()->DrawSetColor( 255, 0, 0, 255 ); |
|
vgui::surface()->DrawFilledRect( cx-3, cy-3, cx+3, cy+3 ); |
|
} |
|
else |
|
{ |
|
vgui::surface()->DrawSetColor( 0, 0, 0, 255 ); |
|
vgui::surface()->DrawOutlinedRect( cx-3, cy-3, cx+3, cy+3 ); |
|
} |
|
} |
|
} |