⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expressiontool.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				}

				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 + -