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(
|
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 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue