📄 expressiontool.cpp
字号:
}
m_pWorkspace->LayoutItems( true );
}
}
}
DeselectAll();
if ( event )
{
m_flLastDuration = event->GetDuration();
}
else
{
m_flLastDuration = 0.0f;
}
m_nLeftOffset = 0;
m_nLastHPixelsNeeded = -1;
InvalidateLayout();
m_bInSetEvent = false;
}
#pragma optimize( "g", on )
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool ExpressionTool::HasCopyData( void )
{
return ( m_CopyData[0].Size() != 0 ) ? true : false;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *source -
//-----------------------------------------------------------------------------
void ExpressionTool::Copy( CFlexAnimationTrack *source )
{
for ( int t = 0; t < 2; t++ )
{
m_CopyData[ t ].RemoveAll();
if ( t == 0 || source->IsComboType() )
{
for ( int i = 0 ; i < source->GetNumSamples( t ); i++ )
{
CExpressionSample *s = source->GetSample( i, t );
m_CopyData[ t ].AddToTail( *s );
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *destination -
//-----------------------------------------------------------------------------
void ExpressionTool::Paste( CFlexAnimationTrack *destination )
{
g_pChoreoView->SetDirty( true );
g_pChoreoView->PushUndo( "Paste" );
destination->Clear();
for ( int t = 0; t < 2; t++ )
{
for ( int i = 0; i < m_CopyData[ t ].Size() ; i++ )
{
CExpressionSample *s = &m_CopyData[ t ][ i ];
if ( t == 0 || destination->IsComboType() )
{
destination->AddSample( s->time, s->value, t );
}
}
}
g_pChoreoView->PushRedo( "Paste" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CChoreoEvent *ExpressionTool::GetSafeEvent( void )
{
if ( !g_pChoreoView )
return NULL;
CChoreoScene *scene = g_pChoreoView->GetScene();
if ( !scene )
return NULL;
// Find event by name
for ( int i = 0; i < scene->GetNumEvents() ; i++ )
{
CChoreoEvent *e = scene->GetEvent( i );
if ( !e || e->GetType() != CChoreoEvent::FLEXANIMATION )
continue;
if ( !stricmp( m_szEvent, e->GetName() ) )
{
DoTrackLookup( e );
return e;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : rcHandle -
//-----------------------------------------------------------------------------
void ExpressionTool::GetScrubHandleRect( RECT& rcHandle, bool clipped )
{
float pixel = 0.0f;
if ( m_pWorkspace->w2() > 0 )
{
pixel = GetPixelForTimeValue( m_flScrub );
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 ExpressionTool::DrawScrubHandle( CChoreoWidgetDrawHelper& drawHelper, RECT& rcHandle )
{
HBRUSH br = CreateSolidBrush( RGB( 0, 150, 100 ) );
COLORREF areaBorder = RGB( 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", m_flScrub );
CChoreoEvent *ev = GetSafeEvent();
if ( ev )
{
float st, ed;
st = ev->GetStartTime();
ed = ev->GetEndTime();
float dt = ed - st;
if ( dt > 0.0f )
{
sprintf( sz, "%.3f", st + m_flScrub );
}
}
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, RGB( 255, 255, 255 ), rcText, sz );
DeleteObject( br );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *event -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool ExpressionTool::IsMouseOverScrubHandle( mxEvent *event )
{
RECT rcHandle;
GetScrubHandleRect( rcHandle, 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 ExpressionTool::IsProcessing( void )
{
if ( !GetSafeEvent() )
return false;
if ( m_flScrub != m_flScrubTarget )
return true;
return false;
}
bool ExpressionTool::IsScrubbing( void ) const
{
bool scrubbing = ( m_nDragType == DRAGTYPE_SCRUBBER ) ? true : false;
return scrubbing;
}
void ExpressionTool::Think( float dt )
{
CChoreoEvent *event = GetSafeEvent();
if ( !event )
return;
bool scrubbing = IsScrubbing();
ScrubThink( dt, scrubbing );
}
void ExpressionTool::SetScrubTime( float t )
{
m_flScrub = t;
CChoreoEvent *e = GetSafeEvent();
if ( e )
{
float realtime = e->GetStartTime() + m_flScrub;
g_pChoreoView->SetScrubTime( realtime );
g_pChoreoView->DrawScrubHandle();
}
}
void ExpressionTool::SetScrubTargetTime( float t )
{
m_flScrubTarget = t;
CChoreoEvent *e = GetSafeEvent();
if ( e )
{
float realtime = e->GetStartTime() + m_flScrubTarget;
g_pChoreoView->SetScrubTargetTime( realtime );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : dt -
//-----------------------------------------------------------------------------
void ExpressionTool::ScrubThink( float dt, bool scrubbing )
{
CChoreoEvent *event = GetSafeEvent();
if ( !event )
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 ExpressionTool::redraw()
{
if ( !ToolCanDraw() )
return;
CChoreoWidgetDrawHelper drawHelper( this );
HandleToolRedraw( drawHelper );
COLORREF areaBorder = RGB( 230, 230, 220 );
RECT rcSelection;
GetWorkspaceRect( rcSelection );
drawHelper.DrawColoredLine( areaBorder,
PS_SOLID, 1, 0, rcSelection.top, w2(), rcSelection.top );
drawHelper.DrawColoredLine( areaBorder,
PS_SOLID, 1, 0, rcSelection.bottom, w2(), rcSelection.bottom );
if ( m_bSelectionActive )
{
RECT rcClient;
drawHelper.GetClientRect( rcClient );
int left, right;
left = GetPixelForTimeValue( m_flSelection[ 0 ] );
right = GetPixelForTimeValue( m_flSelection[ 1 ] );
rcSelection.left = left;
rcSelection.right = right;
rcSelection.bottom = TRAY_HEIGHT;
drawHelper.DrawFilledRect( RGB( 200, 220, 230 ), rcSelection );
drawHelper.DrawColoredLine( RGB( 100, 100, 255 ), PS_SOLID, 3, rcSelection.left, rcSelection.top, rcSelection.left, rcSelection.bottom );
drawHelper.DrawColoredLine( RGB( 100, 100, 255 ), PS_SOLID, 3, rcSelection.right, rcSelection.top, rcSelection.right, rcSelection.bottom );
}
CChoreoEvent *ev = GetSafeEvent();
if ( ev )
{
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, RGB( 0, 100, 0 ), rcUndo,
"Undo: %i/%i", current, total );
}
rcText.left += 60;
// Found it, write out description
//
drawHelper.DrawColoredText( "Arial", 11, 900, RGB( 200, 150, 100 ), rcText,
"Event: %s",
ev->GetName() );
OffsetRect( &rcText, 0, 30 );
rcText.left = 5;
RECT timeRect = rcText;
timeRect.right = timeRect.left + 100;
char sz[ 32 ];
float st, ed;
GetStartAndEndTime( st, ed );
st += ev->GetStartTime();
ed += ev->GetStartTime();
Q_snprintf( sz, sizeof( sz ), "%.2f", st );
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, RGB( 0, 0, 0 ), timeRect, sz );
timeRect = rcText;
Q_snprintf( sz, sizeof( sz ), "%.2f", ed );
int textW = drawHelper.CalcTextWidth( "Arial", 9, FW_NORMAL, sz );
timeRect.right = w2() - 10;
timeRect.left = timeRect.right - textW;
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, RGB( 0, 0, 0 ), timeRect, sz );
}
RECT rcHandle;
GetScrubHandleRect( rcHandle, true );
DrawScrubHandle( drawHelper, rcHandle );
DrawRelativeTags( drawHelper );
RECT rcPos;
GetMouseOverPosRect( rcPos );
DrawMouseOverPos( drawHelper, rcPos );
DrawEventEnd( drawHelper );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *tag -
//-----------------------------------------------------------------------------
bool ExpressionTool::GetTimingTagRect( RECT& rcClient, CChoreoEvent *event, CFlexTimingTag *tag, RECT& rcTag )
{
rcTag = rcClient;
int tagx = GetPixelForTimeValue( tag->GetStartTime() - event->GetStartTime() );
rcTag.top = rcClient.bottom - 6;
rcTag.bottom = rcTag.top + 6;
rcTag.left = tagx - 3;
rcTag.right = tagx + 3;
return true;
}
// Get workspace min, max point in terms of tool window
void ExpressionTool::GetWorkspaceLeftRight( int& left, int& right )
{
POINT pt;
pt.x = TRAY_ITEM_INSET;
pt.y = 0;
ClientToScreen( (HWND)m_pWorkspace->getHandle(), &pt );
ScreenToClient( (HWND)getHandle(), &pt );
left = (short)pt.x;
pt.x = m_pWorkspace->w2() - TRAY_ITEM_INSET - 12;
pt.y = 0;
ClientToScreen( (HWND)m_pWorkspace->getHandle(), &pt );
ScreenToClient( (HWND)getHandle(), &pt );
right = (short)pt.x;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : mx -
// my -
// Output : CFlexTimingTag
//-----------------------------------------------------------------------------
CFlexTimingTag *ExpressionTool::IsMouseOverTag( int mx, int my )
{
CChoreoEvent *event = GetSafeEvent();
if ( !event )
return NULL;
RECT rcClient;
GetClientRect( (HWND)getHandle(), &rcClient );
int left, right;
GetWorkspaceLeftRight( left, right );
rcClient.left = left;
rcClient.right = right;
rcClient.top = GetCaptionHeight();
rcClient.bottom = rcClient.top + TRAY_HEIGHT;
POINT pt;
pt.x = mx;
pt.y = my;
for ( int i = 0 ; i < event->GetNumTimingTags(); i++ )
{
CFlexTimingTag *tag = event->GetTimingTag( i );
if ( !tag )
continue;
RECT rcTag;
if ( !GetTimingTagRect( rcClient, event, tag, rcTag ) )
continue;
if ( !PtInRect( &rcTag, pt ) )
continue;
return tag;
}
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : drawHelper -
//-----------------------------------------------------------------------------
void ExpressionTool::DrawRelativeTags( CChoreoWidgetDrawHelper& drawHelper )
{
CChoreoEvent *event = GetSafeEvent();
if ( !event )
return;
float st, ed;
GetStartAndEndTime( st, ed );
if ( event->GetDuration() <= 0.0f )
return;
CChoreoScene *scene = g_pChoreoView->GetScene();
if ( !scene )
return;
RECT rcClient;
drawHelper.GetClientRect( rcClient );
int left, right;
GetWorkspaceLeftRight( left, right );
rcClient.top += GetCaptionHeight();
rcClient.left = left;
rcClient.right = right;
rcClient.bottom = rcClient.top + TRAY_HEIGHT;
// Iterate relative tags
for ( int i = 0; i < scene->GetNumActors(); i++ )
{
CChoreoActor *a = scene->GetActor( i );
if ( !a )
continue;
for ( int j = 0; j < a->GetNumChannels(); j++ )
{
CChoreoChannel *c = a->GetChannel( j );
if ( !c )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -