Sequencer - Very primitive track display
There are pieces of disabled mouse handling code in the display code.
This commit is contained in:
parent
aa84f95727
commit
2cfc80a6e4
3 changed files with 220 additions and 20 deletions
218
ui-sequencer.cc
218
ui-sequencer.cc
|
@ -135,8 +135,10 @@ bool T_ChangeDurationDialog_::onButton(
|
|||
|
||||
struct T_SyncViewImpl_
|
||||
{
|
||||
static constexpr float SeqHeaderHeight = 24;
|
||||
static constexpr float BarWidth = 40;
|
||||
static constexpr float SeqHeaderHeight = 24.f;
|
||||
static constexpr float BarWidth = 40.f;
|
||||
static constexpr float TrackHeight = 15.f;
|
||||
static constexpr float TrackPadding = 2.f;
|
||||
|
||||
bool display( ) noexcept;
|
||||
|
||||
|
@ -148,9 +150,17 @@ struct T_SyncViewImpl_
|
|||
void computeMetrics( float innerWidth ) noexcept;
|
||||
void sequencerWidget( ) noexcept;
|
||||
void sequencerHeader( ImRect const& bb ) noexcept;
|
||||
void sequencerBody( ImRect const& bb ) noexcept;
|
||||
void sequencerCurves( ) noexcept;
|
||||
void sequencerCurve( T_SyncCurve const& curve ) noexcept;
|
||||
bool sequencerBody( ImRect const& bb ) noexcept;
|
||||
bool sequencerTracks(
|
||||
float& hue ,
|
||||
ImRect& bb ,
|
||||
ImRect const& container ) noexcept;
|
||||
bool sequencerTrack(
|
||||
float& hue ,
|
||||
ImRect const& bb ,
|
||||
ImRect const& container ,
|
||||
T_String const& name ,
|
||||
T_SyncCurve const* curve ) noexcept;
|
||||
|
||||
void displayCurveSelectorWindow( ) noexcept;
|
||||
void displayCurveSelector( ) noexcept;
|
||||
|
@ -225,12 +235,9 @@ bool T_SyncViewImpl_::display( ) noexcept
|
|||
//----------------------------------------------------------------------
|
||||
// Sequencer widget & subwindows
|
||||
|
||||
BeginChild( "##sequencer" , ImVec2{ 0 , 0 } , false ,
|
||||
ImGuiWindowFlags_NoScrollWithMouse );
|
||||
PushItemWidth( -1 );
|
||||
sequencerWidget( );
|
||||
PopItemWidth( );
|
||||
EndChild( );
|
||||
End( );
|
||||
|
||||
switch ( sub ) {
|
||||
|
@ -380,12 +387,17 @@ void T_SyncViewImpl_::sequencerWidget( ) noexcept
|
|||
sequencerHeader( bbHeader );
|
||||
PopID( );
|
||||
}
|
||||
bool mouseConsumed{ false };
|
||||
if ( bbDisplay.Min.y < bbDisplay.Max.y && ItemAdd( bbDisplay , dspId ) ) {
|
||||
PushID( dspId );
|
||||
sequencerBody( bbDisplay );
|
||||
mouseConsumed = sequencerBody( bbDisplay );
|
||||
PopID( );
|
||||
}
|
||||
PopID( );
|
||||
if ( mouseConsumed ) {
|
||||
EndGroup( );
|
||||
return;
|
||||
}
|
||||
|
||||
auto& io( GetIO( ) );
|
||||
if ( hovered && ( io.MouseDown[ 0 ] || io.MouseDown[ 1 ] ) ) {
|
||||
|
@ -528,7 +540,7 @@ void T_SyncViewImpl_::sequencerHeader(
|
|||
PopFont( );
|
||||
}
|
||||
|
||||
void T_SyncViewImpl_::sequencerBody(
|
||||
bool T_SyncViewImpl_::sequencerBody(
|
||||
ImRect const& bb ) noexcept
|
||||
{
|
||||
using namespace ImGui;
|
||||
|
@ -562,11 +574,18 @@ void T_SyncViewImpl_::sequencerBody(
|
|||
}
|
||||
|
||||
// Display the curve / override controls
|
||||
bool mouseConsumed{ false };
|
||||
if ( sCurves.size( ) != 0 ) {
|
||||
BeginGroup( );
|
||||
|
||||
ImRect subBb{ inner };
|
||||
// FIXME scroll
|
||||
subBb.Min.y += TrackPadding;
|
||||
subBb.Max.y = subBb.Min.y + TrackHeight;
|
||||
|
||||
float hue{ 0.12f };
|
||||
|
||||
// TODO: display overrides
|
||||
sequencerCurves( );
|
||||
EndGroup( );
|
||||
mouseConsumed = sequencerTracks( hue , subBb , inner ) || mouseConsumed;
|
||||
}
|
||||
|
||||
if ( cursorPos >= 0 && cursorPos <= inner.GetWidth( ) ) {
|
||||
|
@ -575,26 +594,185 @@ void T_SyncViewImpl_::sequencerBody(
|
|||
ImVec2{ inner.Min.x + cursorPos , inner.Max.y - 1 } ,
|
||||
0xffffffff );
|
||||
}
|
||||
|
||||
return mouseConsumed;
|
||||
}
|
||||
|
||||
void T_SyncViewImpl_::sequencerCurves( ) noexcept
|
||||
bool T_SyncViewImpl_::sequencerTracks(
|
||||
float& hue ,
|
||||
ImRect& subBb ,
|
||||
ImRect const& container ) noexcept
|
||||
{
|
||||
auto& sync{ Common::Sync( ) };
|
||||
const auto nc{ sCurves.size( ) };
|
||||
bool mouseConsumed{ false };
|
||||
for ( auto i = 0u ; i < nc ; i ++ ) {
|
||||
if ( sCurves.values( )[ i ] ) {
|
||||
continue;
|
||||
}
|
||||
auto* const curve{ sync.getCurve( sCurves.keys( )[ i ] ) };
|
||||
assert( curve );
|
||||
sequencerCurve( *curve );
|
||||
|
||||
auto const& name{ sCurves.keys( )[ i ] };
|
||||
auto* const curve{ sync.getCurve( name ) };
|
||||
mouseConsumed = sequencerTrack( hue , subBb , container , name , curve )
|
||||
|| mouseConsumed;
|
||||
subBb.Min.y += TrackHeight + 2 * TrackPadding;
|
||||
subBb.Max.y += TrackHeight + 2 * TrackPadding;
|
||||
hue = fmodf( hue + .17f , 1.f );
|
||||
}
|
||||
return mouseConsumed;
|
||||
}
|
||||
|
||||
void T_SyncViewImpl_::sequencerCurve(
|
||||
T_SyncCurve const& curve ) noexcept
|
||||
bool T_SyncViewImpl_::sequencerTrack(
|
||||
float& hue ,
|
||||
ImRect const& bb ,
|
||||
ImRect const& container ,
|
||||
T_String const& name ,
|
||||
T_SyncCurve const* curve ) noexcept
|
||||
{
|
||||
#warning implement the fuck
|
||||
using namespace ImGui;
|
||||
if ( !container.Overlaps( bb ) ) {
|
||||
return false;
|
||||
}
|
||||
auto* const dl{ GetWindowDrawList( ) };
|
||||
|
||||
// Compute colors
|
||||
const auto bgColor{ ColorHSVAToU32( hue , .25f , 1.f , .25f ) } ,
|
||||
borderColor{ ColorHSVAToU32( hue , .12f , 1.f , 1.f ) };
|
||||
const uint32_t segColors[ 2 ] = {
|
||||
ColorHSVAToU32( hue - .03f , .4f , 1.f , 1.f ) ,
|
||||
ColorHSVAToU32( hue + .03f , .4f , 1.f , 1.f ) ,
|
||||
};
|
||||
|
||||
// Draw the bar itself
|
||||
const ImRect bar{
|
||||
ImVec2{ ImFloor( bb.Min.x ) ,
|
||||
ImFloor( ImMax( container.Min.y , bb.Min.y ) ) } ,
|
||||
ImVec2{ ImFloor( bb.Max.x ) - 1 ,
|
||||
ImFloor( ImMin( container.Max.y , bb.Max.y ) ) }
|
||||
};
|
||||
dl->AddRectFilled( bar.Min , bar.Max , bgColor );
|
||||
if ( container.Contains( bb.GetTL( ) ) ) {
|
||||
dl->AddLine( bar.GetTL( ) , bar.GetTR( ) , borderColor );
|
||||
}
|
||||
if ( container.Contains( bb.GetBL( ) ) ) {
|
||||
dl->AddLine( bar.GetBL( ) , bar.GetBR( ) , borderColor );
|
||||
}
|
||||
// Left only has a border if this is the start
|
||||
if ( startPos == 0.f ) {
|
||||
dl->AddLine( bar.GetTL( ) , bar.GetBL( ) , borderColor );
|
||||
}
|
||||
// Right has a border if the end is being displayed.
|
||||
if ( startPixel + container.GetWidth( ) >= totalPixels ) {
|
||||
dl->AddLine( bar.GetTR( ) , bar.GetBR( ) , borderColor );
|
||||
}
|
||||
dl->PushClipRect( bar.Min , bar.Max );
|
||||
|
||||
#if 0
|
||||
// We'll need to display the right pop-up
|
||||
auto& io( GetIO( ) );
|
||||
const auto mPos{ io.MousePos };
|
||||
bool mousePosUsed{ false } , mouseConsumed{ false };
|
||||
#endif
|
||||
|
||||
// If there's a curve, go through all segments
|
||||
const auto units{ Common::Sync( ).durationUnits( ) };
|
||||
const auto nSeg{ curve ? curve->segments.size( ) : 0u };
|
||||
uint32_t segStart{ 0 };
|
||||
for ( auto i = 0u ; i < nSeg ; i ++ ) {
|
||||
const auto color{ segColors[ i % 2 ] };
|
||||
auto const& seg{ curve->segments[ i ] };
|
||||
const auto segDur{ [&](){
|
||||
auto t{ 0u };
|
||||
for ( auto d : seg.durations ) {
|
||||
t += d;
|
||||
}
|
||||
return t;
|
||||
}() };
|
||||
const float xStart{ ImFloor( container.Min.x + ( segStart - startPos ) * totalPixels / units ) };
|
||||
const float xEnd{ xStart + ImFloor( segDur * totalPixels / units ) };
|
||||
const ImRect segFull{
|
||||
ImVec2{ xStart , bar.Min.y + 1 } ,
|
||||
ImVec2{ xEnd , bar.Max.y }
|
||||
};
|
||||
segStart += segDur;
|
||||
if ( !segFull.Overlaps( bar ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const ImRect segBar{
|
||||
ImVec2{ ImMax( bar.Min.x , segFull.Min.x ) , segFull.Min.y } ,
|
||||
ImVec2{ ImMin( bar.Max.x , segFull.Max.x ) , segFull.Max.y }
|
||||
};
|
||||
dl->AddRectFilled( segBar.Min , segBar.Max , color );
|
||||
dl->PushClipRect( segBar.Min , segBar.Max );
|
||||
|
||||
const auto nd{ seg.durations.size( ) };
|
||||
const auto radius{ ( TrackHeight - 2.f ) * .5f };
|
||||
const auto ym{ bb.Min.y + radius + 1 };
|
||||
auto cDur{ 0 };
|
||||
for ( auto j = 0u ; j < nd + 1 ; j ++ ) {
|
||||
const ImVec2 ctr{
|
||||
std::roundf( xStart + cDur * totalPixels / units ) ,
|
||||
ym
|
||||
};
|
||||
dl->AddCircleFilled( ctr , radius , 0x7f000000 ); // XXX color
|
||||
#if 0
|
||||
if ( ImLengthSqr( mPos - ctr ) <= radius * radius ) {
|
||||
if ( ! mousePosUsed ) {
|
||||
BeginTooltip( );
|
||||
stringBuffer.clear( ) << name << " (input)\nIn "
|
||||
<< seg.type << " segment\nAt " << segDur
|
||||
<< " units\nValue: " << seg.values[ j ];
|
||||
Text( "%s" , stringBuffer.data( ) );
|
||||
EndTooltip( );
|
||||
mousePosUsed = true;
|
||||
}
|
||||
if ( !mouseConsumed && io.MouseDown[ 0 ] ) {
|
||||
printf( "fuck yeah!\n" );
|
||||
mouseConsumed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
cDur += j < nd ? seg.durations[ j ] : 0;
|
||||
}
|
||||
dl->PopClipRect( );
|
||||
|
||||
#if 0
|
||||
if ( segBar.Contains( mPos ) && !mousePosUsed ) {
|
||||
BeginTooltip( );
|
||||
stringBuffer.clear( ) << name << " (input)\nIn "
|
||||
<< seg.type << " segment\nDuration: "
|
||||
<< segDur << " units (from " << ( segStart - segDur )
|
||||
<< " to " << ( segStart - 1 )
|
||||
<< ")\n";
|
||||
Text( "%s" , stringBuffer.data( ) );
|
||||
EndTooltip( );
|
||||
mousePosUsed = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( bar.Contains( mPos ) && !mousePosUsed ) {
|
||||
const float time{ ( io.MousePos.x - container.Min.x + startPixel )
|
||||
* units / totalPixels };
|
||||
const float msf{ fmod( time , 1.f ) };
|
||||
const float sf{ fmod( time - msf , 60.f ) };
|
||||
char buffer[ 12 ];
|
||||
snprintf( buffer , sizeof( buffer ) , "%02d:%02d.%03d" ,
|
||||
uint32_t( ( time - msf - sf ) / 60.f ) ,
|
||||
uint32_t( sf ) , uint32_t( msf * 1000.f ) );
|
||||
BeginTooltip( );
|
||||
stringBuffer.clear( ) << name << " (input)\nNot defined at "
|
||||
<< buffer << '\0';
|
||||
Text( "%s" , stringBuffer.data( ) );
|
||||
EndTooltip( );
|
||||
mousePosUsed = true;
|
||||
}
|
||||
#endif
|
||||
dl->PopClipRect( );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -60,6 +60,20 @@ void ImGui::ToolbarSeparator( ) noexcept
|
|||
SameLine( );
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
uint32_t ImGui::ColorHSVAToU32(
|
||||
float hue ,
|
||||
float saturation ,
|
||||
float value ,
|
||||
float alpha ) noexcept
|
||||
{
|
||||
ImVec4 out{ 0, 0, 0, alpha };
|
||||
ColorConvertHSVtoRGB( hue , saturation , value ,
|
||||
out.x , out.y , out.z );
|
||||
return GetColorU32( out );
|
||||
}
|
||||
|
||||
|
||||
/*= T_CameraMouseControl =======================================================*/
|
||||
|
||||
|
|
|
@ -30,6 +30,14 @@ namespace ImGui {
|
|||
char const* const tooltip = nullptr ,
|
||||
bool enabled = true ) noexcept;
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
uint32_t ColorHSVAToU32(
|
||||
float hue ,
|
||||
float saturation ,
|
||||
float value ,
|
||||
float alpha ) noexcept;
|
||||
|
||||
} // namespace ImGui
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
|
Loading…
Reference in a new issue