Sequencer - Point insertion/deletion
Also selecting a point no longer explodes.
This commit is contained in:
parent
82100cecc4
commit
0106529e96
3 changed files with 105 additions and 50 deletions
100
c-syncedit.cc
100
c-syncedit.cc
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue