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(
T_String const& id ,
T_SyncTrackId const& id ,
const uint32_t segmentIndex ,
const uint32_t pointIndex ) noexcept
{
auto& sync{ Common::Sync( ) };
auto const* const curve{ sync.getCurve( id ) };
if ( !curve || segmentIndex >= curve->segments.size( ) ) {
return;
}
auto const& segment{ curve->segments[ segmentIndex ] };
if ( pointIndex == 0 || pointIndex > segment.values.size( )
|| segment.durations[ pointIndex - 1 ] == 1 ) {
auto const* const ovr{ id.isOverride ? sync.getOverride( id.id ) : nullptr };
if ( id.isOverride && !ovr ) {
return;
}
auto c{ *curve };
auto& ns{ c.segments[ segmentIndex ] };
const auto nc{ ovr ? ovr->inputNames( ).size( ) : 1 };
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 };
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 );
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( )
|| segment.durations[ pointIndex - 1 ] == 1 ) {
return;
}
}
auto& undo{ dynamic_cast< 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(
T_String const& id ,
T_SyncTrackId const& id ,
const uint32_t segmentIndex ,
const uint32_t pointIndex ) noexcept
{
auto& sync{ Common::Sync( ) };
auto const* const curve{ sync.getCurve( id ) };
if ( !curve || segmentIndex >= curve->segments.size( ) ) {
return;
}
auto const& segment{ curve->segments[ segmentIndex ] };
if ( pointIndex == 0 || pointIndex >= segment.values.size( ) ) {
auto const* const ovr{ id.isOverride ? sync.getOverride( id.id ) : nullptr };
if ( id.isOverride && !ovr ) {
return;
}
auto c{ *curve };
auto& ns{ c.segments[ segmentIndex ] };
ns.durations[ pointIndex ] += ns.durations[ pointIndex - 1 ];
ns.durations.remove( pointIndex - 1 );
ns.values.remove( pointIndex );
const auto nc{ ovr ? ovr->inputNames( ).size( ) : 1 };
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 );
}
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& >(
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 ] };
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
// index of the new point; it must not be 0 or nbPoints( segment )
static void InsertPoint(
T_String const& id ,
T_SyncTrackId const& id ,
uint32_t segmentIndex ,
uint32_t pointIndex ) noexcept;
// Delete a point from a segment. The point must not be the first or last
// point in the segment.
static void DeletePoint(
T_String const& id ,
T_SyncTrackId const& id ,
uint32_t segmentIndex ,
uint32_t pointIndex ) noexcept;

View file

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