diff --git a/c-syncedit.cc b/c-syncedit.cc index b96fe0c..063570d 100644 --- a/c-syncedit.cc +++ b/c-syncedit.cc @@ -192,62 +192,109 @@ void SyncEditor::ReplaceCurve( /*----------------------------------------------------------------------------*/ void SyncEditor::DeleteCurve( - T_String const& id ) noexcept + T_SyncTrackId const& id ) noexcept { - auto const* const curve{ Common::Sync( ).getCurve( id ) }; - if ( !curve ) { + auto& sync{ Common::Sync( ) }; + + auto const* const ovr{ id.isOverride ? sync.getOverride( id.id ) : nullptr }; + if ( id.isOverride && !ovr ) { return; } + const uint32_t nCurves{ ovr ? ovr->inputNames( ).size( ) : 1 }; + T_String cNames[ nCurves ]; + if ( ovr ) { + bool hasNonNull{ false }; + for ( auto i = 0u ; i < nCurves ; i ++ ) { + cNames[ i ] = ovr->inputNames( )[ i ]; + hasNonNull = hasNonNull || sync.getCurve( cNames[ i ] ); + } + if ( !hasNonNull ) { + return; + } + } else { + if ( !sync.getCurve( id.id ) ) { + return; + } + cNames[ 0 ] = id.id; + } + // Create undo entry auto& undo{ dynamic_cast< T_UndoSyncChanges& >( Common::Undo( ).add< T_UndoSyncChanges >( ) ) }; - undo.curveDeletion( *curve ); - // Delete curve - Common::Sync( ).removeCurve( id ); + // Delete curves + for ( T_String const& cn : cNames ) { + auto const* const curve{ sync.getCurve( cn ) }; + if ( curve ) { + undo.curveDeletion( *curve ); + Common::Sync( ).removeCurve( cn ); + } + } } /*----------------------------------------------------------------------------*/ void SyncEditor::AppendSegment( - T_String const& id , + T_SyncTrackId const& id , uint32_t nsDuration ) noexcept { assert( nsDuration > 0 ); auto& sync{ Common::Sync( ) }; - auto const* const curve{ sync.getCurve( id ) }; + + auto const* const ovr{ id.isOverride ? sync.getOverride( id.id ) : nullptr }; + if ( id.isOverride && !ovr ) { + return; + } + + const uint32_t nCurves{ ovr ? ovr->inputNames( ).size( ) : 1 }; + T_SyncCurve const* curves[ nCurves ]; + T_String cNames[ nCurves ]; + if ( ovr ) { + for ( auto i = 0u ; i < nCurves ; i ++ ) { + cNames[ i ] = ovr->inputNames( )[ i ]; + curves[ i ] = sync.getCurve( cNames[ i ] ); + } + } else { + cNames[ 0 ] = id.id; + curves[ 0 ] = sync.getCurve( id.id ); + } + auto& undo{ dynamic_cast< T_UndoSyncChanges& >( Common::Undo( ).add< T_UndoSyncChanges >( ) ) }; - if ( curve && !curve->segments.empty( ) ) { - const float lastValue{ [&](){ - auto const& lSeg{ curve->segments.last( ) }; - return lSeg.values.last( ); - }( ) }; - auto nCurve{ *curve }; - auto& nSeg{ nCurve.segments.addNew( ) }; - nSeg.type = T_SyncSegment::LINEAR; - nSeg.values.add( lastValue ); - nSeg.values.add( lastValue ); - nSeg.durations.add( nsDuration ); + for ( auto i = 0u ; i < nCurves ; i ++ ) { + auto const* const curve{ curves[ i ] }; + if ( curve && !curve->segments.empty( ) ) { + const float lastValue{ [&](){ + auto const& lSeg{ curve->segments.last( ) }; + return lSeg.values.last( ); + }( ) }; + auto nCurve{ *curve }; + auto& nSeg{ nCurve.segments.addNew( ) }; + nSeg.type = T_SyncSegment::LINEAR; + nSeg.values.add( lastValue ); + nSeg.values.add( lastValue ); + nSeg.durations.add( nsDuration ); - undo.curveReplacement( *curve , nCurve ); - sync.setCurve( std::move( nCurve ) ); - } else { - T_SyncCurve nCurve; - nCurve.name = id; + undo.curveReplacement( *curve , nCurve ); + sync.setCurve( std::move( nCurve ) ); + } else { + T_SyncCurve nCurve; + nCurve.name = cNames[ i ]; - const auto value{ sync.inputs( )[ sync.inputPos( id ) ] }; - auto& nSeg{ nCurve.segments.addNew( ) }; - nSeg.type = T_SyncSegment::LINEAR; - nSeg.values.add( value ); - nSeg.values.add( value ); - nSeg.durations.add( nsDuration ); + const auto value{ sync.inputs( )[ + sync.inputPos( cNames[ i ] ) ] }; + auto& nSeg{ nCurve.segments.addNew( ) }; + nSeg.type = T_SyncSegment::LINEAR; + nSeg.values.add( value ); + nSeg.values.add( value ); + nSeg.durations.add( nsDuration ); - undo.curveCreation( nCurve ); - sync.setCurve( std::move( nCurve ) ); + undo.curveCreation( nCurve ); + sync.setCurve( std::move( nCurve ) ); + } } } diff --git a/c-syncedit.hh b/c-syncedit.hh index c064ee1..b8bf235 100644 --- a/c-syncedit.hh +++ b/c-syncedit.hh @@ -77,6 +77,30 @@ class T_UndoDurationChanges final : public T_UndoSyncChanges }; +/*= TRACK IDENTIFIER =========================================================*/ + +struct T_SyncTrackId +{ + T_String id; + bool isOverride; + + bool operator ==( T_SyncTrackId const& other ) const noexcept + { + return id == other.id && isOverride == other.isOverride; + } + + bool operator !=( T_SyncTrackId const& other ) const noexcept + { + return id != other.id || isOverride != other.isOverride; + } +}; + +inline uint32_t ComputeHash( T_SyncTrackId const& id ) noexcept +{ + return ComputeHash( id.id ) ^ ( id.isOverride ? 0xffffffff : 0 ); +} + + /*= EDITION FUNCTIONS ========================================================*/ struct SyncEditor final @@ -96,16 +120,16 @@ struct SyncEditor final static void ReplaceCurve( T_SyncCurve replacement ) noexcept; - // Delete a curve's record completely. + // Delete a curve's (or an override's) record completely. static void DeleteCurve( - T_String const& id ) noexcept; + T_SyncTrackId const& id ) noexcept; //---------------------------------------------------------------------- // Append a segment with the specified amount of units at the end of // the curve. If the curve does not exist it will be created. static void AppendSegment( - T_String const& id , + T_SyncTrackId const& id , uint32_t nsDuration ) noexcept; // Delete a segment from a curve. diff --git a/ui-sequencer.cc b/ui-sequencer.cc index bf71eb7..2d55c52 100644 --- a/ui-sequencer.cc +++ b/ui-sequencer.cc @@ -145,30 +145,6 @@ bool T_ChangeDurationDialog_::onButton( } -/*= T_SyncTrackId_ ===========================================================*/ - -struct T_SyncTrackId_ -{ - T_String id; - bool isOverride; - - bool operator ==( T_SyncTrackId_ const& other ) const noexcept - { - return id == other.id && isOverride == other.isOverride; - } - - bool operator !=( T_SyncTrackId_ const& other ) const noexcept - { - return id != other.id || isOverride != other.isOverride; - } -}; - -uint32_t ComputeHash( T_SyncTrackId_ const& id ) noexcept -{ - return ComputeHash( id.id ) ^ ( id.isOverride ? 0xffffffff : 0 ); -} - - /*= T_SyncViewImpl_ ==========================================================*/ struct T_SyncViewImpl_ @@ -187,7 +163,7 @@ struct T_SyncViewImpl_ // Track display data struct T_TrackDisplay { - T_SyncTrackId_ id; + T_SyncTrackId id; ImRect area; uint32_t dispSegs; uint32_t firstSeg; @@ -264,7 +240,7 @@ struct T_SyncViewImpl_ float& hue , ImRect const& bb , ImRect const& container , - T_SyncTrackId_ const& id , + T_SyncTrackId const& id , T_SyncCurve const* curve ) noexcept; void displayTooltips( @@ -338,7 +314,7 @@ struct T_SyncViewImpl_ float curZoomPixel; // Selected item - T_Optional< T_SyncTrackId_ > selId{ }; + T_Optional< T_SyncTrackId > selId{ }; T_Optional< uint32_t > selSegment; T_Optional< uint32_t > selPoint; bool selPointDnD{ false }; @@ -354,7 +330,7 @@ struct T_SyncViewImpl_ // Track selection T_KeyValueTable< T_String , bool > sInputs; - T_Set< T_SyncTrackId_ > sTracks; + T_Set< T_SyncTrackId > sTracks; T_String curveFinder; }; @@ -943,7 +919,7 @@ void T_SyncViewImpl_::sequencerTrack( float& hue , ImRect const& bb , ImRect const& container , - T_SyncTrackId_ const& id , + T_SyncTrackId const& id , T_SyncCurve const* curve ) noexcept { // Don't display if the track is fully hidden @@ -1353,7 +1329,7 @@ void T_SyncViewImpl_::displayInputSelector( ) noexcept // The list ImGui::BeginChild( "content" ); for ( auto const& n : names ) { - const T_SyncTrackId_ id{ n , false }; + const T_SyncTrackId id{ n , false }; const bool present{ sTracks.contains( id ) }; assert( !present || sInputs.contains( n ) ); const bool overriden{ present && *sInputs.get( n ) }; @@ -1415,7 +1391,7 @@ void T_SyncViewImpl_::displayOverrideSelector( ) noexcept auto const& ov{ *element.value< A_SyncOverride* >( ) }; auto const& id{ ov.id( ) }; - const bool present{ sTracks.contains( T_SyncTrackId_{ id , true } ) }; + const bool present{ sTracks.contains( T_SyncTrackId{ id , true } ) }; const bool hasCurves{ !present && areOverrideInputsDisplayed( ov ) }; const bool consistent{ areOverrideInputsConsistent( ov ) }; @@ -1483,7 +1459,7 @@ bool T_SyncViewImpl_::areOverrideInputsDisplayed( { auto const& in{ ov.inputNames( ) }; for ( auto i = 0u ; i < in.size( ) ; i ++ ) { - if ( sTracks.contains( T_SyncTrackId_{ in[ i ] , false } ) ) { + if ( sTracks.contains( T_SyncTrackId{ in[ i ] , false } ) ) { return true; } } @@ -1495,7 +1471,7 @@ void T_SyncViewImpl_::overrideTrackToggled( const bool selected ) noexcept { auto const& in{ ov.inputNames( ) }; - const T_SyncTrackId_ id{ ov.id( ) , true }; + const T_SyncTrackId id{ ov.id( ) , true }; // Handle de-selection if ( !selected ) { @@ -1615,20 +1591,16 @@ void T_SyncViewImpl_::displayTrackWindow( ) noexcept Text( " " ); SameLine( 110 ); if ( Button( "Clear" , ImVec2{ -1 , 0 } ) ) { - assert( !selId->isOverride ); -#warning blah - SyncEditor::DeleteCurve( selId->id ); + SyncEditor::DeleteCurve( *selId ); } } if ( tDuration < dDuration ) { Text( " " ); SameLine( 110 ); if ( Button( "Append segment" , ImVec2{ -1 , 0 } ) ) { - assert( !selId->isOverride ); -#warning blah const uint32_t ns{ std::max( 1u , ( sync.durationUnits( ) - duration ) / 2 ) }; - SyncEditor::AppendSegment( selId->id , ns ); + SyncEditor::AppendSegment( *selId , ns ); } }