tracy/server/TracyTimelineItem.cpp
2022-09-03 17:51:29 +02:00

157 lines
4.3 KiB
C++

#include <algorithm>
#include "TracyImGui.hpp"
#include "TracyMouse.hpp"
#include "TracyTimelineItem.hpp"
#include "TracyView.hpp"
namespace tracy
{
TimelineItem::TimelineItem( View& view, const Worker& worker )
: m_visible( true )
, m_showFull( true )
, m_height( 0 )
, m_offset( 0 )
, m_view( view )
, m_worker( worker )
{
}
void TimelineItem::Draw( bool firstFrame, double pxns, int& offset, const ImVec2& wpos, bool hover, float yMin, float yMax )
{
if( !m_visible )
{
m_height = 0;
m_offset = 0;
return;
}
if( IsEmpty() ) return;
const auto w = ImGui::GetContentRegionAvail().x - 1;
const auto ty = ImGui::GetTextLineHeight();
const auto yPos = AdjustThreadPosition( wpos.y, offset );
const auto dpos = wpos + ImVec2( 0.5f, 0.5f );
const auto oldOffset = offset;
auto draw = ImGui::GetWindowDrawList();
ImGui::PushID( this );
ImGui::PushClipRect( wpos + ImVec2( 0, offset ), wpos + ImVec2( w, offset + m_height ), true );
float labelWidth;
const bool drawHeader = yPos + ty >= yMin && yPos <= yMax;
if( drawHeader )
{
const auto to = 9.f;
const auto th = ( ty - to ) * sqrt( 3 ) * 0.5;
const auto color = HeaderColor();
const auto colorInactive = HeaderColorInactive();
if( m_showFull )
{
draw->AddTriangleFilled( wpos + ImVec2( to/2, offset + to/2 ), wpos + ImVec2( ty - to/2, offset + to/2 ), wpos + ImVec2( ty * 0.5, offset + to/2 + th ), color );
}
else
{
draw->AddTriangle( wpos + ImVec2( to/2, offset + to/2 ), wpos + ImVec2( to/2, offset + ty - to/2 ), wpos + ImVec2( to/2 + th, offset + ty * 0.5 ), colorInactive, 2.0f );
}
const auto label = HeaderLabel();
labelWidth = ImGui::CalcTextSize( label ).x;
DrawTextContrast( draw, wpos + ImVec2( ty, offset ), m_showFull ? color : colorInactive, label );
DrawLine( draw, dpos + ImVec2( 0, offset + ty - 1 ), dpos + ImVec2( w, offset + ty - 1 ), 0x8844DDDD );
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( 0, offset ), wpos + ImVec2( ty + labelWidth, offset + ty ) ) )
{
HeaderTooltip( label );
if( IsMouseClicked( 0 ) )
{
m_showFull = !m_showFull;
}
if( IsMouseClicked( 2 ) )
{
m_view.ZoomToRange( RangeBegin(), RangeEnd() );
}
if( IsMouseClicked( 1 ) )
{
ImGui::OpenPopup( "menuPopup" );
}
}
}
if( ImGui::BeginPopup( "menuPopup" ) )
{
if( ImGui::MenuItem( ICON_FA_EYE_SLASH " Hide" ) )
{
m_visible = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
auto hdrOffset = offset;
offset += ty;
if( m_showFull )
{
DrawContents( pxns, offset, wpos, hover, yMin, yMax );
if( drawHeader )
{
HeaderExtraContents( hdrOffset, wpos, labelWidth );
}
}
offset += 0.2 * ty;
AdjustThreadHeight( firstFrame, oldOffset, offset );
ImGui::PopClipRect();
ImGui::PopID();
}
void TimelineItem::AdjustThreadHeight( bool firstFrame, int oldOffset, int& offset )
{
const auto h = offset - oldOffset;
if( m_height > h )
{
m_height = h;
offset = oldOffset + m_height;
}
else if( m_height < h )
{
if( firstFrame )
{
m_height = h;
offset = oldOffset + h;
}
else
{
const auto diff = h - m_height;
const auto move = std::max( 2.0, diff * 10.0 * ImGui::GetIO().DeltaTime );
m_height = int( std::min<double>( m_height + move, h ) );
offset = oldOffset + m_height;
}
}
}
float TimelineItem::AdjustThreadPosition( float wy, int& offset )
{
if( m_offset < offset )
{
m_offset = offset;
}
else if( m_offset > offset )
{
const auto diff = m_offset - offset;
const auto move = std::max( 2.0, diff * 10.0 * ImGui::GetIO().DeltaTime );
offset = m_offset = int( std::max<double>( m_offset - move, offset ) );
}
return offset + wy;
}
void TimelineItem::VisibilityCheckbox()
{
SmallCheckbox( HeaderLabel(), &m_visible );
}
}