From 78d15dd3508f14dfc1fddfbbf1fb6e663d6e100d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Wed, 29 Nov 2017 12:44:36 +0100 Subject: [PATCH] Sequencer - Moving points (overrides support) --- ui-sequencer.cc | 112 ++++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/ui-sequencer.cc b/ui-sequencer.cc index f9a1de4..8c7c1e6 100644 --- a/ui-sequencer.cc +++ b/ui-sequencer.cc @@ -322,8 +322,8 @@ struct T_SyncViewImpl_ // Original and copy of curve being modified E_ChangeType selUpdate{ E_ChangeType::NONE }; - T_Optional< T_SyncCurve > selUpdatingOriginal; - T_Optional< T_SyncCurve > selUpdatingCopy; + T_AutoArray< T_SyncCurve , 16 > selUpdatingOriginals; + T_AutoArray< T_SyncCurve , 16 > selUpdatingCopies; // Sub-windows E_SubWindow sub{ SW_NONE }; @@ -505,8 +505,8 @@ void T_SyncViewImpl_::checkSelection( ) noexcept // If we were doing something with the curve, get rid of that too if ( selUpdate != E_ChangeType::NONE ) { selUpdate = E_ChangeType::NONE; - selUpdatingCopy.clear( ); - selUpdatingOriginal.clear( ); + selUpdatingCopies.clear( ); + selUpdatingOriginals.clear( ); } } @@ -743,15 +743,19 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept selSegment = dSeg.seg; selPoint = dPoint.index; selPointDnD = io.MouseDown[ 0 ] && dPoint.index != 0; - if ( selPointDnD && !selId->isOverride ) { // XXX + if ( selPointDnD ) { assert( selUpdate == E_ChangeType::NONE ); selPointDnDStart = selPointDnDCur = mPixels; - selUpdatingOriginal = *sync.getCurve( selId->id ); + if ( selId->isOverride ) { + auto const& names{ sync.getOverride( selId->id )->inputNames( ) }; + const auto ni{ names.size( ) }; + for ( auto i = 0u ; i < ni ; i ++ ) { + selUpdatingOriginals.add( *sync.getCurve( names[ i ] ) ); + } + } else { + selUpdatingOriginals.add( *sync.getCurve( selId->id ) ); + } selUpdate = E_ChangeType::POINT_DND; - } else if ( selId->isOverride ) { - printf( "FIXME!\n" ); - selPointDnD = false; -#warning blah } sub = E_SubWindow::SW_POINT; } @@ -979,13 +983,13 @@ void T_SyncViewImpl_::sequencerTrack( // If there's a curve, go through all segments const auto units{ Common::Sync( ).durationUnits( ) }; - const bool useCopy{ sCurve && curve && selUpdatingCopy }; + const bool useCopy{ sCurve && curve && !selUpdatingCopies.empty( ) }; const auto nSeg{ curve - ? ( useCopy ? *selUpdatingCopy : *curve ).segments.size( ) + ? ( useCopy ? selUpdatingCopies[ 0 ] : *curve ).segments.size( ) : 0u }; uint32_t segStart{ 0 }; for ( auto i = 0u ; i < nSeg ; i ++ ) { - auto const& seg{ ( useCopy ? *selUpdatingCopy : *curve ).segments[ i ] }; + auto const& seg{ ( useCopy ? selUpdatingCopies[ 0 ] : *curve ).segments[ i ] }; const auto segDur{ [&](){ auto t{ 0u }; for ( auto d : seg.durations ) { @@ -1199,31 +1203,38 @@ bool T_SyncViewImpl_::handlePointDrag( const float diff{ selPointDnDCur - selPointDnDStart }; const int32_t diffUnits{ int32_t( round( diff * sync.durationUnits( ) / totalPixels ) ) }; const bool moved{ fabsf( diff ) >= 2 && abs( diffUnits ) > 0 }; + const auto ni{ selUpdatingCopies.size( ) }; // Update the point as necessary if ( moved ) { - selUpdatingCopy = selUpdatingOriginal; // XXX - auto& seg{ selUpdatingCopy->segments[ *selSegment ] }; - if ( *selPoint == seg.durations.size( ) ) { - // We're dragging the end point - // XXX make it work "normally" - seg.durations.last( ) = std::max( 1 , - diffUnits + int32_t( seg.durations.last( ) ) ); - } else { - // We're dragging some other point, move units - // from one side to the other - assert( *selPoint > 0 ); - auto& d0{ seg.durations[ *selPoint - 1 ] }; - auto& d1{ seg.durations[ *selPoint ] }; - const int32_t mmNeg( 1 - d0 ) , mmPos( d1 - 1 ); - const int32_t diff{ diffUnits < mmNeg ? mmNeg - : ( diffUnits > mmPos ? mmPos : diffUnits ) }; - d0 += diff; - d1 -= diff; + selUpdatingCopies = selUpdatingOriginals; + for ( auto i = 0u ; i < ni ; i ++ ) { + auto& copy{ selUpdatingCopies[ i ] }; + auto& seg{ copy.segments[ *selSegment ] }; + if ( *selPoint == seg.durations.size( ) ) { + // We're dragging the end point + // XXX make it work "normally" + seg.durations.last( ) = std::max( 1 , + diffUnits + int32_t( seg.durations.last( ) ) ); + } else { + // We're dragging some other point, move units + // from one side to the other + assert( *selPoint > 0 ); + auto& d0{ seg.durations[ *selPoint - 1 ] }; + auto& d1{ seg.durations[ *selPoint ] }; + const int32_t mmNeg( 1 - d0 ) , mmPos( d1 - 1 ); + const int32_t diff{ diffUnits < mmNeg ? mmNeg + : ( diffUnits > mmPos ? mmPos : diffUnits ) }; + d0 += diff; + d1 -= diff; + } + sync.setCurve( copy ); } - sync.setCurve( *selUpdatingCopy ); } else { - selUpdatingCopy.clear( ); + selUpdatingCopies.clear( ); + for ( auto i = 0u ; i < ni ; i ++ ) { + sync.setCurve( selUpdatingOriginals[ i ] ); + } } if ( mouseDown ) { @@ -1233,12 +1244,20 @@ bool T_SyncViewImpl_::handlePointDrag( assert( selUpdate == E_ChangeType::POINT_DND ); selUpdate = E_ChangeType::NONE; selPointDnD = false; - sync.setCurve( std::move( *selUpdatingOriginal ) ); - selUpdatingOriginal.clear( ); if ( moved ) { - SyncEditor::ReplaceCurve( std::move( *selUpdatingCopy ) ); - selUpdatingCopy.clear( ); + auto& undo{ dynamic_cast< T_UndoSyncChanges& >( + Common::Undo( ).add< T_UndoSyncChanges >( ) ) }; + for ( auto i = 0u ; i < ni ; i ++ ) { + undo.curveReplacement( std::move( selUpdatingOriginals[ i ] ) , + std::move( selUpdatingCopies[ i ] ) ); + } + } else { + for ( auto i = 0u ; i < ni ; i ++ ) { + sync.setCurve( std::move( selUpdatingOriginals[ i ] ) ); + } } + selUpdatingOriginals.clear( ); + selUpdatingCopies.clear( ); return false; } @@ -1851,8 +1870,8 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept auto const* const ovr{ selId->isOverride ? sync.getOverride( selId->id ) : nullptr }; - auto const* const curve{ selUpdatingCopy - ? selUpdatingCopy.target( ) + auto const* const curve{ selUpdatingCopies.size( ) + ? &selUpdatingCopies[ 0 ] : sync.getCurve( ovr ? ovr->inputNames( )[ 0 ] : selId->id ) }; auto const& segment{ curve->segments[ sid ] }; @@ -1959,19 +1978,20 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept if ( changed ) { if ( selUpdate == E_ChangeType::NONE ) { - selUpdatingOriginal = *curve; - selUpdatingCopy = *curve; + selUpdatingOriginals.add( *curve ); + selUpdatingCopies.add( *curve ); selUpdate = E_ChangeType::POINT_VALUE; } else { assert( selUpdate == E_ChangeType::POINT_VALUE ); } - selUpdatingCopy->segments[ sid ].values[ pid ] = value; - sync.setCurve( *selUpdatingCopy ); + selUpdatingCopies[ 0 ].segments[ sid ].values[ pid ] = value; + sync.setCurve( selUpdatingCopies[ 0 ] ); } else if ( selUpdate == E_ChangeType::POINT_VALUE ) { selUpdate = E_ChangeType::NONE; - sync.setCurve( *selUpdatingOriginal ); - SyncEditor::ReplaceCurve( std::move( *selUpdatingCopy ) ); - selUpdatingCopy.clear( ); + sync.setCurve( selUpdatingOriginals[ 0 ] ); + SyncEditor::ReplaceCurve( std::move( selUpdatingCopies[ 0 ] ) ); + selUpdatingCopies.clear( ); + selUpdatingOriginals.clear( ); } End( );