diff --git a/ui-sequencer.cc b/ui-sequencer.cc index b80632f..f7e14c2 100644 --- a/ui-sequencer.cc +++ b/ui-sequencer.cc @@ -368,9 +368,14 @@ struct T_SyncViewImpl_ void displayInputSelector( ) noexcept; void displayOverrideSelector( ) noexcept; + void clearSelectedTracks( ) noexcept; + void autoselectTracks( ) noexcept; + // Helpers for selecting overrides static bool areOverrideInputsConsistent( A_SyncOverride const& ov ) noexcept; + static bool wouldInputsNeedAdjustment( + A_SyncOverride const& ov ) noexcept; bool areOverrideInputsDisplayed( A_SyncOverride const& ov ) const noexcept; void overrideTrackToggled( @@ -680,7 +685,7 @@ void T_SyncViewImpl_::displayToolbar( ) noexcept showLabels = !showLabels; } SameLine( ); - if ( ToolbarButton( ICON_FA_BARS , BtSize , + if ( ToolbarButton( ICON_FA_LIST , BtSize , "Select inputs or sets thereof to display & edit." ) ) { const bool displaySelector{ sub == SW_INPUT_SELECTOR || sub == SW_OVERRIDE_SELECTOR }; @@ -690,8 +695,11 @@ void T_SyncViewImpl_::displayToolbar( ) noexcept SameLine( ); if ( ToolbarButton( ICON_FA_BAN , BtSize , "Clear selected tracks." , sTracks.size( ) != 0 ) ) { - sTracks.clear( ); - sInputs.clear( ); + clearSelectedTracks( ); + } + SameLine( ); + if ( ToolbarButton( ICON_FA_COG , BtSize , "Select tracks automatically." ) ) { + autoselectTracks( ); } } @@ -1661,6 +1669,31 @@ bool T_SyncViewImpl_::areOverrideInputsConsistent( return true; } +bool T_SyncViewImpl_::wouldInputsNeedAdjustment( + A_SyncOverride const& ov ) noexcept +{ + auto& sync{ Common::Sync( ) }; + auto const& in{ ov.inputNames( ) }; + auto nNulls{ 0u }; + for ( auto i = 0u ; i < in.size( ) - 1 ; i ++ ) { + T_SyncCurve const* const c0{ sync.getCurve( in[ i ] ) }; + if ( !c0 ) { + nNulls ++; + continue; + } + for ( auto j = i + 1 ; j < in.size( ) ; j ++ ) { + T_SyncCurve const* const c1{ sync.getCurve( in[ j ] ) }; + if ( !c1 || c0->matches( *c1 ) != E_SyncCurveMatch::IDENTICAL ) { + return false; + } + } + } + if ( !sync.getCurve( in[ in.size( ) - 1 ] ) ) { + nNulls ++; + } + return nNulls != 0 && nNulls != in.size( ); +} + bool T_SyncViewImpl_::areOverrideInputsDisplayed( A_SyncOverride const& ov ) const noexcept { @@ -1700,6 +1733,52 @@ void T_SyncViewImpl_::overrideTrackToggled( /*----------------------------------------------------------------------------*/ +void T_SyncViewImpl_::clearSelectedTracks( ) noexcept +{ + sTracks.clear( ); + sInputs.clear( ); + selId.clear( ); + selSegment.clear( ); + selPoint.clear( ); +} + +void T_SyncViewImpl_::autoselectTracks( ) noexcept +{ + clearSelectedTracks( ); + + auto& sync{ Common::Sync( ) }; + sync.visitOverrides( [&]( T_SyncOverrideVisitor::T_Element element , const bool exit ) { + if ( element.hasType< T_SyncOverrideSection* >( ) || !exit ) { + return true; + } + + auto const& ov{ *element.value< A_SyncOverride* >( ) }; + if ( !areOverrideInputsConsistent( ov ) ) { + return true; + } + if ( wouldInputsNeedAdjustment( ov ) ) { + return true; + } + + auto const& in{ ov.inputNames( ) }; + sTracks.add( T_SyncTrackId{ ov.id( ) , true } ); + for ( auto i = 0u ; i < in.size( ) ; i ++ ) { + sInputs.add( in[ i ] , true ); + } + + return true; + } ); + + for ( auto const& n : sync.inputNames( ) ) { + if ( !sInputs.contains( n ) ) { + sTracks.add( T_SyncTrackId{ n , false } ); + sInputs.add( n , false ); + } + } +} + +/*----------------------------------------------------------------------------*/ + void T_SyncViewImpl_::displayTrackWindow( ) noexcept { using namespace ImGui;