📄 expressiontool.cpp
字号:
continue;
for ( int k = 0 ; k < c->GetNumEvents(); k++ )
{
CChoreoEvent *e = c->GetEvent( k );
if ( !e )
continue;
// add each tag to combo box
for ( int t = 0; t < e->GetNumRelativeTags(); t++ )
{
CEventRelativeTag *tag = e->GetRelativeTag( t );
if ( !tag )
continue;
//SendMessage( control, CB_ADDSTRING, 0, (LPARAM)va( "\"%s\" \"%s\"", tag->GetName(), e->GetParameters() ) );
bool clipped;
int tagx = GetPixelForTimeValue( tag->GetStartTime() - event->GetStartTime(), &clipped );
if ( clipped )
continue;
//drawHelper.DrawColoredLine( RGB( 180, 180, 220 ), PS_SOLID, 1, tagx, rcClient.top, tagx, rcClient.bottom );
RECT rcMark;
rcMark = rcClient;
rcMark.top = rcClient.bottom - 6;
rcMark.left = tagx - 3;
rcMark.right = tagx + 3;
drawHelper.DrawTriangleMarker( rcMark, RGB( 0, 100, 250 ) );
RECT rcText;
rcText = rcMark;
rcText.top -= 10;
int len = drawHelper.CalcTextWidth( "Arial", 9, FW_NORMAL, tag->GetName() );
rcText.left = tagx - len / 2;
rcText.right = rcText.left + len + 2;
rcText.bottom = rcText.top + 10;
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, RGB( 0, 100, 200 ), rcText, tag->GetName() );
}
}
}
}
for ( int t = 0; t < event->GetNumTimingTags(); t++ )
{
CFlexTimingTag *tag = event->GetTimingTag( t );
if ( !tag )
continue;
RECT rcMark;
if ( !GetTimingTagRect( rcClient, event, tag, rcMark ) )
continue;
drawHelper.DrawTriangleMarker( rcMark, RGB( 250, 100, 0 ) );
RECT rcText;
rcText = rcMark;
rcText.top -= 20;
char text[ 256 ];
sprintf( text, "%s", tag->GetName() );
if ( tag->GetLocked() )
{
strcat( text, " - locked" );
}
int len = drawHelper.CalcTextWidth( "Arial", 9, FW_NORMAL, text );
rcText.left = ( rcMark.left + rcMark.right ) / 2 - len / 2;
rcText.right = rcText.left + len + 2;
rcText.bottom = rcText.top + 10;
drawHelper.DrawColoredText( "Arial", 9, FW_NORMAL, RGB( 200, 100, 0 ), rcText, text );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ExpressionTool::ShowContextMenu( mxEvent *event, bool include_track_menus )
{
// Construct main menu
mxPopupMenu *pop = new mxPopupMenu();
TimelineItem *item = NULL;
CFlexAnimationTrack *track = NULL;
if ( include_track_menus )
{
item = m_pWorkspace->GetClickedItem();
if ( item )
{
item->CountSelected();
track = item->GetSafeTrack();
}
}
int current, total;
g_pChoreoView->GetUndoLevels( current, total );
if ( total > 0 )
{
if ( current > 0 )
{
pop->add( va( "Undo %s", g_pChoreoView->GetUndoDescription() ), IDC_UNDO_FA );
}
if ( current <= total - 1 )
{
pop->add( va( "Redo %s", g_pChoreoView->GetRedoDescription() ), IDC_REDO_FA );
}
pop->addSeparator();
}
// Create expand menu
mxPopupMenu *expand = new mxPopupMenu();
if ( item && track && item->IsCollapsed() )
{
expand->add( va( "Track '%s'", track->GetFlexControllerName() ), IDC_TL_EXPAND );
}
expand->add( "All tracks", IDC_EXPANDALL );
expand->add( "Used tracks", IDC_EXPANDVALID );
pop->addMenu( "Expand", expand );
mxPopupMenu *collapse = new mxPopupMenu;
if ( item && track && !item->IsCollapsed() )
{
collapse->add( va( "Track '%s'", track->GetFlexControllerName() ), IDC_TL_COLLAPSE );
collapse->add( va( "All tracks except '%s'", track->GetFlexControllerName() ), IDC_COLLAPSE_ALL_EXCEPT );
}
collapse->add( "All tracks", IDC_COLLAPSEALL );
pop->addMenu( "Collapse", collapse );
pop->addSeparator();
pop->add( va( "Enable all valid" ), IDC_ENABLE_ALL_VALID );
if ( item && track )
{
if ( item->IsActive() )
{
pop->add( va( "Disable '%s'", track->GetFlexControllerName() ), IDC_TL_DISABLE );
}
else
{
pop->add( va( "Enable '%s'", track->GetFlexControllerName() ), IDC_TL_ENABLE );
}
pop->add( va( "Disable all except '%s'", track->GetFlexControllerName() ), IDC_DISABLE_ALL_EXCEPT );
pop->addSeparator();
pop->add( "Copy", IDC_TL_COPY );
if ( HasCopyData() )
{
pop->add( "Paste", IDC_TL_PASTE );
}
pop->addSeparator();
if ( item->GetNumSelected() > 0 )
{
pop->add( va( "Delete" ), IDC_TL_DELETE );
pop->add( "Deselect all", IDC_TL_DESELECT );
pop->add( va( "Scale selected..." ), IDC_FLEX_SCALESAMPLES );
}
pop->add( "Select all", IDC_TL_SELECTALL );
if ( FacePoser_IsSnapping() )
{
mxPopupMenu *snap = new mxPopupMenu();
snap->add( va( "All points" ), IDC_TL_SNAPALL );
snap->add( va( "All points in '%s'", track->GetFlexControllerName() ), IDC_TL_SNAPPOINTS );
snap->add( va( "Selected points in '%s'", track->GetFlexControllerName() ), IDC_TL_SNAPSELECTED );
pop->addSeparator();
pop->addMenu( "Snap", snap );
}
if ( track->IsComboType() )
{
pop->addSeparator();
if ( item->GetEditType() == 0 )
{
pop->add( "Edit <left/right>", IDC_TL_EDITLEFTRIGHT );
}
else
{
pop->add( "Edit <amount>", IDC_TL_EDITNORMAL );
}
}
pop->addSeparator();
mxPopupMenu *heightMenu = new mxPopupMenu();
heightMenu->add( va( "Reset '%s'", track->GetFlexControllerName() ) , IDC_ET_RESET_ITEM_SIZE );
heightMenu->add( "Reset All", IDC_ET_RESET_ALL_ITEM_SIZES );
pop->addMenu( "Height", heightMenu );
}
pop->addSeparator();
mxPopupMenu *tagmenu = new mxPopupMenu();
CFlexTimingTag *tag = IsMouseOverTag( (short)event->x, (short)event->y );
if ( tag )
{
if ( tag->GetLocked() )
{
tagmenu->add( va( "Unlock tag '%s'...", tag->GetName() ), IDC_UNLOCK_TIMING_TAG );
}
else
{
tagmenu->add( va( "Lock tag '%s'...", tag->GetName() ), IDC_LOCK_TIMING_TAG );
}
tagmenu->addSeparator();
tagmenu->add( va( "Delete tag '%s'...", tag->GetName() ), IDC_DELETE_TIMING_TAG );
}
else
{
tagmenu->add( "Insert...", IDC_INSERT_TIMING_TAG );
}
if ( IsMouseOverSelection( (short)event->x, (short)event->y ) )
{
mxPopupMenu *selectionMenu = new mxPopupMenu();
selectionMenu->add( "Delete samples", IDC_ET_SELECTION_DELETE );
selectionMenu->add( "Delete samples and shift remainder", IDC_ET_SELECTION_EXCISE );
pop->addMenu( "Column", selectionMenu );
}
pop->addMenu( "Timing Tags", tagmenu );
if ( FacePoser_IsSnapping() )
{
pop->addSeparator();
pop->add( "Delete keys by frame", IDC_TL_DELETECOLUMN );
pop->addSeparator();
}
mxPopupMenu *flexmenu = new mxPopupMenu();
flexmenu->add( "Copy to sliders", IDC_COPY_TO_FLEX );
flexmenu->add( "Copy from sliders", IDC_COPY_FROM_FLEX );
pop->addMenu( "Flex", flexmenu );
pop->add( "Create expression...", IDC_NEW_EXPRESSION_FROM_FLEXANIMATION );
CChoreoEvent *e = GetSafeEvent();
if ( e )
{
mxPopupMenu *importexport = new mxPopupMenu();
importexport->add( "Export flex animation...", IDC_EXPORT_FA );
importexport->add( "Import flex animation...", IDC_IMPORT_FA );
pop->addMenu( "Import/Export", importexport );
}
pop->add( va( "Change scale..." ), IDC_FLEX_CHANGESCALE );
mxPopupMenu *sortmenu = new mxPopupMenu();
sortmenu->add( "Sort by name", IDC_ET_SORT_BY_NAME );
sortmenu->add( "Sort by used", IDC_ET_SORT_BY_USED );
pop->addMenu( "Sort", sortmenu );
pop->popup( this, (short)event->x, (short)event->y );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ExpressionTool::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 ExpressionTool::SetClickedPos( int x, int y )
{
m_nClickedX = x;
m_nClickedY = y;
}
float ExpressionTool::GetTimeForClickedPos( void )
{
CChoreoEvent *e = GetSafeEvent();
if ( !e )
return 0.0f;
float t = GetTimeValueForMouse( m_nClickedX );
// Get spline intensity for controller
float faketime = e->GetStartTime() + t;
return faketime;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : dragtype -
// startx -
// cursor -
//-----------------------------------------------------------------------------
void ExpressionTool::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 rc;
GetWorkspaceRect( rc );
RECT rcStart;
rcStart.left = startx;
rcStart.right = startx;
bool addrect = true;
switch ( dragtype )
{
default:
case DRAGTYPE_SCRUBBER:
{
RECT rcScrub;
GetScrubHandleRect( rcScrub, true );
rcStart = rcScrub;
rcStart.left = ( rcScrub.left + rcScrub.right ) / 2;
rcStart.right = rcStart.left;
rcStart.top = rcScrub.bottom;
rcStart.bottom = h2();
}
break;
case DRAGTYPE_FLEXTIMINGTAG:
{
rcStart.top = rc.top;
rcStart.bottom = h2();
}
break;
case DRAGTYPE_SELECTSAMPLES:
{
float st = GetTimeValueForMouse( startx );
rcStart.left = GetPixelForTimeValue( st );
rcStart.right = rcStart.left;
m_nStartX = rcStart.left;
m_nLastX = rcStart.left;
}
case DRAGTYPE_MOVESELECTIONSTART:
case DRAGTYPE_MOVESELECTIONEND:
{
rcStart.top = rc.top;
rcStart.bottom = rc.bottom;
}
break;
case DRAGTYPE_MOVESELECTION:
{
rcStart.top = rc.top;
rcStart.bottom = rc.bottom;
// Compute left/right pixels for selection
rcStart.left = GetPixelForTimeValue( m_flSelection[ 0 ] );
rcStart.right = GetPixelForTimeValue( m_flSelection[ 1 ] );
}
break;
}
if ( addrect )
{
AddFocusRect( rcStart );
}
DrawFocusRect();
}
void ExpressionTool::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.Size(); i++ )
{
CFocusRect *f = &m_FocusRects[ i ];
f->m_rcFocus = f->m_rcOrig;
switch ( m_nDragType )
{
default:
{
OffsetRect( &f->m_rcFocus, ( (short)event->x - m_nStartX ), 0 );
}
break;
case DRAGTYPE_SELECTSAMPLES:
{
float st = GetTimeValueForMouse( mx );
int snapx = GetPixelForTimeValue( st );
f->m_rcFocus.left = min( snapx, m_nStartX );
f->m_rcFocus.right = max( snapx, m_nStartY );
POINT offset;
offset.x = 0;
offset.y = 0;
ClientToScreen( (HWND)getHandle(), &offset );
OffsetRect( &f->m_rcFocus, offset.x, 0 );
}
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 ) );
}
else if ( IsMouseOverSelection( (short)event->x, (short)event->y ) )
{
if ( IsMouseOverSelectionStartEdge( event ) )
{
m_hPrevCursor = SetCursor( LoadCursor( NULL, IDC_SIZEWE ) );
}
else if ( IsMouseOverSelectionEndEdge( event ) )
{
m_hPrevCursor = SetCursor( LoadCursor( NULL, IDC_SIZEWE ) );
}
else
{
if ( event->modifiers & mxEvent::KeyShift )
{
m_hPrevCursor = SetCursor( LoadCursor( NULL, IDC_SIZEALL ) );
}
}
}
}
switch ( m_nDragType )
{
default:
break;
case DRAGTYPE_FLEXTIMINGTAG:
{
ApplyBounds( mx, my );
}
break;
case DRAGTYPE_SCRUBBER:
{
ApplyBounds( mx, my );
if ( w2() > 0 )
{
float t = GetTimeValueForMouse( mx );
t += m_flScrubberTimeOffset;
ForceScrubPosition( t );
}
}
break;
}
m_nLastX = (short)event->x;
m_nLastY = (short)event->y;
}
int ExpressionTool::handleEvent( mxEvent *event )
{
int iret = 0;
if ( HandleToolEvent( event ) )
{
return iret;
}
switch ( event->event )
{
case mxEvent::Size:
{
int w, h;
w = event->width;
h = event->height;
m_pWorkspace->setBounds( 5, TRAY_HEIGHT + GetCaptionHeight(), w - 10, h - ( TRAY_HEIGHT + 5 + GetCaptionHeight() ) - m_nScrollbarHeight );
m_nLastHPixelsNeeded = 0;
InvalidateLayout();
iret = 1;
}
break;
case mxEvent::MouseWheeled:
{
// Zoom time in / out
if ( event->height > 0 )
{
m_nTimeZoom = min( m_nTimeZoom + TIME_ZOOM_STEP, MAX_TIME_ZOOM );
}
else
{
m_nTimeZoom = max( m_nTimeZoom - TIME_ZOOM_STEP, TIME_ZOOM_STEP );
}
RepositionHSlider();
m_pWorkspace->redraw();
redraw();
iret = 1;
}
break;
case mxEvent::MouseDown:
{
bool ctrldown = ( event->modifiers & mxEvent::KeyCtrl ) ? true : false;
bool shiftdown = ( event->modifiers & mxEvent::KeyShift ) ? true : false;
iret = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -