Sequencer - Very primitive track display

There are pieces of disabled mouse handling code in the display code.
This commit is contained in:
Emmanuel BENOîT 2017-11-25 16:30:46 +01:00
parent aa84f95727
commit 2cfc80a6e4
3 changed files with 220 additions and 20 deletions

View file

@ -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;
}
/*----------------------------------------------------------------------------*/

View file

@ -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 =======================================================*/

View file

@ -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
/*----------------------------------------------------------------------------*/