Sequencer - Points can be moved

This commit is contained in:
Emmanuel BENOîT 2017-11-26 13:46:46 +01:00
parent 052d51a22f
commit 9731adc872
3 changed files with 110 additions and 6 deletions

View file

@ -172,6 +172,23 @@ void SyncEditor::SetDuration(
/*----------------------------------------------------------------------------*/
void SyncEditor::ReplaceCurve(
T_SyncCurve replacement ) noexcept
{
auto* const curve{ Common::Sync( ).getCurve( replacement.name ) };
if ( !curve ) {
return;
}
// Create undo entry
auto& undo{ dynamic_cast< T_UndoSyncChanges& >(
Common::Undo( ).add< T_UndoSyncChanges >( ) ) };
undo.curveReplacement( std::move( *curve ) , replacement );
Common::Sync( ).setCurve( std::move( replacement ) );
}
/*----------------------------------------------------------------------------*/
void SyncEditor::DeleteCurve(
T_String const& id ) noexcept
{

View file

@ -92,6 +92,10 @@ struct SyncEditor final
//----------------------------------------------------------------------
// Replaces a curve with a new record
static void ReplaceCurve(
T_SyncCurve replacement ) noexcept;
// Delete a curve's record completely.
static void DeleteCurve(
T_String const& id ) noexcept;

View file

@ -233,6 +233,9 @@ struct T_SyncViewImpl_
void displayTooltips(
const float time ) noexcept;
bool handlePointDrag(
const float mPixels ,
bool mouseDown ) noexcept;
T_MousePos getMousePos( ) const noexcept;
@ -254,6 +257,8 @@ struct T_SyncViewImpl_
const uint32_t ColHeaderText{ ImGui::GetColorU32( ImVec4{ 0 , 0 , 0 , 1 } ) };
const uint32_t ColMain{ ImGui::GetColorU32( ImVec4{ .4 , .4 , .4 , .8 } ) };
const uint32_t ColSelection{ ImGui::GetColorU32( ImVec4{ .8 , 1 , .8 , .2 } ) };
const uint32_t ColPointNormal{ ImGui::GetColorU32( ImVec4{ 0 , 0 , 0 , .25 } ) };
const uint32_t ColPointSelected{ ImGui::GetColorU32( ImVec4{ 0 , 0 , 0 , .75 } ) };
const ImVec2 BtSize{ 20 , 0 };
// Sequencer settings
@ -289,6 +294,10 @@ struct T_SyncViewImpl_
bool selIsOverride;
T_Optional< uint32_t > selSegment;
T_Optional< uint32_t > selPoint;
bool selPointDnD{ false };
float selPointDnDStart , selPointDnDCur;
T_Optional< T_SyncCurve > selPointDnDOriginal;
T_Optional< T_SyncCurve > selPointDnDCopy;
// Sub-windows
E_SubWindow sub{ SW_NONE };
@ -536,6 +545,10 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
}
}
if ( selPointDnD && handlePointDrag( mPixels , io.MouseDown[ 0 ] ) ) {
return;
}
if ( !( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
ClearActiveID( );
return;
@ -573,6 +586,23 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
selPoint = decltype( selPoint ){};
sub = E_SubWindow::SW_SEGMENT;
}
} else if ( mp.type == E_MousePosType::POINT ) {
auto const& dPoint{ dspPoints[ mp.index ] };
auto const& dSeg{ dspSegments[ dPoint.seg ] };
auto const& dTrack{ dspTracks[ dSeg.track ] };
if ( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) {
selId = dTrack.id;
selIsOverride = dTrack.isOverride;
selSegment = dSeg.seg;
selPoint = dPoint.index;
selPointDnD = io.MouseDown[ 0 ] && dPoint.index != 0;
if ( selPointDnD ) {
selPointDnDStart = selPointDnDCur = mPixels;
selPointDnDOriginal = *sync.getCurve( dTrack.id ); // XXX
}
// sub = E_SubWindow::SW_SEGMENT;
#warning fix that shit
}
}
}
@ -803,10 +833,13 @@ void T_SyncViewImpl_::sequencerTrack(
// If there's a curve, go through all segments
const auto units{ Common::Sync( ).durationUnits( ) };
const auto nSeg{ curve ? curve->segments.size( ) : 0u };
const bool useCopy{ sCurve && curve && selPointDnDCopy };
const auto nSeg{ curve
? ( useCopy ? *selPointDnDCopy : *curve ).segments.size( )
: 0u };
uint32_t segStart{ 0 };
for ( auto i = 0u ; i < nSeg ; i ++ ) {
auto const& seg{ curve->segments[ i ] };
auto const& seg{ ( useCopy ? *selPointDnDCopy : *curve ).segments[ i ] };
const auto segDur{ [&](){
auto t{ 0u };
for ( auto d : seg.durations ) {
@ -827,9 +860,6 @@ void T_SyncViewImpl_::sequencerTrack(
// Add segment to displayed list
const bool sSegment{ sCurve && selSegment && *selSegment == i };
if ( sSegment ) {
printf( "SelSeg! %d\n" , *selSegment );
}
const auto color{ segColors[ i % 2 + ( sSegment ? 2 : 0 ) ] };
auto dSegIdx{ dspSegments.size( ) };
auto& dSeg{ dspSegments.addNew( ) };
@ -857,7 +887,9 @@ void T_SyncViewImpl_::sequencerTrack(
std::roundf( xStart + cDur * totalPixels / units ) ,
ym
};
dl->AddCircleFilled( ctr , PointRadius , 0x7f000000 ); // XXX color
const bool sPoint{ sSegment && selPoint && *selPoint == j };
dl->AddCircleFilled( ctr , PointRadius ,
sPoint ? ColPointSelected : ColPointNormal );
cDur += j < nd ? seg.durations[ j ] : 0;
// Add point record
@ -960,6 +992,57 @@ void T_SyncViewImpl_::displayTooltips(
EndTooltip( );
}
bool T_SyncViewImpl_::handlePointDrag(
const float mPixels ,
bool mouseDown ) noexcept
{
auto& sync( Common::Sync( ) );
selPointDnDCur = mPixels;
const float diff{ selPointDnDCur - selPointDnDStart };
const int32_t diffUnits{ int32_t( round( diff * sync.durationUnits( ) / totalPixels ) ) };
const bool moved{ fabsf( diff ) >= 2 && abs( diffUnits ) > 0 };
// Update the point as necessary
if ( moved ) {
selPointDnDCopy = selPointDnDOriginal; // XXX
auto& seg{ selPointDnDCopy->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;
}
sync.setCurve( *selPointDnDCopy );
} else {
selPointDnDCopy.clear( );
}
if ( mouseDown ) {
return true;
}
selPointDnD = false;
sync.setCurve( std::move( *selPointDnDOriginal ) );
selPointDnDOriginal.clear( );
if ( moved ) {
SyncEditor::ReplaceCurve( std::move( *selPointDnDCopy ) );
selPointDnDCopy.clear( );
}
return false;
}
/*----------------------------------------------------------------------------*/
T_SyncViewImpl_::T_MousePos T_SyncViewImpl_::getMousePos( ) const noexcept