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.
2244 lines
49 KiB
2244 lines
49 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
#include <stdio.h>
|
|
#include "hlfaceposer.h"
|
|
#include "SceneRampTool.h"
|
|
#include "mdlviewer.h"
|
|
#include "choreowidgetdrawhelper.h"
|
|
#include "TimelineItem.h"
|
|
#include "expressions.h"
|
|
#include "expclass.h"
|
|
#include "choreoevent.h"
|
|
#include "StudioModel.h"
|
|
#include "choreoscene.h"
|
|
#include "choreoactor.h"
|
|
#include "choreochannel.h"
|
|
#include "ChoreoView.h"
|
|
#include "InputProperties.h"
|
|
#include "ControlPanel.h"
|
|
#include "FlexPanel.h"
|
|
#include "mxExpressionTray.h"
|
|
#include "ExpressionProperties.h"
|
|
#include "tier1/strtools.h"
|
|
#include "faceposer_models.h"
|
|
#include "UtlBuffer.h"
|
|
#include "FileSystem.h"
|
|
#include "iscenetokenprocessor.h"
|
|
#include "choreoviewcolors.h"
|
|
#include "MatSysWin.h"
|
|
#include "curveeditorhelpers.h"
|
|
#include "EdgeProperties.h"
|
|
|
|
SceneRampTool *g_pSceneRampTool = 0;
|
|
|
|
#define TRAY_HEIGHT 20
|
|
#define TRAY_ITEM_INSET 10
|
|
|
|
#define TAG_TOP ( TRAY_HEIGHT + 12 )
|
|
#define TAG_BOTTOM ( TAG_TOP + 20 )
|
|
|
|
#define MAX_TIME_ZOOM 1000
|
|
// 10% per step
|
|
#define TIME_ZOOM_STEP 2
|
|
|
|
SceneRampTool::SceneRampTool( mxWindow *parent )
|
|
: IFacePoserToolWindow( "SceneRampTool", "Scene Ramp" ), mxWindow( parent, 0, 0, 0, 0 )
|
|
{
|
|
m_pHelper = new CCurveEditorHelper< SceneRampTool >( this );
|
|
|
|
m_bSuppressLayout = false;
|
|
|
|
SetAutoProcess( true );
|
|
|
|
m_flScrub = 0.0f;
|
|
m_flScrubTarget = 0.0f;
|
|
m_nDragType = DRAGTYPE_NONE;
|
|
|
|
m_nClickedX = 0;
|
|
m_nClickedY = 0;
|
|
|
|
m_hPrevCursor = 0;
|
|
|
|
m_nStartX = 0;
|
|
m_nStartY = 0;
|
|
|
|
m_nMousePos[ 0 ] = m_nMousePos[ 1 ] = 0;
|
|
|
|
m_nMinX = 0;
|
|
m_nMaxX = 0;
|
|
m_bUseBounds = false;
|
|
|
|
m_bLayoutIsValid = false;
|
|
m_flPixelsPerSecond = 500.0f;
|
|
|
|
m_flLastDuration = 0.0f;
|
|
m_nScrollbarHeight = 12;
|
|
m_flLeftOffset = 0.0f;
|
|
m_nLastHPixelsNeeded = -1;
|
|
m_pHorzScrollBar = new mxScrollbar( this, 0, 0, 18, 100, IDC_SRT_RAMPHSCROLL, mxScrollbar::Horizontal );
|
|
m_pHorzScrollBar->setVisible( false );
|
|
|
|
m_flScrubberTimeOffset = 0.0f;
|
|
|
|
m_nUndoSetup = 0;
|
|
}
|
|
|
|
SceneRampTool::~SceneRampTool( void )
|
|
{
|
|
delete m_pHelper;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CChoreoScene *SceneRampTool::GetSafeScene( void )
|
|
{
|
|
if ( !g_pChoreoView )
|
|
return NULL;
|
|
|
|
CChoreoScene *scene = g_pChoreoView->GetScene();
|
|
if ( !scene )
|
|
return NULL;
|
|
|
|
return scene;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : rcHandle -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::GetScrubHandleRect( RECT& rcHandle, float scrub, bool clipped )
|
|
{
|
|
float pixel = 0.0f;
|
|
if ( w2() > 0 )
|
|
{
|
|
pixel = GetPixelForTimeValue( scrub );
|
|
|
|
if ( clipped )
|
|
{
|
|
pixel = clamp( pixel, SCRUBBER_HANDLE_WIDTH / 2, w2() - SCRUBBER_HANDLE_WIDTH / 2 );
|
|
}
|
|
}
|
|
|
|
rcHandle.left = pixel- SCRUBBER_HANDLE_WIDTH / 2;
|
|
rcHandle.right = pixel + SCRUBBER_HANDLE_WIDTH / 2;
|
|
rcHandle.top = 2 + GetCaptionHeight();
|
|
rcHandle.bottom = rcHandle.top + SCRUBBER_HANDLE_HEIGHT;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : drawHelper -
|
|
// rcHandle -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DrawScrubHandle( CChoreoWidgetDrawHelper& drawHelper, RECT& rcHandle, float scrub, bool reference )
|
|
{
|
|
HBRUSH br = CreateSolidBrush( ColorToRGB( reference ? Color( 150, 0, 0 ) : Color( 0, 150, 100 ) ) );
|
|
|
|
Color areaBorder = Color( 230, 230, 220 );
|
|
|
|
drawHelper.DrawColoredLine( areaBorder,
|
|
PS_SOLID, 1, 0, rcHandle.top, w2(), rcHandle.top );
|
|
drawHelper.DrawColoredLine( areaBorder,
|
|
PS_SOLID, 1, 0, rcHandle.bottom, w2(), rcHandle.bottom );
|
|
|
|
drawHelper.DrawFilledRect( br, rcHandle );
|
|
|
|
//
|
|
char sz[ 32 ];
|
|
sprintf( sz, "%.3f", scrub );
|
|
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( scene )
|
|
{
|
|
float st, ed;
|
|
st = 0.0f;
|
|
ed = scene->FindStopTime();
|
|
|
|
float dt = ed - st;
|
|
if ( dt > 0.0f )
|
|
{
|
|
sprintf( sz, "%.3f", st + scrub );
|
|
}
|
|
}
|
|
|
|
int len = drawHelper.CalcTextWidth( "Arial", 9, 500, sz );
|
|
|
|
RECT rcText = rcHandle;
|
|
|
|
int textw = rcText.right - rcText.left;
|
|
|
|
rcText.left += ( textw - len ) / 2;
|
|
|
|
drawHelper.DrawColoredText( "Arial", 9, 500, Color( 255, 255, 255 ), rcText, sz );
|
|
|
|
DeleteObject( br );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *event -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool SceneRampTool::IsMouseOverScrubHandle( mxEvent *event )
|
|
{
|
|
RECT rcHandle;
|
|
GetScrubHandleRect( rcHandle, m_flScrub, true );
|
|
InflateRect( &rcHandle, 2, 2 );
|
|
|
|
POINT pt;
|
|
pt.x = (short)event->x;
|
|
pt.y = (short)event->y;
|
|
if ( PtInRect( &rcHandle, pt ) )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool SceneRampTool::IsProcessing( void )
|
|
{
|
|
if ( !GetSafeScene() )
|
|
return false;
|
|
|
|
if ( m_flScrub != m_flScrubTarget )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool SceneRampTool::IsScrubbing( void ) const
|
|
{
|
|
bool scrubbing = ( m_nDragType == DRAGTYPE_SCRUBBER ) ? true : false;
|
|
return scrubbing;
|
|
}
|
|
|
|
void SceneRampTool::SetScrubTime( float t )
|
|
{
|
|
m_flScrub = t;
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( scene && scene->FindStopTime() )
|
|
{
|
|
float realtime = m_flScrub;
|
|
|
|
g_pChoreoView->SetScrubTime( realtime );
|
|
g_pChoreoView->DrawScrubHandle();
|
|
}
|
|
}
|
|
|
|
void SceneRampTool::SetScrubTargetTime( float t )
|
|
{
|
|
m_flScrubTarget = t;
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( scene && scene->FindStopTime() )
|
|
{
|
|
float realtime = m_flScrubTarget;
|
|
|
|
g_pChoreoView->SetScrubTargetTime( realtime );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : dt -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::Think( float dt )
|
|
{
|
|
if ( !GetSafeScene() )
|
|
return;
|
|
|
|
bool scrubbing = IsScrubbing();
|
|
ScrubThink( dt, scrubbing );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : dt -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::ScrubThink( float dt, bool scrubbing )
|
|
{
|
|
if ( !GetSafeScene() )
|
|
return;
|
|
|
|
if ( m_flScrubTarget == m_flScrub && !scrubbing )
|
|
return;
|
|
|
|
float d = m_flScrubTarget - m_flScrub;
|
|
int sign = d > 0.0f ? 1 : -1;
|
|
|
|
float maxmove = dt;
|
|
|
|
if ( sign > 0 )
|
|
{
|
|
if ( d < maxmove )
|
|
{
|
|
SetScrubTime( m_flScrubTarget );
|
|
}
|
|
else
|
|
{
|
|
SetScrubTime( m_flScrub + maxmove );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( -d < maxmove )
|
|
{
|
|
SetScrubTime( m_flScrubTarget );
|
|
}
|
|
else
|
|
{
|
|
SetScrubTime( m_flScrub - maxmove );
|
|
}
|
|
}
|
|
|
|
if ( scrubbing )
|
|
{
|
|
g_pMatSysWindow->Frame();
|
|
}
|
|
}
|
|
|
|
void SceneRampTool::DrawScrubHandles()
|
|
{
|
|
RECT rcTray;
|
|
|
|
RECT rcHandle;
|
|
GetScrubHandleRect( rcHandle, m_flScrub, true );
|
|
|
|
rcTray = rcHandle;
|
|
rcTray.left = 0;
|
|
rcTray.right = w2();
|
|
|
|
CChoreoWidgetDrawHelper drawHelper( this, rcTray );
|
|
DrawScrubHandle( drawHelper, rcHandle, m_flScrub, false );
|
|
}
|
|
|
|
void SceneRampTool::redraw()
|
|
{
|
|
if ( !ToolCanDraw() )
|
|
return;
|
|
|
|
CChoreoWidgetDrawHelper drawHelper( this );
|
|
HandleToolRedraw( drawHelper );
|
|
|
|
RECT rc;
|
|
drawHelper.GetClientRect( rc );
|
|
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( scene )
|
|
{
|
|
RECT rcText;
|
|
drawHelper.GetClientRect( rcText );
|
|
rcText.top += GetCaptionHeight()+1;
|
|
rcText.bottom = rcText.top + 13;
|
|
rcText.left += 5;
|
|
rcText.right -= 5;
|
|
|
|
OffsetRect( &rcText, 0, 12 );
|
|
|
|
int current, total;
|
|
|
|
g_pChoreoView->GetUndoLevels( current, total );
|
|
if ( total > 0 )
|
|
{
|
|
RECT rcUndo = rcText;
|
|
OffsetRect( &rcUndo, 0, 2 );
|
|
|
|
drawHelper.DrawColoredText( "Small Fonts", 8, FW_NORMAL, Color( 0, 100, 0 ), rcUndo,
|
|
"Undo: %i/%i", current, total );
|
|
}
|
|
|
|
rcText.left += 60;
|
|
|
|
// Found it, write out description
|
|
//
|
|
RECT rcTextLine = rcText;
|
|
|
|
drawHelper.DrawColoredText( "Arial", 11, 900, Color( 200, 0, 0 ), rcTextLine,
|
|
"Scene: %s",
|
|
g_pChoreoView->GetChoreoFile() );
|
|
|
|
RECT rcTimeLine;
|
|
drawHelper.GetClientRect( rcTimeLine );
|
|
rcTimeLine.left = 0;
|
|
rcTimeLine.right = w2();
|
|
rcTimeLine.top += ( GetCaptionHeight() + 50 );
|
|
|
|
float lefttime = GetTimeValueForMouse( 0 );
|
|
float righttime = GetTimeValueForMouse( w2() );
|
|
|
|
DrawTimeLine( drawHelper, rcTimeLine, lefttime, righttime );
|
|
|
|
OffsetRect( &rcText, 0, 28 );
|
|
|
|
rcText.left = 5;
|
|
|
|
RECT timeRect = rcText;
|
|
|
|
timeRect.right = timeRect.left + 100;
|
|
|
|
char sz[ 32 ];
|
|
|
|
Q_snprintf( sz, sizeof( sz ), "%.2f", lefttime );
|
|
|
|
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, Color( 0, 0, 0 ), timeRect, sz );
|
|
|
|
timeRect = rcText;
|
|
|
|
Q_snprintf( sz, sizeof( sz ), "%.2f", righttime );
|
|
|
|
int textW = drawHelper.CalcTextWidth( "Arial", 9, FW_NORMAL, sz );
|
|
|
|
timeRect.right = w2() - 10;
|
|
timeRect.left = timeRect.right - textW;
|
|
|
|
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, Color( 0, 0, 0 ), timeRect, sz );
|
|
}
|
|
|
|
RECT rcHandle;
|
|
GetScrubHandleRect( rcHandle, m_flScrub, true );
|
|
DrawScrubHandle( drawHelper, rcHandle, m_flScrub, false );
|
|
|
|
RECT rcSamples;
|
|
GetSampleTrayRect( rcSamples );
|
|
DrawSamples( drawHelper, rcSamples );
|
|
|
|
DrawSceneEnd( drawHelper );
|
|
|
|
RECT rcTags = rc;
|
|
rcTags.top = TAG_TOP + GetCaptionHeight();
|
|
rcTags.bottom = TAG_BOTTOM + GetCaptionHeight();
|
|
|
|
DrawTimingTags( drawHelper, rcTags );
|
|
|
|
RECT rcPos;
|
|
GetMouseOverPosRect( rcPos );
|
|
DrawMouseOverPos( drawHelper, rcPos );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::ShowContextMenu( mxEvent *event, bool include_track_menus )
|
|
{
|
|
// Construct main menu
|
|
mxPopupMenu *pop = new mxPopupMenu();
|
|
|
|
int current, total;
|
|
g_pChoreoView->GetUndoLevels( current, total );
|
|
if ( total > 0 )
|
|
{
|
|
if ( current > 0 )
|
|
{
|
|
pop->add( va( "Undo %s", g_pChoreoView->GetUndoDescription() ), IDC_UNDO_SRT );
|
|
}
|
|
|
|
if ( current <= total - 1 )
|
|
{
|
|
pop->add( va( "Redo %s", g_pChoreoView->GetRedoDescription() ), IDC_REDO_SRT );
|
|
}
|
|
pop->addSeparator();
|
|
}
|
|
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( scene )
|
|
{
|
|
if ( CountSelected() > 0 )
|
|
{
|
|
pop->add( va( "Delete" ), IDC_SRT_DELETE );
|
|
pop->add( "Deselect all", IDC_SRT_DESELECT );
|
|
}
|
|
pop->add( "Select all", IDC_SRT_SELECTALL );
|
|
}
|
|
|
|
pop->add( va( "Change scale..." ), IDC_SRT_CHANGESCALE );
|
|
pop->addSeparator();
|
|
pop->add( "Edge Properties...", IDC_SRT_EDGEPROPERTIES );
|
|
|
|
pop->popup( this, (short)event->x, (short)event->y );
|
|
}
|
|
|
|
void SceneRampTool::GetWorkspaceLeftRight( int& left, int& right )
|
|
{
|
|
left = 0;
|
|
right = w2();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DrawFocusRect( void )
|
|
{
|
|
HDC dc = GetDC( NULL );
|
|
|
|
for ( int i = 0; i < m_FocusRects.Count(); i++ )
|
|
{
|
|
RECT rc = m_FocusRects[ i ].m_rcFocus;
|
|
|
|
::DrawFocusRect( dc, &rc );
|
|
}
|
|
|
|
ReleaseDC( NULL, dc );
|
|
}
|
|
|
|
void SceneRampTool::SetClickedPos( int x, int y )
|
|
{
|
|
m_nClickedX = x;
|
|
m_nClickedY = y;
|
|
}
|
|
|
|
float SceneRampTool::GetTimeForClickedPos( void )
|
|
{
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( !scene )
|
|
return 0.0f;
|
|
|
|
float t = GetTimeValueForMouse( m_nClickedX );
|
|
return t;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : dragtype -
|
|
// startx -
|
|
// cursor -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::StartDragging( int dragtype, int startx, int starty, HCURSOR cursor )
|
|
{
|
|
m_nDragType = dragtype;
|
|
m_nStartX = startx;
|
|
m_nLastX = startx;
|
|
m_nStartY = starty;
|
|
m_nLastY = starty;
|
|
|
|
if ( m_hPrevCursor )
|
|
{
|
|
SetCursor( m_hPrevCursor );
|
|
m_hPrevCursor = NULL;
|
|
}
|
|
m_hPrevCursor = SetCursor( cursor );
|
|
|
|
m_FocusRects.Purge();
|
|
|
|
RECT rcStart;
|
|
rcStart.left = startx;
|
|
rcStart.right = startx;
|
|
|
|
bool addrect = true;
|
|
switch ( dragtype )
|
|
{
|
|
case DRAGTYPE_SCRUBBER:
|
|
{
|
|
RECT rcScrub;
|
|
GetScrubHandleRect( rcScrub, m_flScrub, true );
|
|
|
|
rcStart = rcScrub;
|
|
rcStart.left = ( rcScrub.left + rcScrub.right ) / 2;
|
|
rcStart.right = rcStart.left;
|
|
rcStart.top = rcScrub.bottom;
|
|
|
|
rcStart.bottom = h2();
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
rcStart.top = starty;
|
|
rcStart.bottom = starty;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
if ( addrect )
|
|
{
|
|
AddFocusRect( rcStart );
|
|
}
|
|
|
|
DrawFocusRect();
|
|
}
|
|
|
|
void SceneRampTool::OnMouseMove( mxEvent *event )
|
|
{
|
|
int mx = (short)event->x;
|
|
int my = (short)event->y;
|
|
|
|
event->x = (short)mx;
|
|
|
|
if ( m_nDragType != DRAGTYPE_NONE )
|
|
{
|
|
DrawFocusRect();
|
|
|
|
for ( int i = 0; i < m_FocusRects.Count(); i++ )
|
|
{
|
|
CFocusRect *f = &m_FocusRects[ i ];
|
|
f->m_rcFocus = f->m_rcOrig;
|
|
|
|
switch ( m_nDragType )
|
|
{
|
|
default:
|
|
{
|
|
OffsetRect( &f->m_rcFocus, ( mx - m_nStartX ), ( my - m_nStartY ) );
|
|
}
|
|
break;
|
|
case DRAGTYPE_SCRUBBER:
|
|
{
|
|
ApplyBounds( mx, my );
|
|
if ( w2() > 0 )
|
|
{
|
|
float t = GetTimeValueForMouse( mx );
|
|
t += m_flScrubberTimeOffset;
|
|
ForceScrubPosition( t );
|
|
}
|
|
|
|
OffsetRect( &f->m_rcFocus, ( mx - m_nStartX ), 0 );
|
|
}
|
|
break;
|
|
case DRAGTYPE_MOVEPOINTS_TIME:
|
|
case DRAGTYPE_MOVEPOINTS_VALUE:
|
|
{
|
|
int dx = mx - m_nLastX;
|
|
int dy = my - m_nLastY;
|
|
|
|
if ( !( event->modifiers & mxEvent::KeyCtrl ) )
|
|
{
|
|
// Zero out motion on other axis
|
|
if ( m_nDragType == DRAGTYPE_MOVEPOINTS_VALUE )
|
|
{
|
|
dx = 0;
|
|
mx = m_nLastX;
|
|
}
|
|
else
|
|
{
|
|
dy = 0;
|
|
my = m_nLastY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetCursor( LoadCursor( NULL, IDC_SIZEALL ) );
|
|
}
|
|
|
|
RECT rcSamples;
|
|
GetSampleTrayRect( rcSamples );
|
|
|
|
int height = rcSamples.bottom - rcSamples.top;
|
|
Assert( height > 0 );
|
|
|
|
float dfdx = (float)dx / GetPixelsPerSecond();
|
|
float dfdy = (float)dy / (float)height;
|
|
|
|
MoveSelectedSamples( dfdx, dfdy );
|
|
|
|
// Update the scrubber
|
|
if ( w2() > 0 )
|
|
{
|
|
float t = GetTimeValueForMouse( mx );
|
|
ForceScrubPosition( t );
|
|
g_pMatSysWindow->Frame();
|
|
}
|
|
|
|
OffsetRect( &f->m_rcFocus, dx, dy );
|
|
}
|
|
break;
|
|
case DRAGTYPE_SELECTION:
|
|
{
|
|
RECT rcFocus;
|
|
|
|
rcFocus.left = m_nStartX < m_nLastX ? m_nStartX : m_nLastX;
|
|
rcFocus.right = m_nStartX < m_nLastX ? m_nLastX : m_nStartX;
|
|
|
|
rcFocus.top = m_nStartY < m_nLastY ? m_nStartY : m_nLastY;
|
|
rcFocus.bottom = m_nStartY < m_nLastY ? m_nLastY : m_nStartY;
|
|
|
|
POINT offset;
|
|
offset.x = 0;
|
|
offset.y = 0;
|
|
ClientToScreen( (HWND)getHandle(), &offset );
|
|
OffsetRect( &rcFocus, offset.x, offset.y );
|
|
|
|
f->m_rcFocus = rcFocus;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
DrawFocusRect();
|
|
}
|
|
else
|
|
{
|
|
if ( m_hPrevCursor )
|
|
{
|
|
SetCursor( m_hPrevCursor );
|
|
m_hPrevCursor = NULL;
|
|
}
|
|
|
|
if ( IsMouseOverScrubHandle( event ) )
|
|
{
|
|
m_hPrevCursor = SetCursor( LoadCursor( NULL, IDC_SIZEWE ) );
|
|
}
|
|
/*
|
|
else if ( IsMouseOverTag( mx, my ) )
|
|
{
|
|
m_hPrevCursor = SetCursor( LoadCursor( NULL, IDC_SIZEWE ) );
|
|
}
|
|
*/
|
|
// See if anything is selected
|
|
if ( CountSelected() <= 0 )
|
|
{
|
|
// Nothing selected
|
|
// Draw auto highlight
|
|
DrawAutoHighlight( event );
|
|
}
|
|
}
|
|
|
|
m_nLastX = (short)event->x;
|
|
m_nLastY = (short)event->y;
|
|
}
|
|
|
|
int SceneRampTool::handleEvent( mxEvent *event )
|
|
{
|
|
MDLCACHE_CRITICAL_SECTION_( g_pMDLCache );
|
|
|
|
int iret = 0;
|
|
|
|
if ( HandleToolEvent( event ) )
|
|
{
|
|
return iret;
|
|
}
|
|
|
|
// Give helper a shot at the event
|
|
if ( m_pHelper->HelperHandleEvent( event ) )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
switch ( event->event )
|
|
{
|
|
case mxEvent::Size:
|
|
{
|
|
int w, h;
|
|
w = event->width;
|
|
h = event->height;
|
|
|
|
m_nLastHPixelsNeeded = 0;
|
|
InvalidateLayout();
|
|
iret = 1;
|
|
}
|
|
break;
|
|
case mxEvent::MouseWheeled:
|
|
{
|
|
CChoreoScene *scene = g_pChoreoView->GetScene();
|
|
if ( scene )
|
|
{
|
|
int tz = g_pChoreoView->GetTimeZoom( GetToolName() );
|
|
bool shiftdown = ( event->modifiers & mxEvent::KeyShift ) ? true : false;
|
|
int stepMultipiler = shiftdown ? 5 : 1;
|
|
|
|
// Zoom time in / out
|
|
if ( event->height > 0 )
|
|
{
|
|
tz = min( tz + TIME_ZOOM_STEP * stepMultipiler, MAX_TIME_ZOOM );
|
|
}
|
|
else
|
|
{
|
|
tz = max( tz - TIME_ZOOM_STEP * stepMultipiler, TIME_ZOOM_STEP );
|
|
}
|
|
|
|
g_pChoreoView->SetPreservedTimeZoom( this, tz );
|
|
}
|
|
redraw();
|
|
iret = 1;
|
|
}
|
|
break;
|
|
case mxEvent::MouseDown:
|
|
{
|
|
bool ctrldown = ( event->modifiers & mxEvent::KeyCtrl ) ? true : false;
|
|
bool shiftdown = ( event->modifiers & mxEvent::KeyShift ) ? true : false;
|
|
|
|
bool rightbutton = ( event->buttons & mxEvent::MouseRightButton ) ? true : false;
|
|
|
|
iret = 1;
|
|
|
|
int mx = (short)event->x;
|
|
int my = (short)event->y;
|
|
|
|
SetClickedPos( mx, my );
|
|
|
|
SetMouseOverPos( mx, my );
|
|
DrawMouseOverPos();
|
|
|
|
POINT pt;
|
|
pt.x = mx;
|
|
pt.y = my;
|
|
|
|
RECT rcSamples;
|
|
GetSampleTrayRect( rcSamples );
|
|
|
|
bool insamplearea = PtInRect( &rcSamples, pt ) ? true : false;
|
|
|
|
if ( m_nDragType == DRAGTYPE_NONE )
|
|
{
|
|
bool ctrlDown = ( event->modifiers & mxEvent::KeyCtrl ) ? true : false;
|
|
|
|
CExpressionSample *sample = GetSampleUnderMouse( event->x, event->y, ctrlDown ? FP_SRT_ADDSAMPLE_TOLERANCE : FP_SRT_SELECTION_TOLERANCE );
|
|
|
|
if ( IsMouseOverScrubHandle( event ) )
|
|
{
|
|
if ( w2() > 0 )
|
|
{
|
|
float t = GetTimeValueForMouse( (short)event->x );
|
|
m_flScrubberTimeOffset = m_flScrub - t;
|
|
float maxoffset = 0.5f * (float)SCRUBBER_HANDLE_WIDTH / GetPixelsPerSecond();
|
|
m_flScrubberTimeOffset = clamp( m_flScrubberTimeOffset, -maxoffset, maxoffset );
|
|
t += m_flScrubberTimeOffset;
|
|
ForceScrubPosition( t );
|
|
}
|
|
|
|
StartDragging( DRAGTYPE_SCRUBBER, m_nClickedX, m_nClickedY, LoadCursor( NULL, IDC_SIZEWE ) );
|
|
}
|
|
else if ( insamplearea )
|
|
{
|
|
if ( sample )
|
|
{
|
|
if ( shiftdown )
|
|
{
|
|
sample->selected = !sample->selected;
|
|
redraw();
|
|
}
|
|
else if ( sample->selected )
|
|
{
|
|
PreDataChanged( "move scene ramp points" );
|
|
|
|
StartDragging(
|
|
rightbutton ? DRAGTYPE_MOVEPOINTS_TIME : DRAGTYPE_MOVEPOINTS_VALUE,
|
|
m_nClickedX, m_nClickedY,
|
|
LoadCursor( NULL, rightbutton ? IDC_SIZEWE : IDC_SIZENS ) );
|
|
}
|
|
else
|
|
{
|
|
if ( !shiftdown )
|
|
{
|
|
DeselectAll();
|
|
}
|
|
|
|
StartDragging( DRAGTYPE_SELECTION, m_nClickedX, m_nClickedY, LoadCursor( NULL, IDC_ARROW ) );
|
|
}
|
|
}
|
|
else if ( ctrldown )
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( s )
|
|
{
|
|
// Add a sample point
|
|
float t = GetTimeValueForMouse( mx );
|
|
|
|
t = FacePoser_SnapTime( t );
|
|
float value = 1.0f - (float)( (short)event->y - rcSamples.top ) / (float)( rcSamples.bottom - rcSamples.top );
|
|
value = clamp( value, 0.0f, 1.0f );
|
|
|
|
PreDataChanged( "Add scene ramp point" );
|
|
|
|
s->AddSceneRamp( t, value, false );
|
|
|
|
s->ResortSceneRamp();
|
|
|
|
PostDataChanged( "Add scene ramp point" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( event->buttons & mxEvent::MouseRightButton )
|
|
{
|
|
ShowContextMenu( event, false );
|
|
iret = 1;
|
|
return iret;
|
|
}
|
|
else
|
|
{
|
|
if ( !shiftdown )
|
|
{
|
|
DeselectAll();
|
|
}
|
|
|
|
StartDragging( DRAGTYPE_SELECTION, m_nClickedX, m_nClickedY, LoadCursor( NULL, IDC_ARROW ) );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( event->buttons & mxEvent::MouseRightButton )
|
|
{
|
|
ShowContextMenu( event, false );
|
|
iret = 1;
|
|
return iret;
|
|
}
|
|
else
|
|
{
|
|
if ( w2() > 0 )
|
|
{
|
|
float t = GetTimeValueForMouse( (short)event->x );
|
|
|
|
SetScrubTargetTime( t );
|
|
}
|
|
}
|
|
}
|
|
|
|
CalcBounds( m_nDragType );
|
|
}
|
|
}
|
|
break;
|
|
case mxEvent::MouseDrag:
|
|
case mxEvent::MouseMove:
|
|
{
|
|
int mx = (short)event->x;
|
|
int my = (short)event->y;
|
|
|
|
SetMouseOverPos( mx, my );
|
|
DrawMouseOverPos();
|
|
|
|
OnMouseMove( event );
|
|
|
|
iret = 1;
|
|
}
|
|
break;
|
|
case mxEvent::MouseUp:
|
|
{
|
|
OnMouseMove( event );
|
|
|
|
int mx = (short)event->x;
|
|
int my = (short)event->y;
|
|
|
|
if ( m_nDragType != DRAGTYPE_NONE )
|
|
{
|
|
DrawFocusRect();
|
|
}
|
|
|
|
if ( m_hPrevCursor )
|
|
{
|
|
SetCursor( m_hPrevCursor );
|
|
m_hPrevCursor = 0;
|
|
}
|
|
|
|
switch ( m_nDragType )
|
|
{
|
|
case DRAGTYPE_NONE:
|
|
break;
|
|
case DRAGTYPE_SCRUBBER:
|
|
{
|
|
ApplyBounds( mx, my );
|
|
|
|
if ( w2() > 0 )
|
|
{
|
|
float t = GetTimeValueForMouse( (short)event->x );
|
|
t += m_flScrubberTimeOffset;
|
|
ForceScrubPosition( t );
|
|
m_flScrubberTimeOffset = 0.0f;
|
|
}
|
|
}
|
|
break;
|
|
case DRAGTYPE_MOVEPOINTS_VALUE:
|
|
case DRAGTYPE_MOVEPOINTS_TIME:
|
|
{
|
|
PostDataChanged( "move ramp points" );
|
|
}
|
|
break;
|
|
case DRAGTYPE_SELECTION:
|
|
{
|
|
SelectPoints();
|
|
}
|
|
break;
|
|
}
|
|
|
|
m_nDragType = DRAGTYPE_NONE;
|
|
|
|
SetMouseOverPos( mx, my );
|
|
DrawMouseOverPos();
|
|
|
|
redraw();
|
|
|
|
iret = 1;
|
|
}
|
|
break;
|
|
case mxEvent::Action:
|
|
{
|
|
iret = 1;
|
|
switch ( event->action )
|
|
{
|
|
default:
|
|
iret = 0;
|
|
break;
|
|
case IDC_UNDO_SRT:
|
|
{
|
|
OnUndo();
|
|
}
|
|
break;
|
|
case IDC_REDO_SRT:
|
|
{
|
|
OnRedo();
|
|
}
|
|
break;
|
|
case IDC_SRT_DELETE:
|
|
{
|
|
Delete();
|
|
}
|
|
break;
|
|
case IDC_SRT_DESELECT:
|
|
{
|
|
DeselectAll();
|
|
}
|
|
break;
|
|
case IDC_SRT_SELECTALL:
|
|
{
|
|
SelectAll();
|
|
}
|
|
break;
|
|
case IDC_SRT_RAMPHSCROLL:
|
|
{
|
|
int offset = 0;
|
|
bool processed = true;
|
|
|
|
switch ( event->modifiers )
|
|
{
|
|
case SB_THUMBTRACK:
|
|
offset = event->height;
|
|
break;
|
|
case SB_PAGEUP:
|
|
offset = m_pHorzScrollBar->getValue();
|
|
offset -= 20;
|
|
offset = max( offset, m_pHorzScrollBar->getMinValue() );
|
|
break;
|
|
case SB_PAGEDOWN:
|
|
offset = m_pHorzScrollBar->getValue();
|
|
offset += 20;
|
|
offset = min( offset, m_pHorzScrollBar->getMaxValue() );
|
|
break;
|
|
case SB_LINEUP:
|
|
offset = m_pHorzScrollBar->getValue();
|
|
offset -= 10;
|
|
offset = max( offset, m_pHorzScrollBar->getMinValue() );
|
|
break;
|
|
case SB_LINEDOWN:
|
|
offset = m_pHorzScrollBar->getValue();
|
|
offset += 10;
|
|
offset = min( offset, m_pHorzScrollBar->getMaxValue() );
|
|
break;
|
|
default:
|
|
processed = false;
|
|
break;
|
|
}
|
|
|
|
if ( processed )
|
|
{
|
|
MoveTimeSliderToPos( offset );
|
|
}
|
|
}
|
|
break;
|
|
case IDC_SRT_CHANGESCALE:
|
|
{
|
|
OnChangeScale();
|
|
}
|
|
break;
|
|
case IDC_SRT_EDGEPROPERTIES:
|
|
{
|
|
OnEdgeProperties();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case mxEvent::KeyDown:
|
|
{
|
|
iret = 1;
|
|
switch ( event->key )
|
|
{
|
|
default:
|
|
iret = g_pChoreoView->HandleZoomKey( this, event->key );
|
|
break;
|
|
case VK_ESCAPE:
|
|
DeselectAll();
|
|
break;
|
|
case VK_DELETE:
|
|
Delete();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return iret;
|
|
}
|
|
|
|
void SceneRampTool::ApplyBounds( int& mx, int& my )
|
|
{
|
|
if ( !m_bUseBounds )
|
|
return;
|
|
|
|
mx = clamp( mx, m_nMinX, m_nMaxX );
|
|
}
|
|
|
|
void SceneRampTool::CalcBounds( int movetype )
|
|
{
|
|
switch ( movetype )
|
|
{
|
|
default:
|
|
case DRAGTYPE_NONE:
|
|
{
|
|
m_bUseBounds = false;
|
|
m_nMinX = 0;
|
|
m_nMaxX = 0;
|
|
}
|
|
break;
|
|
case DRAGTYPE_SCRUBBER:
|
|
{
|
|
m_bUseBounds = true;
|
|
m_nMinX = 0;
|
|
m_nMaxX = w2();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool SceneRampTool::PaintBackground()
|
|
{
|
|
redraw();
|
|
return false;
|
|
}
|
|
|
|
void SceneRampTool::OnUndo( void )
|
|
{
|
|
g_pChoreoView->Undo();
|
|
}
|
|
|
|
void SceneRampTool::OnRedo( void )
|
|
{
|
|
g_pChoreoView->Redo();
|
|
}
|
|
|
|
void SceneRampTool::ForceScrubPositionFromSceneTime( float scenetime )
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s || !s->FindStopTime() )
|
|
return;
|
|
|
|
float t = scenetime;
|
|
m_flScrub = t;
|
|
m_flScrubTarget = t;
|
|
DrawScrubHandles();
|
|
}
|
|
|
|
void SceneRampTool::ForceScrubPosition( float t )
|
|
{
|
|
m_flScrub = t;
|
|
m_flScrubTarget = t;
|
|
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( s && s->FindStopTime() )
|
|
{
|
|
float realtime = t;
|
|
|
|
g_pChoreoView->SetScrubTime( realtime );
|
|
g_pChoreoView->SetScrubTargetTime( realtime );
|
|
|
|
g_pChoreoView->DrawScrubHandle();
|
|
}
|
|
|
|
DrawScrubHandles();
|
|
}
|
|
|
|
void SceneRampTool::SetMouseOverPos( int x, int y )
|
|
{
|
|
m_nMousePos[ 0 ] = x;
|
|
m_nMousePos[ 1 ] = y;
|
|
}
|
|
|
|
void SceneRampTool::GetMouseOverPos( int &x, int& y )
|
|
{
|
|
x = m_nMousePos[ 0 ];
|
|
y = m_nMousePos[ 1 ];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : rcPos -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::GetMouseOverPosRect( RECT& rcPos )
|
|
{
|
|
rcPos.top = GetCaptionHeight() + 12;
|
|
rcPos.left = w2() - 200;
|
|
rcPos.right = w2() - 5;
|
|
rcPos.bottom = rcPos.top + 13;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : drawHelper -
|
|
// rcPos -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DrawMouseOverPos( CChoreoWidgetDrawHelper& drawHelper, RECT& rcPos )
|
|
{
|
|
// Compute time for pixel x
|
|
float t = GetTimeValueForMouse( m_nMousePos[ 0 ] );
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
float snapped = FacePoser_SnapTime( t );
|
|
|
|
// Found it, write out description
|
|
//
|
|
char sz[ 128 ];
|
|
if ( t != snapped )
|
|
{
|
|
Q_snprintf( sz, sizeof( sz ), "%s", FacePoser_DescribeSnappedTime( t ) );
|
|
}
|
|
else
|
|
{
|
|
Q_snprintf( sz, sizeof( sz ), "%.3f", t );
|
|
}
|
|
|
|
int len = drawHelper.CalcTextWidth( "Arial", 11, 900, sz );
|
|
|
|
RECT rcText = rcPos;
|
|
rcText.left = max( rcPos.left, rcPos.right - len );
|
|
|
|
drawHelper.DrawColoredText( "Arial", 11, 900, Color( 255, 50, 70 ), rcText, sz );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DrawMouseOverPos()
|
|
{
|
|
RECT rcPos;
|
|
GetMouseOverPosRect( rcPos );
|
|
|
|
CChoreoWidgetDrawHelper drawHelper( this, rcPos );
|
|
DrawMouseOverPos( drawHelper, rcPos );
|
|
}
|
|
|
|
void SceneRampTool::AddFocusRect( RECT& rc )
|
|
{
|
|
RECT rcFocus = rc;
|
|
|
|
POINT offset;
|
|
offset.x = 0;
|
|
offset.y = 0;
|
|
ClientToScreen( (HWND)getHandle(), &offset );
|
|
OffsetRect( &rcFocus, offset.x, offset.y );
|
|
|
|
// Convert to screen space?
|
|
CFocusRect fr;
|
|
fr.m_rcFocus = rcFocus;
|
|
fr.m_rcOrig = rcFocus;
|
|
|
|
m_FocusRects.AddToTail( fr );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : drawHelper -
|
|
// rc -
|
|
// left -
|
|
// right -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DrawTimeLine( CChoreoWidgetDrawHelper& drawHelper, RECT& rc, float left, float right )
|
|
{
|
|
RECT rcLabel;
|
|
float granularity = 0.5f;
|
|
|
|
drawHelper.DrawColoredLine( Color( 150, 150, 200 ), PS_SOLID, 1, rc.left, rc.top + 2, rc.right, rc.top + 2 );
|
|
|
|
float f = SnapTime( left, granularity );
|
|
while ( f < right )
|
|
{
|
|
float frac = ( f - left ) / ( right - left );
|
|
if ( frac >= 0.0f && frac <= 1.0f )
|
|
{
|
|
rcLabel.left = GetPixelForTimeValue( f );
|
|
rcLabel.top = rc.top + 5;
|
|
rcLabel.bottom = rcLabel.top + 10;
|
|
|
|
if ( f != left )
|
|
{
|
|
drawHelper.DrawColoredLine( Color( 220, 220, 240 ), PS_DOT, 1,
|
|
rcLabel.left, rc.top, rcLabel.left, h2() );
|
|
}
|
|
|
|
char sz[ 32 ];
|
|
sprintf( sz, "%.2f", f );
|
|
|
|
int textWidth = drawHelper.CalcTextWidth( "Arial", 9, FW_NORMAL, sz );
|
|
|
|
rcLabel.right = rcLabel.left + textWidth;
|
|
|
|
OffsetRect( &rcLabel, -textWidth / 2, 0 );
|
|
|
|
RECT rcOut = rcLabel;
|
|
if ( rcOut.left <= 0 )
|
|
{
|
|
OffsetRect( &rcOut, -rcOut.left + 2, 0 );
|
|
}
|
|
|
|
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, Color( 0, 50, 150 ), rcOut, sz );
|
|
|
|
}
|
|
f += granularity;
|
|
}
|
|
}
|
|
|
|
void SceneRampTool::DrawTimingTags( CChoreoWidgetDrawHelper& drawHelper, RECT& rc )
|
|
{
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( !scene )
|
|
return;
|
|
|
|
float starttime = GetTimeValueForMouse( 0 );
|
|
float endtime = GetTimeValueForMouse( w2() );
|
|
|
|
if ( endtime - starttime <= 0.0f )
|
|
return;
|
|
|
|
RECT rcText = rc;
|
|
rcText.bottom = rcText.top + 10;
|
|
|
|
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, Color( 0, 100, 200 ), rcText, "Timing Tags:" );
|
|
|
|
// Loop through all events in scene
|
|
|
|
int c = scene->GetNumEvents();
|
|
int i;
|
|
for ( i = 0; i < c; i++ )
|
|
{
|
|
CChoreoEvent *e = scene->GetEvent( i );
|
|
if ( !e )
|
|
continue;
|
|
|
|
// See if time overlaps
|
|
if ( !e->HasEndTime() )
|
|
continue;
|
|
|
|
if ( e->GetEndTime() < starttime )
|
|
continue;
|
|
|
|
if ( e->GetStartTime() > endtime )
|
|
continue;
|
|
|
|
if ( e->GetNumRelativeTags() > 0 )
|
|
{
|
|
DrawRelativeTagsForEvent( drawHelper, rc, e, starttime, endtime );
|
|
}
|
|
if ( e->GetNumAbsoluteTags( CChoreoEvent::PLAYBACK ) > 0 )
|
|
{
|
|
DrawAbsoluteTagsForEvent( drawHelper, rc, e, starttime, endtime );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : drawHelper -
|
|
// &rc -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DrawAbsoluteTagsForEvent( CChoreoWidgetDrawHelper& drawHelper, RECT &rc, CChoreoEvent *event, float starttime, float endtime )
|
|
{
|
|
if ( !event )
|
|
return;
|
|
|
|
for ( int i = 0; i < event->GetNumAbsoluteTags( CChoreoEvent::PLAYBACK ); i++ )
|
|
{
|
|
CEventAbsoluteTag *tag = event->GetAbsoluteTag( CChoreoEvent::PLAYBACK, i );
|
|
if ( !tag )
|
|
continue;
|
|
|
|
float tagtime = ( event->GetStartTime() + tag->GetPercentage() * event->GetDuration() );
|
|
if ( tagtime < starttime || tagtime > endtime )
|
|
continue;
|
|
|
|
bool clipped = false;
|
|
int left = GetPixelForTimeValue( tagtime, &clipped );
|
|
if ( clipped )
|
|
continue;
|
|
|
|
if ( event->GetType() == CChoreoEvent::GESTURE )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Color clr = Color( 0, 100, 250 );
|
|
|
|
RECT rcMark;
|
|
rcMark = rc;
|
|
rcMark.top = rc.bottom - 8;
|
|
rcMark.bottom = rc.bottom;
|
|
rcMark.left = left - 4;
|
|
rcMark.right = left + 4;
|
|
|
|
drawHelper.DrawTriangleMarker( rcMark, clr );
|
|
|
|
RECT rcText;
|
|
rcText = rcMark;
|
|
rcText.top -= 12;
|
|
|
|
int len = drawHelper.CalcTextWidth( "Arial", 9, FW_NORMAL, tag->GetName() );
|
|
rcText.left = left - len / 2;
|
|
rcText.right = rcText.left + len + 2;
|
|
|
|
rcText.bottom = rcText.top + 10;
|
|
|
|
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, clr, rcText, tag->GetName() );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : drawHelper -
|
|
// rc -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DrawRelativeTagsForEvent( CChoreoWidgetDrawHelper& drawHelper, RECT& rc, CChoreoEvent *event, float starttime, float endtime )
|
|
{
|
|
if ( !event )
|
|
return;
|
|
|
|
//drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, PEColor( COLOR_PHONEME_TIMING_TAG ), rc, "Timing Tags:" );
|
|
|
|
for ( int i = 0; i < event->GetNumRelativeTags(); i++ )
|
|
{
|
|
CEventRelativeTag *tag = event->GetRelativeTag( i );
|
|
if ( !tag )
|
|
continue;
|
|
|
|
//
|
|
float tagtime = ( event->GetStartTime() + tag->GetPercentage() * event->GetDuration() );
|
|
if ( tagtime < starttime || tagtime > endtime )
|
|
continue;
|
|
|
|
bool clipped = false;
|
|
int left = GetPixelForTimeValue( tagtime, &clipped );
|
|
if ( clipped )
|
|
continue;
|
|
|
|
//float frac = ( tagtime - starttime ) / ( endtime - starttime );
|
|
|
|
//int left = rc.left + (int)( frac * ( float )( rc.right - rc.left ) + 0.5f );
|
|
|
|
Color clr = Color( 100, 100, 100 );
|
|
|
|
RECT rcMark;
|
|
rcMark = rc;
|
|
rcMark.top = rc.bottom - 8;
|
|
rcMark.bottom = rc.bottom;
|
|
rcMark.left = left - 4;
|
|
rcMark.right = left + 4;
|
|
|
|
drawHelper.DrawTriangleMarker( rcMark, clr );
|
|
|
|
RECT rcText;
|
|
rcText = rc;
|
|
rcText.bottom = rc.bottom - 10;
|
|
rcText.top = rcText.bottom - 10;
|
|
|
|
int len = drawHelper.CalcTextWidth( "Arial", 9, FW_NORMAL, tag->GetName() );
|
|
rcText.left = left - len / 2;
|
|
rcText.right = rcText.left + len + 2;
|
|
|
|
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, clr, rcText, tag->GetName() );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : int
|
|
//-----------------------------------------------------------------------------
|
|
int SceneRampTool::ComputeHPixelsNeeded( void )
|
|
{
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( !scene )
|
|
return 0;
|
|
|
|
int pixels = 0;
|
|
float maxtime = scene->FindStopTime();
|
|
pixels = (int)( ( maxtime ) * GetPixelsPerSecond() + 10 );
|
|
|
|
return pixels;
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::RepositionHSlider( void )
|
|
{
|
|
int pixelsneeded = ComputeHPixelsNeeded();
|
|
|
|
if ( pixelsneeded <= w2() )
|
|
{
|
|
m_pHorzScrollBar->setVisible( false );
|
|
}
|
|
else
|
|
{
|
|
m_pHorzScrollBar->setVisible( true );
|
|
}
|
|
m_pHorzScrollBar->setBounds( 0, h2() - m_nScrollbarHeight, w2() - m_nScrollbarHeight, m_nScrollbarHeight );
|
|
|
|
m_flLeftOffset = max( 0, m_flLeftOffset );
|
|
m_flLeftOffset = min( (float)pixelsneeded, m_flLeftOffset );
|
|
|
|
m_pHorzScrollBar->setRange( 0, pixelsneeded );
|
|
m_pHorzScrollBar->setValue( (int)m_flLeftOffset );
|
|
m_pHorzScrollBar->setPagesize( w2() );
|
|
|
|
m_nLastHPixelsNeeded = pixelsneeded;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : float
|
|
//-----------------------------------------------------------------------------
|
|
float SceneRampTool::GetPixelsPerSecond( void )
|
|
{
|
|
return m_flPixelsPerSecond * (float)g_pChoreoView->GetTimeZoom( GetToolName() )/100.0f;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : x -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::MoveTimeSliderToPos( int x )
|
|
{
|
|
m_flLeftOffset = (float)x;
|
|
m_pHorzScrollBar->setValue( (int)m_flLeftOffset );
|
|
InvalidateRect( (HWND)m_pHorzScrollBar->getHandle(), NULL, TRUE );
|
|
InvalidateLayout();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::InvalidateLayout( void )
|
|
{
|
|
if ( m_bSuppressLayout )
|
|
return;
|
|
|
|
if ( ComputeHPixelsNeeded() != m_nLastHPixelsNeeded )
|
|
{
|
|
RepositionHSlider();
|
|
}
|
|
|
|
m_bLayoutIsValid = false;
|
|
redraw();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : st -
|
|
// ed -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::GetStartAndEndTime( float& st, float& ed )
|
|
{
|
|
st = m_flLeftOffset / GetPixelsPerSecond();
|
|
ed = st + (float)w2() / GetPixelsPerSecond();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : -
|
|
// Output : float
|
|
//-----------------------------------------------------------------------------
|
|
float SceneRampTool::GetEventEndTime()
|
|
{
|
|
CChoreoScene *scene = GetSafeScene();
|
|
if ( !scene )
|
|
return 1.0f;
|
|
|
|
return scene->FindStopTime();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : time -
|
|
// *clipped -
|
|
// Output : int
|
|
//-----------------------------------------------------------------------------
|
|
int SceneRampTool::GetPixelForTimeValue( float time, bool *clipped /*=NULL*/ )
|
|
{
|
|
if ( clipped )
|
|
{
|
|
*clipped = false;
|
|
}
|
|
|
|
float st, ed;
|
|
GetStartAndEndTime( st, ed );
|
|
|
|
float frac = ( time - st ) / ( ed - st );
|
|
if ( frac < 0.0 || frac > 1.0 )
|
|
{
|
|
if ( clipped )
|
|
{
|
|
*clipped = true;
|
|
}
|
|
}
|
|
|
|
int pixel = ( int )( frac * w2() );
|
|
return pixel;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : mx -
|
|
// clip -
|
|
// Output : float
|
|
//-----------------------------------------------------------------------------
|
|
float SceneRampTool::GetTimeValueForMouse( int mx, bool clip /*=false*/)
|
|
{
|
|
float st, ed;
|
|
GetStartAndEndTime( st, ed );
|
|
|
|
if ( clip )
|
|
{
|
|
if ( mx < 0 )
|
|
{
|
|
return st;
|
|
}
|
|
if ( mx > w2() )
|
|
{
|
|
return ed;
|
|
}
|
|
}
|
|
|
|
float frac = (float)( mx ) / (float)( w2() );
|
|
return st + frac * ( ed - st );
|
|
}
|
|
|
|
void SceneRampTool::OnChangeScale( void )
|
|
{
|
|
CChoreoScene *scene = g_pChoreoView->GetScene();
|
|
if ( !scene )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Zoom time in / out
|
|
CInputParams params;
|
|
memset( ¶ms, 0, sizeof( params ) );
|
|
|
|
strcpy( params.m_szDialogTitle, "Change Zoom" );
|
|
strcpy( params.m_szPrompt, "New scale (e.g., 2.5x):" );
|
|
|
|
Q_snprintf( params.m_szInputText, sizeof( params.m_szInputText ), "%.2f", (float)g_pChoreoView->GetTimeZoom( GetToolName() ) / 100.0f );
|
|
|
|
if ( !InputProperties( ¶ms ) )
|
|
return;
|
|
|
|
g_pChoreoView->SetTimeZoom( GetToolName(), clamp( (int)( 100.0f * atof( params.m_szInputText ) ), 1, MAX_TIME_ZOOM ), false );
|
|
|
|
m_nLastHPixelsNeeded = -1;
|
|
m_flLeftOffset= 0.0f;
|
|
InvalidateLayout();
|
|
Con_Printf( "Zoom factor %i %%\n", g_pChoreoView->GetTimeZoom( GetToolName() ) );
|
|
}
|
|
|
|
void SceneRampTool::DrawSceneEnd( CChoreoWidgetDrawHelper& drawHelper )
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
float duration = s->FindStopTime();
|
|
if ( !duration )
|
|
return;
|
|
|
|
int leftx = GetPixelForTimeValue( duration );
|
|
if ( leftx >= w2() )
|
|
return;
|
|
|
|
RECT rcSample;
|
|
GetSampleTrayRect( rcSample );
|
|
|
|
drawHelper.DrawColoredLine(
|
|
COLOR_CHOREO_ENDTIME, PS_SOLID, 1,
|
|
leftx, rcSample.top, leftx, rcSample.bottom );
|
|
}
|
|
|
|
void SceneRampTool::GetSampleTrayRect( RECT& rc )
|
|
{
|
|
rc.left = 0;
|
|
rc.right = w2();
|
|
rc.top = GetCaptionHeight() + 65;
|
|
|
|
rc.bottom = h2() - m_nScrollbarHeight-2;
|
|
}
|
|
|
|
void SceneRampTool::DrawSamplesSimple( CChoreoWidgetDrawHelper& drawHelper, CChoreoScene *scene, bool clearbackground, const Color& sampleColor, RECT &rcSamples )
|
|
{
|
|
if ( clearbackground )
|
|
{
|
|
drawHelper.DrawFilledRect( Color( 230, 230, 215 ), rcSamples );
|
|
}
|
|
|
|
if ( !scene )
|
|
return;
|
|
|
|
float starttime = 0.0f;
|
|
float endtime = scene->FindStopTime();
|
|
|
|
Color lineColor = sampleColor;
|
|
|
|
int width = rcSamples.right - rcSamples.left;
|
|
if ( width <= 0.0f )
|
|
return;
|
|
|
|
int height = rcSamples.bottom - rcSamples.top;
|
|
int bottom = rcSamples.bottom;
|
|
|
|
float timestepperpixel = endtime / (float)width;
|
|
|
|
float prev_value = scene->GetSceneRampIntensity( starttime );
|
|
int prev_x = rcSamples.left;
|
|
float prev_t = 0.0f;
|
|
|
|
for ( float x = rcSamples.left; x < rcSamples.right; x+=3 )
|
|
{
|
|
float t = (float)( x - rcSamples.left ) * timestepperpixel;
|
|
|
|
float value = scene->GetSceneRampIntensity( starttime + t );
|
|
|
|
// Draw segment
|
|
drawHelper.DrawColoredLine( lineColor, PS_SOLID, 1,
|
|
prev_x, bottom - prev_value * height,
|
|
x, bottom - value * height );
|
|
|
|
prev_x = x;
|
|
prev_t = t;
|
|
prev_value = value;
|
|
}
|
|
}
|
|
|
|
void SceneRampTool::DrawSamples( CChoreoWidgetDrawHelper& drawHelper, RECT &rcSamples )
|
|
{
|
|
drawHelper.DrawFilledRect( Color( 230, 230, 215 ), rcSamples );
|
|
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
int rampCount = s->GetSceneRampCount();
|
|
if ( !rampCount )
|
|
return;
|
|
|
|
float starttime;
|
|
float endtime;
|
|
|
|
GetStartAndEndTime( starttime, endtime );
|
|
|
|
Color lineColor = Color( 0, 0, 255 );
|
|
Color dotColor = Color( 0, 0, 255 );
|
|
Color dotColorSelected = Color( 240, 80, 20 );
|
|
Color shadowColor = Color( 150, 150, 250 );
|
|
|
|
int height = rcSamples.bottom - rcSamples.top;
|
|
int bottom = rcSamples.bottom;
|
|
int top = rcSamples.top;
|
|
|
|
float timestepperpixel = 1.0f / GetPixelsPerSecond();
|
|
|
|
float stoptime = min( endtime, s->FindStopTime() );
|
|
|
|
float prev_t = starttime;
|
|
float prev_value = s->GetSceneRampIntensity( prev_t );
|
|
|
|
for ( float t = starttime-timestepperpixel; t <= stoptime; t += timestepperpixel )
|
|
{
|
|
float value = s->GetSceneRampIntensity( t );
|
|
|
|
int prevx, x;
|
|
|
|
bool clipped1, clipped2;
|
|
x = GetPixelForTimeValue( t, &clipped1 );
|
|
prevx = GetPixelForTimeValue( prev_t, &clipped2 );
|
|
|
|
if ( !clipped1 && !clipped2 )
|
|
{
|
|
// Draw segment
|
|
drawHelper.DrawColoredLine( lineColor, PS_SOLID, 1,
|
|
prevx, clamp( bottom - prev_value * height, top, bottom ),
|
|
x, clamp( bottom - value * height, top, bottom ) );
|
|
}
|
|
|
|
prev_t = t;
|
|
prev_value = value;
|
|
|
|
}
|
|
|
|
for ( int sample = 0; sample < rampCount; sample++ )
|
|
{
|
|
CExpressionSample *start = s->GetSceneRamp( sample );
|
|
|
|
/*
|
|
int pixel = (int)( ( start->time / event_time ) * width + 0.5f);
|
|
int x = m_rcBounds.left + pixel;
|
|
float roundedfrac = (float)pixel / (float)width;
|
|
*/
|
|
float value = start->value;
|
|
bool clipped = false;
|
|
int x = GetPixelForTimeValue( start->time, &clipped );
|
|
if ( clipped )
|
|
continue;
|
|
int y = bottom - value * height;
|
|
|
|
int dotsize = 6;
|
|
int dotSizeSelected = 6;
|
|
|
|
Color clr = dotColor;
|
|
Color clrSelected = dotColorSelected;
|
|
|
|
drawHelper.DrawCircle(
|
|
start->selected ? clrSelected : clr,
|
|
x, y,
|
|
start->selected ? dotSizeSelected : dotsize,
|
|
true );
|
|
|
|
if ( !start->selected )
|
|
continue;
|
|
|
|
if ( start->GetCurveType() == CURVE_DEFAULT )
|
|
continue;
|
|
|
|
// Draw curve type indicator...
|
|
char sz[ 128 ];
|
|
Q_snprintf( sz, sizeof( sz ), "%s", Interpolator_NameForCurveType( start->GetCurveType(), true ) );
|
|
RECT rc;
|
|
int fontSize = 9;
|
|
rc.top = clamp( y + 5, rcSamples.top + 2, rcSamples.bottom - 2 - fontSize );
|
|
rc.bottom = rc.top + fontSize + 1;
|
|
rc.left = x - 75;
|
|
rc.right = x + 175;
|
|
drawHelper.DrawColoredText( "Arial", fontSize, 500, shadowColor, rc, sz );
|
|
}
|
|
}
|
|
|
|
void SceneRampTool::DrawAutoHighlight( mxEvent *event )
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
CExpressionSample *hover = GetSampleUnderMouse( event->x, event->y, 0.0f );
|
|
RECT rcSamples;
|
|
GetSampleTrayRect( rcSamples );
|
|
|
|
CChoreoWidgetDrawHelper drawHelper( this, rcSamples, true );
|
|
|
|
RECT rcClient = rcSamples;
|
|
|
|
Color dotColor = Color( 0, 0, 255 );
|
|
Color dotColorSelected = Color( 240, 80, 20 );
|
|
Color clrHighlighted = Color( 0, 200, 0 );
|
|
|
|
int height = rcClient.bottom - rcClient.top;
|
|
int bottom = rcClient.bottom;
|
|
|
|
int dotsize = 6;
|
|
int dotSizeSelected = 6;
|
|
int dotSizeHighlighted = 6;
|
|
|
|
Color clr = dotColor;
|
|
Color clrSelected = dotColorSelected;
|
|
Color bgColor = Color( 230, 230, 200 );
|
|
|
|
// Fixme, could look at 1st derivative and do more sampling at high rate of change?
|
|
// or near actual sample points!
|
|
int sampleCount = s->GetSceneRampCount();
|
|
for ( int sample = 0; sample < sampleCount; sample++ )
|
|
{
|
|
CExpressionSample *start = s->GetSceneRamp( sample );
|
|
|
|
float value = start->value;
|
|
bool clipped = false;
|
|
int x = GetPixelForTimeValue( start->time, &clipped );
|
|
if ( clipped )
|
|
continue;
|
|
int y = bottom - value * height;
|
|
|
|
if ( hover == start )
|
|
{
|
|
drawHelper.DrawCircle(
|
|
bgColor,
|
|
x, y,
|
|
dotSizeHighlighted,
|
|
true );
|
|
|
|
drawHelper.DrawCircle(
|
|
clrHighlighted,
|
|
x, y,
|
|
dotSizeHighlighted,
|
|
false );
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
drawHelper.DrawCircle(
|
|
start->selected ? clrSelected : clr,
|
|
x, y,
|
|
start->selected ? dotSizeSelected : dotsize,
|
|
true );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int SceneRampTool::NumSamples()
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return 0;
|
|
|
|
return s->GetSceneRampCount();
|
|
}
|
|
|
|
CExpressionSample *SceneRampTool::GetSample( int idx )
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return NULL;
|
|
|
|
return s->GetSceneRamp( idx );
|
|
}
|
|
|
|
CExpressionSample *SceneRampTool::GetSampleUnderMouse( int mx, int my, float tolerance /*= FP_SRT_SELECTION_TOLERANCE*/ )
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return NULL;
|
|
|
|
RECT rcSamples;
|
|
GetSampleTrayRect( rcSamples );
|
|
|
|
POINT pt;
|
|
pt.x = mx;
|
|
pt.y = my;
|
|
|
|
if ( !PtInRect( &rcSamples, pt ) )
|
|
return NULL;
|
|
|
|
pt.y -= rcSamples.top;
|
|
|
|
float closest_dist = 9999999.f;
|
|
CExpressionSample *bestsample = NULL;
|
|
|
|
int height = rcSamples.bottom - rcSamples.top;
|
|
|
|
for ( int i = 0; i < s->GetSceneRampCount(); i++ )
|
|
{
|
|
CExpressionSample *sample = s->GetSceneRamp( i );
|
|
Assert( sample );
|
|
|
|
bool clipped = false;
|
|
int px = GetPixelForTimeValue( sample->time, &clipped );
|
|
int py = height * ( 1.0f - sample->value );
|
|
|
|
int dx = px - pt.x;
|
|
int dy = py - pt.y;
|
|
|
|
float dist = sqrt( (float)(dx * dx + dy * dy) );
|
|
|
|
if ( dist < closest_dist )
|
|
{
|
|
bestsample = sample;
|
|
closest_dist = dist;
|
|
}
|
|
|
|
}
|
|
|
|
// Not close to any of them!!!
|
|
if ( ( tolerance != 0.0f ) &&
|
|
( closest_dist > tolerance ) )
|
|
return NULL;
|
|
|
|
return bestsample;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::SelectPoints( void )
|
|
{
|
|
RECT rcSelection;
|
|
|
|
rcSelection.left = m_nStartX < m_nLastX ? m_nStartX : m_nLastX;
|
|
rcSelection.right = m_nStartX < m_nLastX ? m_nLastX : m_nStartX;
|
|
|
|
rcSelection.top = m_nStartY < m_nLastY ? m_nStartY : m_nLastY;
|
|
rcSelection.bottom = m_nStartY < m_nLastY ? m_nLastY : m_nStartY;
|
|
|
|
int selW = rcSelection.right - rcSelection.left;
|
|
int selH = rcSelection.bottom - rcSelection.top;
|
|
|
|
float tolerance = FP_SRT_SELECTION_RECTANGLE_TOLERANCE;
|
|
// If they are just clicking and releasing in one spot, capture any items w/in a larger tolerance
|
|
if ( selW <= 2 && selH <= 2 )
|
|
{
|
|
tolerance = FP_SRT_SELECTION_TOLERANCE;
|
|
|
|
CExpressionSample *sample = GetSampleUnderMouse( rcSelection.left + selW * 0.5f, rcSelection.top + selH * 0.5f );
|
|
if ( sample )
|
|
{
|
|
sample->selected = true;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
InflateRect( &rcSelection, 3, 3 );
|
|
}
|
|
|
|
RECT rcSamples;
|
|
GetSampleTrayRect( rcSamples );
|
|
|
|
int height = rcSamples.bottom - rcSamples.top;
|
|
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
float duration = s->FindStopTime();
|
|
if ( !duration )
|
|
return;
|
|
|
|
float fleft = (float)GetTimeValueForMouse( rcSelection.left );
|
|
float fright = (float)GetTimeValueForMouse( rcSelection.right );
|
|
|
|
//fleft *= duration;
|
|
//fright *= duration;
|
|
|
|
float ftop = (float)( rcSelection.top - rcSamples.top ) / (float)height;
|
|
float fbottom = (float)( rcSelection.bottom - rcSamples.top ) / (float)height;
|
|
|
|
fleft = clamp( fleft, 0.0f, duration );
|
|
fright = clamp( fright, 0.0f, duration );
|
|
ftop = clamp( ftop, 0.0f, 1.0f );
|
|
fbottom = clamp( fbottom, 0.0f, 1.0f );
|
|
|
|
float timestepperpixel = 1.0f / GetPixelsPerSecond();
|
|
float yfracstepperpixel = 1.0f / (float)height;
|
|
|
|
|
|
float epsx = tolerance*timestepperpixel;
|
|
float epsy = tolerance*yfracstepperpixel;
|
|
|
|
for ( int i = 0; i < s->GetSceneRampCount(); i++ )
|
|
{
|
|
CExpressionSample *sample = s->GetSceneRamp( i );
|
|
|
|
if ( sample->time + epsx < fleft )
|
|
continue;
|
|
|
|
if ( sample->time - epsx > fright )
|
|
continue;
|
|
|
|
if ( (1.0f - sample->value ) + epsy < ftop )
|
|
continue;
|
|
|
|
if ( (1.0f - sample->value ) - epsy > fbottom )
|
|
continue;
|
|
|
|
sample->selected = true;
|
|
}
|
|
|
|
redraw();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Output : int
|
|
//-----------------------------------------------------------------------------
|
|
int SceneRampTool::CountSelected( void )
|
|
{
|
|
return m_pHelper->CountSelected( false );
|
|
}
|
|
|
|
void SceneRampTool::MoveSelectedSamples( float dfdx, float dfdy )
|
|
{
|
|
int selecteditems = CountSelected();
|
|
if ( !selecteditems )
|
|
return;
|
|
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
int c = s->GetSceneRampCount();
|
|
|
|
float duration = s->FindStopTime();
|
|
//dfdx *= duration;
|
|
|
|
for ( int i = 0; i < c; i++ )
|
|
{
|
|
CExpressionSample *sample = s->GetSceneRamp( i );
|
|
if ( !sample || !sample->selected )
|
|
continue;
|
|
|
|
sample->time += dfdx;
|
|
sample->time = clamp( sample->time, 0.0f, duration );
|
|
|
|
sample->value -= dfdy;
|
|
sample->value = clamp( sample->value, 0.0f, 1.0f );
|
|
}
|
|
|
|
s->ResortSceneRamp();
|
|
redraw();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::DeselectAll( void )
|
|
{
|
|
int i;
|
|
|
|
int selecteditems = CountSelected();
|
|
if ( !selecteditems )
|
|
return;
|
|
|
|
CChoreoScene *s = GetSafeScene();
|
|
Assert( s );
|
|
if ( !s )
|
|
return;
|
|
|
|
for ( i = s->GetSceneRampCount() - 1; i >= 0 ; i-- )
|
|
{
|
|
CExpressionSample *sample = s->GetSceneRamp( i );
|
|
sample->selected = false;
|
|
}
|
|
|
|
redraw();
|
|
}
|
|
|
|
void SceneRampTool::SelectAll( void )
|
|
{
|
|
int i;
|
|
|
|
CChoreoScene *s = GetSafeScene();
|
|
Assert( s );
|
|
if ( !s )
|
|
return;
|
|
|
|
for ( i = s->GetSceneRampCount() - 1; i >= 0 ; i-- )
|
|
{
|
|
CExpressionSample *sample = s->GetSceneRamp( i );
|
|
sample->selected = true;
|
|
}
|
|
|
|
redraw();
|
|
}
|
|
|
|
void SceneRampTool::Delete( void )
|
|
{
|
|
int i;
|
|
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
int selecteditems = CountSelected();
|
|
if ( !selecteditems )
|
|
return;
|
|
|
|
PreDataChanged( "Delete scene ramp points" );
|
|
|
|
for ( i = s->GetSceneRampCount() - 1; i >= 0 ; i-- )
|
|
{
|
|
CExpressionSample *sample = s->GetSceneRamp( i );
|
|
if ( !sample->selected )
|
|
continue;
|
|
|
|
s->DeleteSceneRamp( i );
|
|
}
|
|
|
|
PostDataChanged( "Delete scene ramp points" );
|
|
}
|
|
|
|
void SceneRampTool::OnModelChanged()
|
|
{
|
|
redraw();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *undodescription -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::PreDataChanged( char const *undodescription )
|
|
{
|
|
if ( m_nUndoSetup == 0 )
|
|
{
|
|
g_pChoreoView->SetDirty( true );
|
|
g_pChoreoView->PushUndo( undodescription );
|
|
}
|
|
++m_nUndoSetup;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *redodescription -
|
|
//-----------------------------------------------------------------------------
|
|
void SceneRampTool::PostDataChanged( char const *redodescription )
|
|
{
|
|
--m_nUndoSetup;
|
|
if ( m_nUndoSetup == 0 )
|
|
{
|
|
g_pChoreoView->PushRedo( redodescription );
|
|
redraw();
|
|
}
|
|
}
|
|
|
|
void SceneRampTool::SetMousePositionForEvent( mxEvent *event )
|
|
{
|
|
POINT pt;
|
|
GetCursorPos( &pt );
|
|
ScreenToClient( (HWND)getHandle(), &pt );
|
|
|
|
event->x = pt.x;
|
|
event->y = pt.y;
|
|
}
|
|
|
|
void SceneRampTool::OnEdgeProperties()
|
|
{
|
|
CChoreoScene *s = GetSafeScene();
|
|
if ( !s )
|
|
return;
|
|
|
|
CEdgePropertiesParams params;
|
|
Q_memset( ¶ms, 0, sizeof( params ) );
|
|
Q_strcpy( params.m_szDialogTitle, "Edge Properties" );
|
|
|
|
params.SetFromCurve( s->GetSceneRamp() );
|
|
|
|
if ( !EdgeProperties( ¶ms ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
char *undotext = "Change Scene Ramp Edge Properties";
|
|
|
|
PreDataChanged( undotext );
|
|
|
|
// Apply changes.
|
|
params.ApplyToCurve( s->GetSceneRamp() );
|
|
|
|
PostDataChanged( undotext );
|
|
}
|
|
|
|
void SceneRampTool::GetWorkList( bool reflect, CUtlVector< SceneRampTool * >& list )
|
|
{
|
|
NOTE_UNUSED( reflect );
|
|
list.AddToTail( this );
|
|
}
|