using System.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Headless.XUnit;
using Avalonia.Threading;
using Avalonia.VisualTree;
using IFSRenderer.AvaloniaShell.Controls;
using Xunit;
using Xunit.Abstractions;
namespace IFSRenderer.AvaloniaShell.Tests;
/// <summary>
/// "left hand panel has some keyframes that are slightly occluded."
/// </summary>
/// <remarks>
/// The keyframe diamond is how an animation channel is created — the canonical empty dopesheet
/// says so outright: "Insert a keyframe by clicking ◇ next to the value!". If it is clipped or
/// sitting under the scrollbar it is not just cosmetic, it is the entry point to animation
/// being partly unreachable.
/// </remarks>
public class DiamondLayoutTests
{
private readonly ITestOutputHelper _out;
public DiamondLayoutTests(ITestOutputHelper output) => _out = output;
[AvaloniaFact]
public void No_keyframe_diamond_is_clipped_or_under_the_scrollbar()
{
(MainWindow window, _) = MainWindowHarness.Start();
window.Measure(new Size(1500, 900));
window.Arrange(new Rect(0, 0, 1500, 900));
Dispatcher.UIThread.RunJobs();
var pane = window.FindControl<Border>("LeftPanel");
Assert.NotNull(pane);
ScrollViewer viewer = pane.GetVisualDescendants().OfType<ScrollViewer>().First();
ScrollBar bar = viewer.GetVisualDescendants().OfType<ScrollBar>()
.First(b => b.Orientation == Avalonia.Layout.Orientation.Vertical);
double barLeftInViewer = bar.TranslatePoint(new Point(0, 0), viewer)?.X ?? double.MaxValue;
var sliders = pane.GetVisualDescendants().OfType<ValueSlider>().ToList();
Assert.NotEmpty(sliders);
int clipped = 0, occluded = 0;
foreach (ValueSlider slider in sliders)
{
foreach (Button diamond in slider.GetVisualDescendants().OfType<Button>()
.Where(b => b.Name is "Diamond1" or "Diamond2" && b.IsVisible))
{
Rect bounds = diamond.Bounds;
double rightInViewer =
(diamond.TranslatePoint(new Point(bounds.Width, 0), viewer)?.X) ?? 0;
// A zero-width button means the glyph had nowhere to go.
bool isClipped = bounds.Width <= 0 || bounds.Height <= 0;
bool isOccluded = rightInViewer > barLeftInViewer;
if (isClipped || isOccluded)
{
_out.WriteLine($"{slider.Name ?? slider.Label}/{diamond.Name}: " +
$"bounds={bounds} rightInViewer={rightInViewer} " +
$"barLeft={barLeftInViewer} " +
$"{(isClipped ? "CLIPPED " : "")}{(isOccluded ? "OCCLUDED" : "")}");
}
if (isClipped) clipped++;
if (isOccluded) occluded++;
}
}
_out.WriteLine($"diamonds checked: {sliders.Count}, clipped: {clipped}, occluded: {occluded}");
Assert.True(clipped == 0, $"{clipped} keyframe diamonds have no room to draw");
Assert.True(occluded == 0, $"{occluded} keyframe diamonds sit under the scrollbar");
}
}