From 99264594f64a6b515575fa368dc4ddc674d05a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Mon, 27 Nov 2017 09:12:51 +0100 Subject: [PATCH] Sequencer - Display track values on hover --- TODO | 3 +-- c-sync.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++++ c-sync.hh | 7 +++++++ ui-sequencer.cc | 11 ++++++++--- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 85f4411..fb385c6 100644 --- a/TODO +++ b/TODO @@ -31,9 +31,8 @@ Sync / inputs: -> remove points that serve no purpose * Support for overrides * Fix the various remaining issues - * Issues related to "selected stuff going the way of the dodo" - * Finding values for arbitrary points in time * Zooming issues on the right side + * Scrollbars * Add curve display Misc: diff --git a/c-sync.cc b/c-sync.cc index 32965ac..2dac47f 100644 --- a/c-sync.cc +++ b/c-sync.cc @@ -180,6 +180,29 @@ void T_SyncTime::setDuration( /*= T_SyncSegment ============================================================*/ +float T_SyncSegment::computeValue( + const float relTimeUnits ) const noexcept +{ + uint32_t part{ 0 } , begin{ 0 } , end{ durations[ 0 ] }; + while ( end < relTimeUnits ) { + part ++; + begin = end; + end += durations[ part ]; + } + + const float v0{ ( relTimeUnits - begin ) / ( end - begin ) }; + float v = v0; + if ( type != T_SyncSegment::LINEAR ) { + v *= v0; + if ( type == T_SyncSegment::SMOOTH ) { + v *= 3 - 2 * v0; + } + } + + const float sv{ values[ part ] }; + return v * ( values[ part + 1 ] - sv ) + sv; +} + M_LSHIFT_OP( T_StringBuilder , T_SyncSegment::E_SegmentType ) { switch ( value ) { @@ -197,6 +220,30 @@ M_LSHIFT_OP( T_StringBuilder , T_SyncSegment::E_SegmentType ) } +/*= T_SyncCurve ==============================================================*/ + +float T_SyncCurve::computeValue( + const float timeUnits ) const noexcept +{ + assert( timeUnits >= 0 ); + + uint32_t segStart{ 0 } , prevSegStart{ 0 }; + auto it{ segments.begin( ) }; + while ( segStart < timeUnits && it != segments.end( ) ) { + prevSegStart = segStart; + for ( auto d : it->durations ) { + segStart += d; + } + ++ it; + } + -- it; + if ( segStart < timeUnits ) { + return it->values.last( ); + } + return it->computeValue( timeUnits - prevSegStart ); +} + + /*= T_SyncCurves =============================================================*/ int32_t T_SyncCurves::indexOf( diff --git a/c-sync.hh b/c-sync.hh index bee7d38..ac4e3bd 100644 --- a/c-sync.hh +++ b/c-sync.hh @@ -41,6 +41,10 @@ struct T_SyncSegment E_SegmentType type; T_Array< float > values; T_Array< uint32_t > durations; // n(values) - 1 items + + // Compute the value for the specified position, which is relative + // to the start of the segment. + float computeValue( float relTimeUnits ) const noexcept; }; M_LSHIFT_OP( T_StringBuilder , T_SyncSegment::E_SegmentType ); @@ -59,6 +63,9 @@ struct T_SyncCurve T_SyncCurve( char const* name ) noexcept : name( T_String( name ).usePool( ) ) { } + + // Compute the value at the specified time. + float computeValue( float timeUnits ) const noexcept; }; // All configured curves. Some may not actually correspond to an input and may diff --git a/ui-sequencer.cc b/ui-sequencer.cc index b2b9711..58a4f40 100644 --- a/ui-sequencer.cc +++ b/ui-sequencer.cc @@ -1032,7 +1032,8 @@ void T_SyncViewImpl_::displayTooltips( }() ); // Curve from track - T_SyncCurve const* const curve{ Common::Sync( ).getCurve( track.id ) }; + auto& sync{ Common::Sync( ) }; + T_SyncCurve const* const curve{ sync.getCurve( track.id ) }; assert( mp.type == E_MousePosType::TRACK || curve != nullptr ); // Time offset @@ -1048,14 +1049,18 @@ void T_SyncViewImpl_::displayTooltips( tDur += s.durations[ j ]; } } - return tDur * Common::Sync( ).durationUnitSize( ); + return tDur * sync.durationUnitSize( ); } return time; }() ); + const float dUTime{ dTime / sync.durationUnitSize( ) }; char buffer[ 12 ]; TimeToString_( buffer , sizeof( buffer ) , dTime ); - const float value{ point ? curve->segments[ seg->seg ].values[ point->index ] : -.666f }; // FIXME + const float value{ point + ? curve->segments[ seg->seg ].values[ point->index ] + : ( curve ? curve->computeValue( dUTime ) + : sync.inputs( )[ sync.inputPos( track.id ) ] ) }; stringBuffer.clear( ) << track.id << " (input)\n"; if ( mp.type == E_MousePosType::TRACK ) {