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

📄 expressiontool.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include <stdio.h>
#include "hlfaceposer.h"
#include "ExpressionTool.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 "MatSysWin.h"
#include "choreoviewcolors.h"

ExpressionTool *g_pExpressionTool = 0;

#define TRAY_HEIGHT 55 

#define TRAY_ITEM_INSET 10

#define MAX_TIME_ZOOM 1000
// 10% per step
#define TIME_ZOOM_STEP 2

void SetupFlexControllerTracks( studiohdr_t *hdr, CChoreoEvent *event );

class CExpressionToolWorkspace : public mxWindow
{
public:
	CExpressionToolWorkspace( mxWindow *parent );
	~CExpressionToolWorkspace();

	virtual int			handleEvent( mxEvent *event );
	virtual void		redraw( void );
	virtual bool		PaintBackground( void )
	{
		redraw();
		return false;
	}

	void				RepositionVSlider( void );
	int					ComputeVPixelsNeeded( void );
	// Playback tick
	void				Think( float dt );

	void				LayoutItems( bool force = false );

	void				HideTimelines( void );
	void				CollapseAll( TimelineItem *keepExpanded );

	void				ExpandAll( void );
	void				ExpandValid( void );
	void				DisableAllExcept( void );
	void				EnableValid( void );

	TimelineItem		*GetItem( int number );
	TimelineItem		*GetClickedItem( void );
	void				ClearClickedItem( void );

	void				OnSnapAll();
	void				OnDeleteColumn();

	void				MoveSelectedSamples( float dfdx, float dfdy, bool snap );
	void				DeleteSelectedSamples( void );
	int					CountSelectedSamples( void );
	void				DeselectAll( void );
	void				SelectPoints( float start, float end );

	void				DrawEventEnd( CChoreoWidgetDrawHelper& drawHelper );

	void				OnSortByUsed( void );
	void				OnSortByName( void );
private:

	int					GetItemUnderMouse( int mx, int my );

	void				MouseToToolMouse( int& mx, int& my, char *reason );

	TimelineItem		*m_pItems[ GLOBAL_STUDIO_FLEX_CONTROL_COUNT ];

	// The scroll bars
	mxScrollbar			*m_pVertScrollBar;
	int					m_nLastVPixelsNeeded;

	int					m_nTopOffset;
	int					m_nScrollbarHeight;

	int					m_nItemGap;
	int					m_nFocusItem;
};

CExpressionToolWorkspace::CExpressionToolWorkspace( mxWindow *parent ) :
	mxWindow( parent, 0, 0, 0, 0 )
{
	HWND wnd = (HWND)getHandle();
	DWORD style = GetWindowLong( wnd, GWL_STYLE );
	style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
	SetWindowLong( wnd, GWL_STYLE, style );

	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		m_pItems[ i ] = new TimelineItem( this );
	}

	m_nItemGap		= 2;

	m_nScrollbarHeight = 12;
	m_nTopOffset	= 0;

	m_nLastVPixelsNeeded = -1;

	m_pVertScrollBar = new mxScrollbar( this, 0, 0, 12, 100, IDC_EXPRESSIONTOOLVSCROLL, mxScrollbar::Vertical );

	m_nFocusItem = -1;

	HideTimelines();
	LayoutItems();
}

CExpressionToolWorkspace::~CExpressionToolWorkspace()
{
}

void CExpressionToolWorkspace::redraw()
{
	CChoreoWidgetDrawHelper drawHelper( this );

	DrawEventEnd( drawHelper );

	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		if ( !item )
			continue;

		if ( !item->GetVisible() )
			continue;

		RECT rcBounds;
		item->GetBounds( rcBounds );

		if ( rcBounds.bottom < 0 )
			continue;
		if ( rcBounds.top > h2() )
			continue;

		item->Draw( drawHelper );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *elem1 - 
//			*elem2 - 
// Output : int
//-----------------------------------------------------------------------------
int SortFuncByUse(const void *elem1, const void *elem2 )
{
	TimelineItem *item1 = *( TimelineItem ** )elem1;
	TimelineItem *item2 = *( TimelineItem ** )elem2;

	if ( item1->IsValid() == item2->IsValid() )
		return 0;

	if ( !item2->IsValid() && item1->IsValid() )
		return -1;

	return 1;
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *elem1 - 
//			*elem2 - 
// Output : int
//-----------------------------------------------------------------------------
int SortFuncByName(const void *elem1, const void *elem2 )
{
	TimelineItem *item1 = *( TimelineItem ** )elem1;
	TimelineItem *item2 = *( TimelineItem ** )elem2;

	CFlexAnimationTrack *track1 = item1->GetSafeTrack();
	CFlexAnimationTrack *track2 = item2->GetSafeTrack();

	if ( !track1 || !track2 )
	{
		if ( track1 )
			return -1;
		if ( track2 )
			return 1;
		return 0;
	}

	return stricmp( track1->GetFlexControllerName(), track2->GetFlexControllerName() );
}

void CExpressionToolWorkspace::OnSortByUsed( void )
{
	qsort( m_pItems, GLOBAL_STUDIO_FLEX_CONTROL_COUNT, sizeof( TimelineItem * ), SortFuncByUse );
	LayoutItems( false );
}

void CExpressionToolWorkspace::OnSortByName( void )
{
	qsort( m_pItems, GLOBAL_STUDIO_FLEX_CONTROL_COUNT, sizeof( TimelineItem * ), SortFuncByName );
	LayoutItems( false );
}

void CExpressionToolWorkspace::DrawEventEnd( CChoreoWidgetDrawHelper& drawHelper )
{
	CChoreoEvent *e = g_pExpressionTool->GetSafeEvent();
	if ( !e )
		return;

	float duration = e->GetDuration();
	if ( !duration )
		return;

	int leftx = g_pExpressionTool->GetPixelForTimeValue( duration ) -5;
	if ( leftx >= w2() )
		return;

	RECT rcClient;
	drawHelper.GetClientRect( rcClient );

	drawHelper.DrawColoredLine(
		COLOR_CHOREO_ENDTIME, PS_SOLID, 1,
		leftx, rcClient.top, leftx, rcClient.bottom );

}

int CExpressionToolWorkspace::GetItemUnderMouse( int mx, int my )
{
	POINT pt;
	pt.x = mx;
	pt.y = my;

	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		if ( !item )
			continue;

		if ( !item->GetVisible() )
			continue;

		RECT rc;
		item->GetBounds( rc );

		if ( PtInRect( &rc, pt ) )
		{
			return i;
		}
	}

	return -1;
}

void CExpressionToolWorkspace::MouseToToolMouse( int& mx, int& my, char *reason )
{
	POINT pt;

	int oldmx = mx;

	pt.x = mx;
	pt.y = my;

	ClientToScreen( (HWND)getHandle(), &pt );
	ScreenToClient( (HWND)getParent()->getHandle(), &pt );

	mx = pt.x;
	my = pt.y;
}

int	CExpressionToolWorkspace::handleEvent( mxEvent *event )
{
	int iret = 0;

	switch ( event->event )
	{
	case mxEvent::MouseDown:
		{
			SetFocus( (HWND)getParent()->getHandle() );

			{
				int mx = (short)event->x;
				int my = (short)event->y;

				MouseToToolMouse( mx, my, "CExpressionToolWorkspace mousedown" );

				g_pExpressionTool->SetClickedPos( mx, my );
				g_pExpressionTool->SetMouseOverPos( mx, my );
				g_pExpressionTool->DrawMouseOverPos();

			}

			int oldFocus = m_nFocusItem;
			m_nFocusItem = GetItemUnderMouse( (short)event->x, (short)event->y );

			if ( oldFocus != -1 &&
				oldFocus != m_nFocusItem )
			{
				TimelineItem *item = GetItem( oldFocus );
				if ( item )
				{
					item->DrawSelf();
				}
			}
			if ( m_nFocusItem != -1 )
			{
				TimelineItem *item = GetItem( m_nFocusItem );
				if ( item )
				{
					RECT rc;
					item->GetBounds( rc );

					event->x -= rc.left;
					event->y -= rc.top;

					iret = item->handleEvent( event );
				}
			}
			
			iret = 1;
		}
		break;
	case mxEvent::MouseDrag:
	case mxEvent::MouseMove:
		{
			// 
			bool handled = false;

			if ( m_nFocusItem != -1 )
			{
				TimelineItem *item = GetItem( m_nFocusItem );
				if ( item )
				{
					RECT rc;
					item->GetBounds( rc );

					event->x -= rc.left;
					event->y -= rc.top;

					iret = item->handleEvent( event );

					if ( event->event == mxEvent::MouseDrag )
					{
						int mx, my;
						
						item->GetLastMouse( mx, my );
						mx += rc.left;
						my += rc.top;

						MouseToToolMouse( mx, my, "CExpressionToolWorkspace mousedrag" );

						g_pExpressionTool->SetMouseOverPos( mx, my );
						g_pExpressionTool->DrawMouseOverPos();
						handled = true;
					}
				}
			}

			if ( !handled )
			{
				int mx = (short)event->x;
				int my = (short)event->y;

				mx += TRAY_ITEM_INSET;

				MouseToToolMouse( mx, my, "CExpressionToolWorkspace mousemove" );

				g_pExpressionTool->SetMouseOverPos( mx, my );
				g_pExpressionTool->DrawMouseOverPos();
			}
		}
		break;
	case mxEvent::MouseUp:
		{
			// 
			{
				int mx = (short)event->x;
				int my = (short)event->y;

				MouseToToolMouse( mx, my, "CExpressionToolWorkspace mouseup" );

				g_pExpressionTool->SetMouseOverPos( mx, my );
				g_pExpressionTool->DrawMouseOverPos();

			}

			if ( m_nFocusItem != -1 )
			{
				TimelineItem *item = GetItem( m_nFocusItem );
				if ( item )
				{
					RECT rc;
					item->GetBounds( rc );

					event->x -= rc.left;
					event->y -= rc.top;

					iret = item->handleEvent( event );
				}
			}
		}
		break;
	case mxEvent::Size:
		{
			RepositionVSlider();
			LayoutItems();
			iret = 1;
		}
		break;
	case mxEvent::MouseWheeled:
		// Tell parent
		{
			if ( event->modifiers & mxEvent::KeyShift )
			{
				// Zoom time in  / out
				if ( event->height > 0 )
				{
					g_pExpressionTool->SetTimeZoomScale( min( g_pExpressionTool->GetTimeZoomScale() + TIME_ZOOM_STEP, MAX_TIME_ZOOM ) );
				}
				else
				{
					g_pExpressionTool->SetTimeZoomScale( max( g_pExpressionTool->GetTimeZoomScale() - TIME_ZOOM_STEP, TIME_ZOOM_STEP ) );
				}
				g_pExpressionTool->RepositionHSlider();
				redraw();
				iret = 1;
				return iret;
			}

			int offset = 0;
			int jump = 50;

			if ( event->height < 0 )
			{
				offset = m_pVertScrollBar->getValue();
				offset += jump;
				offset = min( offset, m_pVertScrollBar->getMaxValue() );
			}
			else
			{
				offset = m_pVertScrollBar->getValue();
				offset -= jump;
				offset = max( offset, m_pVertScrollBar->getMinValue() );
			}

			m_pVertScrollBar->setValue( offset );
			InvalidateRect( (HWND)m_pVertScrollBar->getHandle(), NULL, TRUE );
			m_nTopOffset = offset;
			LayoutItems();
			iret = 1;
		}
		break;
	case mxEvent::Action:
		{
			iret = 1;
			switch ( event->action )
			{
			default:
				iret = 0;
				break;
			case IDC_EXPRESSIONTOOLVSCROLL:
				{
					int offset = 0;
					bool processed = true;

					switch ( event->modifiers )
					{
					case SB_THUMBTRACK:
						offset = event->height;
						break;
					case SB_PAGEUP:
						offset = m_pVertScrollBar->getValue();
						offset -= 100;
						offset = max( offset, m_pVertScrollBar->getMinValue() );
						break;
					case SB_PAGEDOWN:
						offset = m_pVertScrollBar->getValue();
						offset += 100;
						offset = min( offset, m_pVertScrollBar->getMaxValue() );
						break;
					case SB_LINEDOWN:
						offset = m_pVertScrollBar->getValue();
						offset += 10;
						offset = min( offset, m_pVertScrollBar->getMaxValue() );
						break;
					case SB_LINEUP:
						offset = m_pVertScrollBar->getValue();
						offset -= 10;
						offset = max( offset, m_pVertScrollBar->getMinValue() );
						break;
					default:
						processed = false;
						break;
					}
		
					if ( processed )
					{
						m_pVertScrollBar->setValue( offset );
						InvalidateRect( (HWND)m_pVertScrollBar->getHandle(), NULL, TRUE );
						m_nTopOffset = offset;
						LayoutItems();
					}
				}
			}
		}
		break;
	}
	return iret;
}

void CExpressionToolWorkspace::HideTimelines( void )
{
	for ( int i = 0; i < GLOBAL_STUDIO_FLEX_CONTROL_COUNT; i++ )
	{
		TimelineItem *item = GetItem( i );
		Assert( item );
		item->SetVisible( false );
	}

	redraw();
}


TimelineItem *CExpressionToolWorkspace::GetItem( int number )
{
	if ( number < 0 || number >= GLOBAL_STUDIO_FLEX_CONTROL_COUNT )
	{
		return NULL;
	}
	return m_pItems[ number ];
}

TimelineItem *CExpressionToolWorkspace::GetClickedItem( void )
{
	return GetItem( m_nFocusItem );
}

//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -