Editor/AudioTimeAxis.cs
using Editor;
using Sandbox;
using System;

namespace Ardi;

public class AudioTimeAxis : GraphicsItem
{
	private readonly AudioTimelineView TimelineView;

	public AudioTimeAxis( AudioTimelineView view ) : base( null )
	{
		TimelineView = view;
		ZIndex = -1f;
		HoverEvents = true;
	}

	protected override void OnMousePressed( GraphicsMouseEvent e )
	{
		base.OnMousePressed( e );
		if ( e.LeftMouseButton )
		{
			TimelineView.MoveScrubber( e.LocalPosition.x );
		}
	}

	protected override void OnPaint()
	{
		base.OnPaint();

		Paint.Antialiasing = false;
		Paint.ClearPen();
		Paint.SetBrush( Theme.ControlBackground );
		Paint.DrawRect( LocalRect );

		Paint.SetDefaultFont( 7f, 400, false, false );
		var drawRect = LocalRect.Shrink( 1f );

		var visibleWidth = (int)TimelineView.VisibleRect.Width;
		var visibleTime = TimelineView.TimeFromPosition( visibleWidth );
		var step = visibleTime * (100f / visibleWidth);
		step = GetNiceStepSize( step );
		var substep = step / 10f;

		var startStep = (int)Math.Floor( TimelineView.TimeFromPosition( TimelineView.VisibleRect.Left ) / step );
		var endStep = (int)Math.Ceiling( TimelineView.TimeFromPosition( TimelineView.VisibleRect.Right ) / step );

		for ( int i = startStep; i <= endStep; i++ )
		{
			var time = i * step;
			var x = drawRect.Left + time * (visibleWidth / visibleTime);

			var color = Theme.Text.WithAlpha( 0.5f );
			Paint.SetPen( color );
			var tickStart = new Vector2( x, drawRect.Bottom );
			var tickEnd = new Vector2( x, drawRect.Bottom - 8f );
			Paint.DrawLine( tickStart, tickEnd );

			if ( Math.Abs( time ) > 0f )
			{
				var text = time < 60f ? $"{time}" : $"{(int)(time / 60f)}:{time % 60f:00}";
				var textPos = new Vector2( x, drawRect.Top );
				var textSize = Paint.MeasureText( text );
				var textRect = new Rect( textPos, textSize );
				textRect.Left = textRect.Left - textRect.Width;
				Paint.DrawText( textRect, text, TextFlag.LeftCenter );
			}

			color = Theme.Text.WithAlpha( 0.2f );
			Paint.SetPen( color );
			for ( int j = 1; j < 10; j++ )
			{
				var subTime = time + j * substep;
				var subX = drawRect.Left + subTime * (visibleWidth / visibleTime);
				var subTickStart = new Vector2( subX, drawRect.Bottom );
				var subTickEnd = new Vector2( subX, drawRect.Bottom - 4f );
				Paint.DrawLine( subTickStart, subTickEnd );
			}
		}
	}

	private float GetNiceStepSize( float step )
	{
		var steps = new float[] { 1f, 2f, 5f, 10f, 20f, 50f, 100f, 200f, 500f, 1000f };
		foreach ( var s in steps )
		{
			if ( step <= s ) return s;
		}
		return steps[^1];
	}
}