Sequencer - Points can be moved
This commit is contained in:
parent
052d51a22f
commit
9731adc872
3 changed files with 110 additions and 6 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue