📄 sceneramptool.cpp
字号:
#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 "vstdlib/strtools.h"
#include "faceposer_models.h"
#include "UtlBuffer.h"
#include "FileSystem.h"
#include "cmdlib.h"
#include "scriplib.h"
#include "iscenetokenprocessor.h"
#include "choreoviewcolors.h"
#include "MatSysWin.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
float SnapTime( float input, float granularity );
StudioModel *FindAssociatedModel( CChoreoScene *scene, CChoreoActor *a );
SceneRampTool::SceneRampTool( mxWindow *parent )
: IFacePoserToolWindow( "SceneRampTool", "Scene Ramp" ), mxWindow( parent, 0, 0, 0, 0 )
{
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_nTimeZoom = 100;
m_nScrollbarHeight = 12;
m_nLeftOffset = 0;
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;
}
SceneRampTool::~SceneRampTool( void )
{
}
//-----------------------------------------------------------------------------
// 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( reference ? RGB( 150, 0, 0 ) : 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", 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, RGB( 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, RGB( 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, RGB( 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, RGB( 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, RGB( 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 ( CountSelectedSamples() > 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->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.Size(); 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 -
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -