Sequencer - Right click selection zoom
This commit is contained in:
parent
dd0403ab1c
commit
5916e9f61c
1 changed files with 77 additions and 8 deletions
85
syncview.cc
85
syncview.cc
|
@ -21,6 +21,7 @@ struct T_SyncViewImpl_
|
||||||
const uint32_t ColHeader{ ImGui::GetColorU32( ImVec4{ .5 , .5 , .5 , .8 } ) };
|
const uint32_t ColHeader{ ImGui::GetColorU32( ImVec4{ .5 , .5 , .5 , .8 } ) };
|
||||||
const uint32_t ColHeaderText{ ImGui::GetColorU32( ImVec4{ 0 , 0 , 0 , 1 } ) };
|
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 ColMain{ ImGui::GetColorU32( ImVec4{ .4 , .4 , .4 , .8 } ) };
|
||||||
|
const uint32_t ColSelection{ ImGui::GetColorU32( ImVec4{ .8 , 1 , .8 , .2 } ) };
|
||||||
|
|
||||||
float zoomLevel{ 0.f };
|
float zoomLevel{ 0.f };
|
||||||
float startPos{ 0.f };
|
float startPos{ 0.f };
|
||||||
|
@ -38,8 +39,18 @@ struct T_SyncViewImpl_
|
||||||
uint32_t startBar;
|
uint32_t startBar;
|
||||||
float startBarPos;
|
float startBarPos;
|
||||||
float timePerBar;
|
float timePerBar;
|
||||||
|
float totalPixels;
|
||||||
|
float startPixel;
|
||||||
|
|
||||||
|
// Zoom area selection
|
||||||
|
bool zoomInProgress{ false };
|
||||||
|
bool justZoomed{ false };
|
||||||
|
float firstZoomPixel;
|
||||||
|
float curZoomPixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr float T_SyncViewImpl_::BarWidth;
|
||||||
|
|
||||||
|
|
||||||
bool T_SyncViewImpl_::display( ) noexcept
|
bool T_SyncViewImpl_::display( ) noexcept
|
||||||
{
|
{
|
||||||
|
@ -122,14 +133,13 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
|
||||||
if ( !ItemAdd( bbAll , seqId ) ) {
|
if ( !ItemAdd( bbAll , seqId ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const bool hovered{ ItemHoverable( bbAll , seqId ) };
|
||||||
computeMetrics( std::max( 0.f , width - 2.f ) );
|
computeMetrics( std::max( 0.f , width - 2.f ) );
|
||||||
|
|
||||||
PushID( seqId );
|
|
||||||
BeginGroup( );
|
BeginGroup( );
|
||||||
|
|
||||||
const auto hdrId{ win->GetID( "##header" ) };
|
const auto hdrId{ win->GetID( "##header" ) };
|
||||||
const auto dspId{ win->GetID( "##display" ) };
|
const auto dspId{ win->GetID( "##display" ) };
|
||||||
|
PushID( seqId );
|
||||||
if ( ItemAdd( bbHeader , hdrId ) ) {
|
if ( ItemAdd( bbHeader , hdrId ) ) {
|
||||||
PushID( hdrId );
|
PushID( hdrId );
|
||||||
sequencerHeader( bbHeader );
|
sequencerHeader( bbHeader );
|
||||||
|
@ -140,9 +150,53 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
|
||||||
sequencerBody( bbDisplay );
|
sequencerBody( bbDisplay );
|
||||||
PopID( );
|
PopID( );
|
||||||
}
|
}
|
||||||
|
PopID( );
|
||||||
|
|
||||||
|
auto& io( GetIO( ) );
|
||||||
|
if ( hovered && ( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
|
||||||
|
SetActiveID( seqId , win );
|
||||||
|
FocusWindow( win );
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool active( GetCurrentContext( )->ActiveId == seqId );
|
||||||
|
if ( active ) {
|
||||||
|
if ( io.MouseDown[ 0 ] ) {
|
||||||
|
const float p{ io.MousePos.x - bbAll.Min.x + startPixel };
|
||||||
|
auto& sync( Globals::Sync( ) );
|
||||||
|
sync.setTime( p * Globals::Sync( ).duration( ) / totalPixels );
|
||||||
|
}
|
||||||
|
if ( io.MouseDown[ 1 ] ) {
|
||||||
|
const float p{ io.MousePos.x - bbAll.Min.x + startPixel };
|
||||||
|
if ( !zoomInProgress ) {
|
||||||
|
firstZoomPixel = p;
|
||||||
|
zoomInProgress = true;
|
||||||
|
}
|
||||||
|
curZoomPixel = p;
|
||||||
|
} else if ( zoomInProgress ) {
|
||||||
|
zoomInProgress = false;
|
||||||
|
justZoomed = true;
|
||||||
|
const auto zMin{ std::min( firstZoomPixel , curZoomPixel ) } ,
|
||||||
|
zMax{ std::max( firstZoomPixel , curZoomPixel ) } ,
|
||||||
|
diff{ zMax - zMin };
|
||||||
|
if ( diff > 4 ) {
|
||||||
|
auto& sync( Globals::Sync( ) );
|
||||||
|
const float u( sync.durationUnits( ) );
|
||||||
|
startPos = zMin * u / totalPixels;
|
||||||
|
if ( ( width - 2.f ) / u >= BarWidth ) {
|
||||||
|
zoomLevel = 0;
|
||||||
|
} else {
|
||||||
|
const auto length{ std::min( u , diff * u / totalPixels ) };
|
||||||
|
const auto ppu{ std::min( ( width - 2 ) / length , BarWidth ) };
|
||||||
|
zoomLevel = ( ppu - BarWidth ) / ( BarWidth - width / u ) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
|
||||||
|
ClearActiveID( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EndGroup( );
|
EndGroup( );
|
||||||
PopID( );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_SyncViewImpl_::computeMetrics(
|
void T_SyncViewImpl_::computeMetrics(
|
||||||
|
@ -152,7 +206,7 @@ void T_SyncViewImpl_::computeMetrics(
|
||||||
const uint32_t units{ sync.durationUnits( ) };
|
const uint32_t units{ sync.durationUnits( ) };
|
||||||
zoomLevel = ImSaturate( zoomLevel );
|
zoomLevel = ImSaturate( zoomLevel );
|
||||||
const float zoom1Pixels{ std::max( units * BarWidth , innerWidth ) };
|
const float zoom1Pixels{ std::max( units * BarWidth , innerWidth ) };
|
||||||
const float totalPixels{ zoomLevel * ( zoom1Pixels - innerWidth ) + innerWidth };
|
totalPixels = zoomLevel * ( zoom1Pixels - innerWidth ) + innerWidth;
|
||||||
const uint32_t totalBars{ [=](){
|
const uint32_t totalBars{ [=](){
|
||||||
const float b{ std::max( std::min( totalPixels / BarWidth , float( units ) ) , 1.f ) };
|
const float b{ std::max( std::min( totalPixels / BarWidth , float( units ) ) , 1.f ) };
|
||||||
const float mod{ fmod( b , 1.f ) };
|
const float mod{ fmod( b , 1.f ) };
|
||||||
|
@ -169,14 +223,18 @@ void T_SyncViewImpl_::computeMetrics(
|
||||||
const float spp{ startPos * totalPixels / units };
|
const float spp{ startPos * totalPixels / units };
|
||||||
const float epp{ endPos * totalPixels / units };
|
const float epp{ endPos * totalPixels / units };
|
||||||
if ( absCursorPos < spp || absCursorPos > epp ) {
|
if ( absCursorPos < spp || absCursorPos > epp ) {
|
||||||
startPos = std::max( 0.f , sync.time( ) / uSize - unitsPerBar * .5f );
|
if ( justZoomed ) {
|
||||||
|
followTime = false;
|
||||||
|
} else {
|
||||||
|
startPos = std::max( 0.f , sync.time( ) / uSize - unitsPerBar * .5f );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const float unadjustedStartPixel{ totalPixels * startPos / units };
|
const float unadjustedStartPixel{ totalPixels * startPos / units };
|
||||||
if ( unadjustedStartPixel + innerWidth > totalPixels ) {
|
if ( unadjustedStartPixel + innerWidth > totalPixels ) {
|
||||||
startPos = std::max( 0.f , totalPixels - innerWidth );
|
startPos = std::max( 0.f , totalPixels - innerWidth );
|
||||||
}
|
}
|
||||||
const float startPixel{ totalPixels * startPos / units };
|
startPixel = totalPixels * startPos / units;
|
||||||
startBar = [=](){
|
startBar = [=](){
|
||||||
const float b{ startPixel * totalBars / totalPixels };
|
const float b{ startPixel * totalBars / totalPixels };
|
||||||
const float mod{ fmod( b , 1.f ) };
|
const float mod{ fmod( b , 1.f ) };
|
||||||
|
@ -185,9 +243,10 @@ void T_SyncViewImpl_::computeMetrics(
|
||||||
startBarPos = startBar * barWidth - startPixel;
|
startBarPos = startBar * barWidth - startPixel;
|
||||||
cursorPos = absCursorPos - startPixel;
|
cursorPos = absCursorPos - startPixel;
|
||||||
timePerBar = unitsPerBar * sync.durationUnitSize( );
|
timePerBar = unitsPerBar * sync.durationUnitSize( );
|
||||||
printf( "Z: %f; P@zl1: %f; Pt: %f; Bt: %d; U/B: %f; Bw: %f; Sp: %f; Sb: %d, SbP: %f\n" , zoomLevel , zoom1Pixels , totalPixels , totalBars , unitsPerBar , barWidth , startPixel , startBar , startBarPos );
|
|
||||||
assert( startBarPos <= 0 );
|
assert( startBarPos <= 0 );
|
||||||
assert( totalPixels >= innerWidth );
|
assert( totalPixels >= innerWidth );
|
||||||
|
|
||||||
|
justZoomed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void T_SyncViewImpl_::sequencerHeader(
|
void T_SyncViewImpl_::sequencerHeader(
|
||||||
|
@ -241,6 +300,16 @@ void T_SyncViewImpl_::sequencerBody(
|
||||||
|
|
||||||
dl->AddRectFilled( inner.Min , inner.Max , ColMain );
|
dl->AddRectFilled( inner.Min , inner.Max , ColMain );
|
||||||
dl->AddRect( bb.Min , bb.Max , ColFrame );
|
dl->AddRect( bb.Min , bb.Max , ColFrame );
|
||||||
|
if ( zoomInProgress ) {
|
||||||
|
const float z0{ ImClamp( firstZoomPixel - startPixel + inner.Min.x , inner.Min.x , inner.Max.x ) } ,
|
||||||
|
z1{ ImClamp( curZoomPixel - startPixel + bb.Min.x , inner.Min.x , inner.Max.x ) };
|
||||||
|
const float zMin{ std::min( z0 , z1 ) } , zMax{ std::max( z0 , z1 ) };
|
||||||
|
if ( zMin != zMax ) {
|
||||||
|
dl->AddRectFilled( ImVec2{ zMin , inner.Min.y } ,
|
||||||
|
ImVec2{ zMax , inner.Max.y } ,
|
||||||
|
ColSelection );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto pos{ startBarPos };
|
auto pos{ startBarPos };
|
||||||
auto bar{ startBar };
|
auto bar{ startBar };
|
||||||
|
|
Loading…
Reference in a new issue