Sequencer - Improved point d'n'd
This commit is contained in:
parent
99f6862138
commit
7f6db48a61
2 changed files with 48 additions and 24 deletions
1
TODO
1
TODO
|
@ -33,6 +33,7 @@ Sync / inputs:
|
|||
* Moving tracks
|
||||
* Moving segments
|
||||
* Add curve display
|
||||
* CLEAN UP THAT FUCKING SPAGHETTI MESS!
|
||||
|
||||
Misc:
|
||||
* General overhaul (e.g. use tabs)
|
||||
|
|
|
@ -367,7 +367,8 @@ struct T_SyncViewImpl_
|
|||
const float time ) noexcept;
|
||||
bool handlePointDrag(
|
||||
const float mPixels ,
|
||||
bool mouseDown ) noexcept;
|
||||
bool mouseDown ,
|
||||
bool shiftPressed ) noexcept;
|
||||
|
||||
T_MousePos getMousePos( ) const noexcept;
|
||||
|
||||
|
@ -858,7 +859,8 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
|
|||
zoomLevel = ( ppu - BarWidth ) / ( BarWidth - width / u ) + 1;
|
||||
}
|
||||
}
|
||||
} else if ( dnd == E_DNDType::POINT && handlePointDrag( mPixels , io.MouseDown[ 0 ] ) ) {
|
||||
} else if ( dnd == E_DNDType::POINT
|
||||
&& handlePointDrag( mPixels , io.MouseDown[ 0 ] , io.KeyShift ) ) {
|
||||
return;
|
||||
} else if ( dnd == E_DNDType::CLICK && ( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
|
||||
return;
|
||||
|
@ -911,7 +913,8 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
|
|||
selId = dTrack.id;
|
||||
selSegment = dSeg.seg;
|
||||
selPoint = dPoint.index;
|
||||
const bool pdnd{ io.MouseDown[ 0 ] && dPoint.index != 0 };
|
||||
const bool pdnd{ io.MouseDown[ 0 ]
|
||||
&& ( dPoint.index != 0 || dSeg.seg != 0 ) };
|
||||
if ( pdnd ) {
|
||||
assert( selUpdate == E_ChangeType::NONE );
|
||||
selPointDnDStart = selPointDnDCur = mPixels;
|
||||
|
@ -1400,7 +1403,8 @@ void T_SyncViewImpl_::displayTooltips(
|
|||
|
||||
bool T_SyncViewImpl_::handlePointDrag(
|
||||
const float mPixels ,
|
||||
bool mouseDown ) noexcept
|
||||
bool mouseDown ,
|
||||
bool shiftPressed ) noexcept
|
||||
{
|
||||
auto& sync( Common::Sync( ) );
|
||||
|
||||
|
@ -1409,32 +1413,51 @@ bool T_SyncViewImpl_::handlePointDrag(
|
|||
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( ) };
|
||||
const auto sid{ *selSegment };
|
||||
const auto pid{ *selPoint };
|
||||
assert( pid > 0 || sid > 0 );
|
||||
const bool isLastPoint{ [&](){
|
||||
auto const& s{ selUpdatingOriginals[ 0 ].segments };
|
||||
return sid == s.size( ) - 1 && pid == s[ sid ].durations.size( );
|
||||
}( ) };
|
||||
|
||||
// Update the point as necessary
|
||||
if ( moved ) {
|
||||
if ( moved && ( shiftPressed || isLastPoint ) ) {
|
||||
// Increase/decrease duration
|
||||
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;
|
||||
}
|
||||
auto& seg{ copy.segments[ sid ] };
|
||||
auto& d{ pid == 0
|
||||
? copy.segments[ sid - 1 ].durations.last( )
|
||||
: seg.durations[ pid - 1 ] };
|
||||
d = std::max( 1 , diffUnits + int32_t( d ) );
|
||||
sync.setCurve( copy );
|
||||
}
|
||||
|
||||
} else if ( moved ) {
|
||||
// Move the point but keep the sum of before/after durations
|
||||
// a constant
|
||||
selUpdatingCopies = selUpdatingOriginals;
|
||||
for ( auto i = 0u ; i < ni ; i ++ ) {
|
||||
auto& copy{ selUpdatingCopies[ i ] };
|
||||
auto& seg{ copy.segments[ sid ] };
|
||||
|
||||
auto& d0{ pid == 0
|
||||
? copy.segments[ sid - 1 ].durations.last( )
|
||||
: seg.durations[ pid - 1 ] };
|
||||
auto& d1{ pid == seg.durations.size( )
|
||||
? copy.segments[ sid + 1 ].durations[ 0 ]
|
||||
: seg.durations[ pid ]
|
||||
};
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
} else {
|
||||
selUpdatingCopies.clear( );
|
||||
for ( auto i = 0u ; i < ni ; i ++ ) {
|
||||
|
|
Loading…
Reference in a new issue