Sequencer - Point insertion/deletion

Also selecting a point no longer explodes.
This commit is contained in:
Emmanuel BENOîT 2017-11-29 11:37:47 +01:00
parent 82100cecc4
commit 0106529e96
3 changed files with 105 additions and 50 deletions

View file

@ -410,64 +410,100 @@ void SyncEditor::SetSegmentTypes(
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void SyncEditor::InsertPoint( void SyncEditor::InsertPoint(
T_String const& id , T_SyncTrackId const& id ,
const uint32_t segmentIndex , const uint32_t segmentIndex ,
const uint32_t pointIndex ) noexcept const uint32_t pointIndex ) noexcept
{ {
auto& sync{ Common::Sync( ) }; auto& sync{ Common::Sync( ) };
auto const* const curve{ sync.getCurve( id ) }; auto const* const ovr{ id.isOverride ? sync.getOverride( id.id ) : nullptr };
if ( !curve || segmentIndex >= curve->segments.size( ) ) { if ( id.isOverride && !ovr ) {
return;
}
auto const& segment{ curve->segments[ segmentIndex ] };
if ( pointIndex == 0 || pointIndex > segment.values.size( )
|| segment.durations[ pointIndex - 1 ] == 1 ) {
return; return;
} }
auto c{ *curve }; const auto nc{ ovr ? ovr->inputNames( ).size( ) : 1 };
auto& ns{ c.segments[ segmentIndex ] }; T_SyncCurve const* curves[ nc ];
if ( ovr ) {
for ( auto i = 0u ; i < nc ; i ++ ) {
curves[ i ] = sync.getCurve( ovr->inputNames( )[ i ] );
}
} else {
curves[ 0 ] = sync.getCurve( id.id );
}
const auto hd{ ns.durations[ pointIndex - 1 ] / 2 }; for ( auto const* curve : curves ) {
const float hv{ ns.computeValue( ns.findTimeOfPoint( pointIndex - 1 ) + hd ) }; if ( !curve || segmentIndex >= curve->segments.size( ) ) {
return;
ns.durations[ pointIndex - 1 ] -= hd; }
ns.durations.insert( pointIndex - 1 , hd ); auto const& segment{ curve->segments[ segmentIndex ] };
ns.values.insert( pointIndex , hv ); if ( pointIndex == 0 || pointIndex > segment.values.size( )
|| segment.durations[ pointIndex - 1 ] == 1 ) {
return;
}
}
auto& undo{ dynamic_cast< T_UndoSyncChanges& >( auto& undo{ dynamic_cast< T_UndoSyncChanges& >(
Common::Undo( ).add< T_UndoSyncChanges >( ) ) }; Common::Undo( ).add< T_UndoSyncChanges >( ) ) };
undo.curveReplacement( *curve , c );
sync.setCurve( std::move( c ) ); for ( auto const* curve : curves ) {
auto c{ *curve };
auto& ns{ c.segments[ segmentIndex ] };
const auto hd{ ns.durations[ pointIndex - 1 ] / 2 };
const float hv{ ns.computeValue( ns.findTimeOfPoint( pointIndex - 1 ) + hd ) };
ns.durations[ pointIndex - 1 ] -= hd;
ns.durations.insert( pointIndex - 1 , hd );
ns.values.insert( pointIndex , hv );
undo.curveReplacement( *curve , c );
sync.setCurve( std::move( c ) );
}
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void SyncEditor::DeletePoint( void SyncEditor::DeletePoint(
T_String const& id , T_SyncTrackId const& id ,
const uint32_t segmentIndex , const uint32_t segmentIndex ,
const uint32_t pointIndex ) noexcept const uint32_t pointIndex ) noexcept
{ {
auto& sync{ Common::Sync( ) }; auto& sync{ Common::Sync( ) };
auto const* const curve{ sync.getCurve( id ) }; auto const* const ovr{ id.isOverride ? sync.getOverride( id.id ) : nullptr };
if ( !curve || segmentIndex >= curve->segments.size( ) ) { if ( id.isOverride && !ovr ) {
return;
}
auto const& segment{ curve->segments[ segmentIndex ] };
if ( pointIndex == 0 || pointIndex >= segment.values.size( ) ) {
return; return;
} }
auto c{ *curve }; const auto nc{ ovr ? ovr->inputNames( ).size( ) : 1 };
auto& ns{ c.segments[ segmentIndex ] }; T_SyncCurve const* curves[ nc ];
ns.durations[ pointIndex ] += ns.durations[ pointIndex - 1 ]; if ( ovr ) {
ns.durations.remove( pointIndex - 1 ); for ( auto i = 0u ; i < nc ; i ++ ) {
ns.values.remove( pointIndex ); curves[ i ] = sync.getCurve( ovr->inputNames( )[ i ] );
}
} else {
curves[ 0 ] = sync.getCurve( id.id );
}
for ( auto const* curve : curves ) {
if ( !curve || segmentIndex >= curve->segments.size( ) ) {
return;
}
auto const& segment{ curve->segments[ segmentIndex ] };
if ( pointIndex == 0 || pointIndex >= segment.values.size( ) ) {
return;
}
}
auto& undo{ dynamic_cast< T_UndoSyncChanges& >( auto& undo{ dynamic_cast< T_UndoSyncChanges& >(
Common::Undo( ).add< T_UndoSyncChanges >( ) ) }; Common::Undo( ).add< T_UndoSyncChanges >( ) ) };
undo.curveReplacement( *curve , c ); for ( auto const* curve : curves ) {
sync.setCurve( std::move( c ) ); auto c{ *curve };
auto& ns{ c.segments[ segmentIndex ] };
ns.durations[ pointIndex ] += ns.durations[ pointIndex - 1 ];
ns.durations.remove( pointIndex - 1 );
ns.values.remove( pointIndex );
undo.curveReplacement( *curve , c );
sync.setCurve( std::move( c ) );
}
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/

View file

@ -154,14 +154,14 @@ struct SyncEditor final
// Insert a point in a segment. The pointIndex parameter indicates the // Insert a point in a segment. The pointIndex parameter indicates the
// index of the new point; it must not be 0 or nbPoints( segment ) // index of the new point; it must not be 0 or nbPoints( segment )
static void InsertPoint( static void InsertPoint(
T_String const& id , T_SyncTrackId const& id ,
uint32_t segmentIndex , uint32_t segmentIndex ,
uint32_t pointIndex ) noexcept; uint32_t pointIndex ) noexcept;
// Delete a point from a segment. The point must not be the first or last // Delete a point from a segment. The point must not be the first or last
// point in the segment. // point in the segment.
static void DeletePoint( static void DeletePoint(
T_String const& id , T_SyncTrackId const& id ,
uint32_t segmentIndex , uint32_t segmentIndex ,
uint32_t pointIndex ) noexcept; uint32_t pointIndex ) noexcept;

View file

@ -743,11 +743,15 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
selSegment = dSeg.seg; selSegment = dSeg.seg;
selPoint = dPoint.index; selPoint = dPoint.index;
selPointDnD = io.MouseDown[ 0 ] && dPoint.index != 0; selPointDnD = io.MouseDown[ 0 ] && dPoint.index != 0;
if ( selPointDnD ) { if ( selPointDnD && !selId->isOverride ) { // XXX
assert( selUpdate == E_ChangeType::NONE ); assert( selUpdate == E_ChangeType::NONE );
selPointDnDStart = selPointDnDCur = mPixels; selPointDnDStart = selPointDnDCur = mPixels;
selUpdatingOriginal = *sync.getCurve( selId->id ); // XXX selUpdatingOriginal = *sync.getCurve( selId->id );
selUpdate = E_ChangeType::POINT_DND; selUpdate = E_ChangeType::POINT_DND;
} else if ( selId->isOverride ) {
printf( "FIXME!\n" );
selPointDnD = false;
#warning blah
} }
sub = E_SubWindow::SW_POINT; sub = E_SubWindow::SW_POINT;
} }
@ -1255,7 +1259,7 @@ T_SyncViewImpl_::T_MousePos T_SyncViewImpl_::getMousePos( ) const noexcept
} }
for ( auto k = 0u ; k < seg.dispPoints ; k ++ ) { for ( auto k = 0u ; k < seg.dispPoints ; k ++ ) {
auto const& p{ dspPoints[ seg.firstPoint + k ] }; auto const& p{ dspPoints[ seg.firstPoint + k ] };
if ( ImLengthSqr( mp - p.center ) <= PointRadiusSqr ) { if ( ImLengthSqr( mp - p.center ) <= PointRadiusSqr * 2.25 ) {
return T_MousePos{ E_MousePosType::POINT , return T_MousePos{ E_MousePosType::POINT ,
seg.firstPoint + k }; seg.firstPoint + k };
} }
@ -1844,14 +1848,23 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
const uint32_t sid{ *selSegment }; const uint32_t sid{ *selSegment };
const uint32_t pid{ *selPoint }; const uint32_t pid{ *selPoint };
auto& sync{ Common::Sync( ) }; auto& sync{ Common::Sync( ) };
auto const* const ovr{ selId->isOverride
? sync.getOverride( selId->id )
: nullptr };
auto const* const curve{ selUpdatingCopy auto const* const curve{ selUpdatingCopy
? selUpdatingCopy.target( ) ? selUpdatingCopy.target( )
: sync.getCurve( selId->id ) }; : sync.getCurve( ovr ? ovr->inputNames( )[ 0 ] : selId->id ) };
auto const& segment{ curve->segments[ sid ] }; auto const& segment{ curve->segments[ sid ] };
Text( "Curve:" ); if ( selId->isOverride ) {
SameLine( 110 ); Text( "Override:" );
Text( "%s" , selId->id.toOSString( ).data( ) ); SameLine( 110 );
Text( "%s" , ovr->title( ) );
} else {
Text( "Curve:" );
SameLine( 110 );
Text( "%s" , selId->id.toOSString( ).data( ) );
}
Text( "Segment index:" ); Text( "Segment index:" );
SameLine( 110 ); SameLine( 110 );
@ -1895,13 +1908,19 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
Separator( ); Separator( );
Text( "Value:" ); bool changed;
SameLine( 110 );
float value{ segment.values[ pid ] }; float value{ segment.values[ pid ] };
PushItemWidth( -1 ); if ( ovr ) {
DragFloat( "##value" , &value , .01f , 0 , 0 , "%.6f" ); // XXX override control
const bool changed{ IsItemActive( ) }; changed = false;
PopItemWidth( ); } else {
Text( "Value:" );
SameLine( 110 );
PushItemWidth( -1 );
DragFloat( "##value" , &value , .01f , 0 , 0 , "%.6f" );
changed = IsItemActive( );
PopItemWidth( );
}
const bool canUseButtons{ !changed && selUpdate == E_ChangeType::NONE }; const bool canUseButtons{ !changed && selUpdate == E_ChangeType::NONE };
const auto canInsertBefore{ pid != 0 const auto canInsertBefore{ pid != 0
@ -1913,7 +1932,7 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
Text( " " ); Text( " " );
SameLine( 110 ); SameLine( 110 );
if ( Button( "Delete point" , ImVec2{ -1 , 0 } ) && canUseButtons ) { if ( Button( "Delete point" , ImVec2{ -1 , 0 } ) && canUseButtons ) {
SyncEditor::DeletePoint( selId->id , sid , pid ); SyncEditor::DeletePoint( *selId , sid , pid );
selPoint.clear( ); selPoint.clear( );
sub = SW_SEGMENT; sub = SW_SEGMENT;
} }
@ -1925,7 +1944,7 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
Text( " " ); Text( " " );
SameLine( 110 ); SameLine( 110 );
if ( Button( "Insert before" , ImVec2{ -1 , 0 } ) && canUseButtons ) { if ( Button( "Insert before" , ImVec2{ -1 , 0 } ) && canUseButtons ) {
SyncEditor::InsertPoint( selId->id , sid , pid ); SyncEditor::InsertPoint( *selId , sid , pid );
(*selPoint) ++; (*selPoint) ++;
} }
} }
@ -1933,7 +1952,7 @@ void T_SyncViewImpl_::displayPointWindow( ) noexcept
Text( " " ); Text( " " );
SameLine( 110 ); SameLine( 110 );
if ( Button( "Insert after" , ImVec2{ -1 , 0 } ) && canUseButtons ) { if ( Button( "Insert after" , ImVec2{ -1 , 0 } ) && canUseButtons ) {
SyncEditor::InsertPoint( selId->id , sid , pid + 1 ); SyncEditor::InsertPoint( *selId , sid , pid + 1 );
} }
} }
} }