using Amphora;
using Annulus;
using Azimuth;
using Blacklight.Core;
using Blacklight.Core.Cameras;
using Blacklight.Core.Drawables;
using Glass.Blacklight;
using System;
using Prism;
namespace Glass.Testbed.TestCases.Layout
{
///
/// A nameplate pinned to the Arrow in the game scene.
///
public class WorldAnchorTestCase : TestCase
{
private static readonly Vector ArrowHome = new Vector(120, -70);
private const double ArrowOrbitRadius = 60;
private const double ArrowOrbitSecondsPerTurn = 9;
private readonly World world;
private Arrow arrow;
private EntityHandle arrowHandle;
private WorldAnchoredPanel arrowNameplate;
private TextMaterial anchorReadoutMaterial;
private double arrowOrbitPhase;
public WorldAnchorTestCase(World world)
{
this.world = world;
}
protected override void Populate()
{
arrow = new Arrow(5, 2)
{
InsideColor = new Color(0.5, 0.5, 0),
ShellColor = new Color(0.75, 0.75, 0),
ShellModelSpaceThickness = 0,
ShellPixelThickness = 3,
};
arrowHandle = world.cel.AddEntity(arrow, new AffineMatrix(0, ArrowHome));
AddCaption("The nameplate tracks the world.arrow as the world.arrow orbits");
AddCaption("Drag to pan and wheel to zoom");
// Use a Panel rather than a Label, since the text changes every frame.
anchorReadoutMaterial = Widgets.Caption("anchor: measuring...");
Panel anchorReadout = anchorReadoutMaterial.BuildControl(Constraints.Unbounded);
anchorReadout.Bounds = ContentAggregator.NewRow(anchorReadout.Bounds.Height);
Add(anchorReadout);
Material nameplateMaterial = UiPacksheetMaterials.YellowPanel;
var nameplateLabel = new Label(Widgets.ButtonLabelStyle, "world.arrow", Constraints.Unbounded);
Vector nameplateSize = nameplateMaterial.BoundsSizeFor(nameplateLabel.Bounds.Size);
arrowNameplate = new WorldAnchoredPanel(
point => world.camera.WorldToWorldOf(world.uiWorld.camera).TransformPoint(point))
{
DebugName = "world.arrow nameplate",
Material = nameplateMaterial,
Bounds = Rect.FromPositionAndSize(Vector.Zero, nameplateSize),
WorldPosition = ArrowHome,
OffsetFromAnchor = new Vector(-nameplateSize.X / 2, -nameplateSize.Y - 14),
};
nameplateLabel.FillParent(arrowNameplate);
Add(arrowNameplate);
}
///
/// Walks the arrow around its home position so the nameplate has something to track without the user
/// having to drag the camera.
///
public override void Update(Duration elapsed)
{
arrowOrbitPhase += elapsed.TotalSeconds / ArrowOrbitSecondsPerTurn * 2 * Math.PI;
Amphora.PortableMath.SinCosOfRadians(arrowOrbitPhase, out double sin, out double cos);
Vector position = ArrowHome + new Vector(cos * ArrowOrbitRadius, sin * ArrowOrbitRadius);
var entity = new Entity(arrow, new AffineMatrix(arrowOrbitPhase, position));
world.cel.ReplaceEntity(arrowHandle, ref entity);
arrowNameplate.WorldPosition = position;
Vector glassPosition = world.camera.WorldToWorldOf(world.uiWorld.camera).TransformPoint(position);
anchorReadoutMaterial.Text = $"anchor: world ({position.X:F0}, {position.Y:F0})" +
$" -> glass ({glassPosition.X:F0}, {glassPosition.Y:F0})";
}
}
}