diff --git a/ui-sequencer.cc b/ui-sequencer.cc index f05904f..6c4184c 100644 --- a/ui-sequencer.cc +++ b/ui-sequencer.cc @@ -145,6 +145,30 @@ 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_ @@ -159,17 +183,11 @@ struct T_SyncViewImpl_ bool display( ) noexcept; private: - // Track identifier - struct T_TrackId_ - { - T_String id; - bool isOverride; - }; // Track display data struct T_TrackDisplay { - T_TrackId_ id; + T_SyncTrackId_ id; ImRect area; uint32_t dispSegs; uint32_t firstSeg; @@ -240,7 +258,6 @@ struct T_SyncViewImpl_ void sequencerHeader( ImRect const& bb ) noexcept; void sequencerBody( ImRect const& bb ) noexcept; void sequencerTracks( - float& hue , ImRect& bb , ImRect const& container ) noexcept; void sequencerTrack( @@ -321,7 +338,7 @@ struct T_SyncViewImpl_ float curZoomPixel; // Selected item - T_Optional< T_TrackId_ > selId{ }; + T_Optional< T_SyncTrackId_ > selId{ }; T_Optional< uint32_t > selSegment; T_Optional< uint32_t > selPoint; bool selPointDnD{ false }; @@ -335,9 +352,9 @@ struct T_SyncViewImpl_ // Sub-windows E_SubWindow sub{ SW_NONE }; - // Curve selection - T_KeyValueTable< T_String , bool > sCurves; - T_Set< T_String > sOverrides; + // Track selection + T_KeyValueTable< T_String , bool > sInputs; + T_Set< T_SyncTrackId_ > sTracks; T_String curveFinder; }; @@ -422,16 +439,25 @@ void T_SyncViewImpl_::checkTracks( ) noexcept { auto& sync{ Common::Sync( ) }; - // Check for "dead" overrides + // Check for overrides that have gone missing or that have become + // inconsistent. { bool ovRemoved{ false }; - for ( auto i = 0u ; i < sOverrides.size( ) ; ) { - if ( sync.overrideExists( sOverrides[ i ] ) ) { + for ( auto i = 0u ; i < sTracks.size( ) ; ) { + const auto& t{ sTracks[ i ] }; + if ( !t.isOverride ) { i ++; - } else { - sOverrides.remove( sOverrides[ i ] ); - ovRemoved = true; + continue; } + + A_SyncOverride const* const ovr{ sync.getOverride( t.id ) }; + if ( ovr && areOverrideInputsConsistent( *ovr ) ) { + i++; + continue; + } + + sTracks.remove( t ); + ovRemoved = true; } if ( !ovRemoved ) { return; @@ -439,22 +465,23 @@ void T_SyncViewImpl_::checkTracks( ) noexcept } // Remove all curves that come from overrides - for ( auto i = 0u ; i < sCurves.size( ) ; ) { - if ( sCurves.values( )[ i ] ) { - sCurves.remove( sCurves.keys( )[ i ] ); + for ( auto i = 0u ; i < sInputs.size( ) ; ) { + if ( sInputs.values( )[ i ] ) { + sInputs.remove( sInputs.keys( )[ i ] ); } else { i ++; } } // Re-add curves for the remaining overrides - const auto no{ sOverrides.size( ) }; + const auto no{ sTracks.size( ) }; for ( auto i = 0u ; i < no ; i ++ ) { - auto const* od{ sync.getOverride( sOverrides[ i ] ) }; + auto const& t{ sTracks[ i ] }; + auto const* const od{ sync.getOverride( t.id ) }; assert( od ); const auto ni{ od->inputNames( ).size( ) }; for ( auto j = 0u ; j < ni ; j ++ ) { - const bool ok{ sCurves.add( od->inputNames( )[ j ] , true ) }; + const bool ok{ sInputs.add( od->inputNames( )[ j ] , true ) }; assert( ok ); (void) ok; } } @@ -613,11 +640,10 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept } // Vertical scrollbar - tracks - const float totalHeight{ sCurves.size( ) * ( TrackHeight + TrackPadding * 2.f ) }; + const float totalHeight{ sTracks.size( ) * ( TrackHeight + TrackPadding * 2.f ) }; if ( vScroll > totalHeight - bbDisplay.GetHeight( ) ) { vScroll = ImMax( 0.f , totalHeight - bbDisplay.GetHeight( ) ); } - // FIXME overrides UserScrollbar( false , totalHeight , bbDisplay.GetHeight( ) , &vScroll , bbHeader.GetTR( ) , bbAll.GetHeight( ) ); @@ -874,16 +900,11 @@ void T_SyncViewImpl_::sequencerBody( dspTracks.clear( ); dspSegments.clear( ); dspPoints.clear( ); - if ( sCurves.size( ) != 0 ) { - + if ( sTracks.size( ) != 0 ) { ImRect subBb{ inner }; subBb.Min.y += TrackPadding - vScroll; subBb.Max.y = subBb.Min.y + TrackHeight; - - float hue{ 0.12f }; - - // TODO: display overrides - sequencerTracks( hue , subBb , inner ); + sequencerTracks( subBb , inner ); } if ( cursorPos >= 0 && cursorPos <= inner.GetWidth( ) ) { @@ -894,18 +915,19 @@ void T_SyncViewImpl_::sequencerBody( } } void T_SyncViewImpl_::sequencerTracks( - float& hue , ImRect& subBb , ImRect const& container ) noexcept { + float hue{ 0.12f }; auto& sync{ Common::Sync( ) }; - const auto nc{ sCurves.size( ) }; + + const auto nc{ sTracks.size( ) }; for ( auto i = 0u ; i < nc ; i ++ ) { - if ( sCurves.values( )[ i ] ) { + if ( sTracks[ i ].isOverride ) { continue; } - auto const& name{ sCurves.keys( )[ i ] }; + auto const& name{ sTracks[ i ].id }; auto* const curve{ sync.getCurve( name ) }; sequencerTrack( hue , subBb , container , name , curve ); subBb.Min.y += TrackHeight + 2 * TrackPadding; @@ -929,7 +951,7 @@ void T_SyncViewImpl_::sequencerTrack( // Add track display record const auto dTrackIdx{ dspTracks.size( ) }; auto& dTrack{ dspTracks.addNew( ) }; - dTrack.id = T_TrackId_{ id , false }; + dTrack.id = T_SyncTrackId_{ id , false }; dTrack.dispSegs = 0; dTrack.firstSeg = dspSegments.size( ); dTrack.area = bb; @@ -1304,8 +1326,10 @@ void T_SyncViewImpl_::displayInputSelector( ) noexcept // The list ImGui::BeginChild( "content" ); for ( auto const& n : names ) { - const bool present{ sCurves.contains( n ) }; - const bool overriden{ present && *sCurves.get( n ) }; + const T_SyncTrackId_ id{ n , false }; + const bool present{ sTracks.contains( id ) }; + assert( !present || sInputs.contains( n ) ); + const bool overriden{ present && *sInputs.get( n ) }; if ( overriden ) { PushDisabled( ); @@ -1315,9 +1339,11 @@ void T_SyncViewImpl_::displayInputSelector( ) noexcept stringBuffer.clear( ) << n << '\0'; if ( Checkbox( stringBuffer.data( ) , &select ) ) { if ( select ) { - sCurves.add( n , false ); + sTracks.add( id ); + sInputs.add( n , false ); } else { - sCurves.remove( n ); + sTracks.remove( id ); + sInputs.remove( n ); } } @@ -1362,7 +1388,7 @@ void T_SyncViewImpl_::displayOverrideSelector( ) noexcept auto const& ov{ *element.value< A_SyncOverride* >( ) }; auto const& id{ ov.id( ) }; - const bool present{ sOverrides.contains( id ) }; + const bool present{ sTracks.contains( T_SyncTrackId_{ id , true } ) }; const bool hasCurves{ !present && areOverrideInputsDisplayed( ov ) }; const bool consistent{ areOverrideInputsConsistent( ov ) }; @@ -1430,7 +1456,7 @@ bool T_SyncViewImpl_::areOverrideInputsDisplayed( { auto const& in{ ov.inputNames( ) }; for ( auto i = 0u ; i < in.size( ) ; i ++ ) { - if ( sCurves.contains( in[ i ] ) ) { + if ( sTracks.contains( T_SyncTrackId_{ in[ i ] , false } ) ) { return true; } } @@ -1442,12 +1468,13 @@ void T_SyncViewImpl_::overrideTrackToggled( const bool selected ) noexcept { auto const& in{ ov.inputNames( ) }; + const T_SyncTrackId_ id{ ov.id( ) , true }; // Handle de-selection if ( !selected ) { - sOverrides.remove( ov.id( ) ); + sTracks.remove( id ); for ( auto i = 0u ; i < in.size( ) ; i ++ ) { - sCurves.remove( in[ i ] ); + sInputs.remove( in[ i ] ); } return; } @@ -1455,9 +1482,9 @@ void T_SyncViewImpl_::overrideTrackToggled( // If the override is not consistent, we need to make it so SyncEditor::MakeOverrideConsistent( ov.id( ) ); - sOverrides.add( ov.id( ) ); + sTracks.add( id ); for ( auto i = 0u ; i < in.size( ) ; i ++ ) { - sCurves.add( in[ i ] , true ); + sInputs.add( in[ i ] , true ); } }