Sequencer - Unified drag'n'drop handling

Until now the various types of drag'n'drop were handled separately and
could very possibly interfere with each other. This fixes the problem by
using a single variable for the current type (if any) of drag'n'drop
This commit is contained in:
Emmanuel BENOîT 2017-11-30 12:10:47 +01:00
parent eb7bd8bcbe
commit 99f6862138
2 changed files with 35 additions and 19 deletions

1
TODO
View file

@ -30,7 +30,6 @@ Sync / inputs:
* Zoom level is mostly useless, fix it
* Save/restore sets of tracks
* Edition buttons in toolbar
* Fix drag-and-drop
* Moving tracks
* Moving segments
* Add curve display

View file

@ -330,6 +330,16 @@ struct T_SyncViewImpl_
POINT_VALUE ,
};
// Type of drag-and-drop operation in progress
enum class E_DNDType {
NONE , // No drag'n'drop
CLICK , // Clicked in an area that will not
// cause drag'n'drop to happen
TIME , // Time being adjusted
ZOOM , // Zoom region being selected
POINT , // Point being moved
};
// Make sure all displayed inputs/overrides still exist
void checkTracks( ) noexcept;
// Make sure the currently selected track/segment/point is still valid
@ -408,6 +418,7 @@ struct T_SyncViewImpl_
// Misc stuff
T_StringBuilder stringBuffer; // XXX damn this shit to fucking hell
E_DNDType dnd{ E_DNDType::NONE };
// Computed metrics
bool checkLockMode{ false };
@ -426,7 +437,6 @@ struct T_SyncViewImpl_
T_Array< T_TrackPointDisplay > dspPoints;
// Zoom area selection
bool zoomInProgress{ false };
float firstZoomPixel;
float curZoomPixel;
@ -434,7 +444,6 @@ struct T_SyncViewImpl_
T_Optional< T_SyncTrackId > selId{ };
T_Optional< uint32_t > selSegment;
T_Optional< uint32_t > selPoint;
bool selPointDnD{ false };
float selPointDnDStart , selPointDnDCur;
// Original and copy of curve being modified
@ -829,8 +838,11 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
return;
}
if ( zoomInProgress && !io.MouseDown[ 1 ] ) {
zoomInProgress = false;
if ( dnd == E_DNDType::ZOOM ) {
if ( io.MouseDown[ 1 ] ) {
curZoomPixel = mPixels;
return;
}
checkLockMode = true;
const auto zMin{ std::min( firstZoomPixel , curZoomPixel ) } ,
zMax{ std::max( firstZoomPixel , curZoomPixel ) } ,
@ -846,16 +858,17 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
zoomLevel = ( ppu - BarWidth ) / ( BarWidth - width / u ) + 1;
}
}
} else if ( zoomInProgress && io.MouseDown[ 1 ] ) {
curZoomPixel = mPixels;
} else if ( dnd == E_DNDType::POINT && handlePointDrag( mPixels , io.MouseDown[ 0 ] ) ) {
return;
} else if ( dnd == E_DNDType::CLICK && ( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
return;
} else if ( dnd == E_DNDType::TIME && io.MouseDown[ 0 ] ) {
sync.setTime( mTime );
return;
}
if ( selPointDnD && handlePointDrag( mPixels , io.MouseDown[ 0 ] ) ) {
return;
}
if ( !( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
if ( dnd != E_DNDType::NONE && !( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
dnd = E_DNDType::NONE;
ClearActiveID( );
return;
}
@ -864,10 +877,10 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
if ( mp.type == E_MousePosType::NONE ) {
if ( io.MouseDown[ 0 ] ) {
sync.setTime( mTime );
}
if ( io.MouseDown[ 1 ] ) {
dnd = E_DNDType::TIME;
} else if ( io.MouseDown[ 1 ] ) {
firstZoomPixel = mPixels;
zoomInProgress = true;
dnd = E_DNDType::ZOOM;
curZoomPixel = mPixels;
}
@ -878,6 +891,7 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
selSegment = decltype( selSegment ){};
selPoint = decltype( selPoint ){};
sub = E_SubWindow::SW_TRACK;
dnd = E_DNDType::CLICK;
}
} else if ( mp.type == E_MousePosType::SEGMENT ) {
auto const& dSeg{ dspSegments[ mp.index ] };
@ -887,6 +901,7 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
selSegment = dSeg.seg;
selPoint = decltype( selPoint ){};
sub = E_SubWindow::SW_SEGMENT;
dnd = E_DNDType::CLICK;
}
} else if ( mp.type == E_MousePosType::POINT ) {
auto const& dPoint{ dspPoints[ mp.index ] };
@ -896,8 +911,8 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
selId = dTrack.id;
selSegment = dSeg.seg;
selPoint = dPoint.index;
selPointDnD = io.MouseDown[ 0 ] && dPoint.index != 0;
if ( selPointDnD ) {
const bool pdnd{ io.MouseDown[ 0 ] && dPoint.index != 0 };
if ( pdnd ) {
assert( selUpdate == E_ChangeType::NONE );
selPointDnDStart = selPointDnDCur = mPixels;
if ( selId->isOverride ) {
@ -910,6 +925,9 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
selUpdatingOriginals.add( *sync.getCurve( selId->id ) );
}
selUpdate = E_ChangeType::POINT_DND;
dnd = E_DNDType::POINT;
} else {
dnd = E_DNDType::CLICK;
}
sub = E_SubWindow::SW_POINT;
}
@ -1013,7 +1031,7 @@ void T_SyncViewImpl_::sequencerBody(
dl->AddRectFilled( inner.Min , inner.Max , ColMain );
dl->AddRect( bb.Min , bb.Max , ColFrame );
if ( zoomInProgress ) {
if ( dnd == E_DNDType::ZOOM ) {
const float z0{ ImClamp( firstZoomPixel - startPixel + inner.Min.x , inner.Min.x , inner.Max.x ) } ,
z1{ ImClamp( curZoomPixel - startPixel + bb.Min.x , inner.Min.x , inner.Max.x ) };
const float zMin{ std::min( z0 , z1 ) } , zMax{ std::max( z0 , z1 ) };
@ -1430,7 +1448,6 @@ bool T_SyncViewImpl_::handlePointDrag(
assert( selUpdate == E_ChangeType::POINT_DND );
selUpdate = E_ChangeType::NONE;
selPointDnD = false;
if ( moved ) {
auto& undo{ dynamic_cast< T_UndoSyncChanges& >(
Common::Undo( ).add< T_UndoSyncChanges >( ) ) };