using Blacklight.Core.Cameras; using Blacklight.Core.Keyboard; using UnitTestSharp; using Azimuth; using Annulus; namespace Glass.Blacklight.UnitTests { public class BlacklightGlassWorldTests : TestFixture { public class CtorTests : TestFixture { public void RendersIntoTheScreensExceptionLog() { var world = new BlacklightGlassWorld(); CheckEqual(world.screen.Exceptions, world.renderer.Exceptions); } } public class KeyDownTests : TestFixture { [IgnoreTest] private static Control ClickLockedControl(BlacklightGlassWorld world) { var control = new Control { Bounds = Rect.FromTwoPoints(new Vector(-5, -5), new Vector(5, 5)) }; control.OnMouseDown += (in MouseState _, MouseButtonFlags __) => { }; world.screen.Controls.Add(control); world.screen.MouseManager.MouseDown(new MouseState { Position = Vector.Zero }, MouseButtonFlags.Left); return control; } public void Escape_WithNothingLocked_ReturnsFalse() { var world = new BlacklightGlassWorld(); CheckFalse(world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Escape, default)); } public void Escape_WithAClickLock_CancelsItAndReturnsTrue() { var world = new BlacklightGlassWorld(); ClickLockedControl(world); CheckTrue(world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Escape, default)); } public void AnyOtherKey_NeverConsumesEvenWithAClickLock() { var world = new BlacklightGlassWorld(); ClickLockedControl(world); CheckFalse(world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Space, default)); } public void Tab_MovesFocusToTheFirstFocusableControl() { var world = new BlacklightGlassWorld(); var control = new Control { Focusable = true }; world.screen.Controls.Add(control); world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Tab, default); CheckEqual(control, world.screen.KeyboardManager.Focused); } public void Tab_ClaimsThePress() { var world = new BlacklightGlassWorld(); world.screen.Controls.Add(new Control { Focusable = true }); CheckTrue(world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Tab, default)); } public void ShiftTab_MovesFocusBackward() { var world = new BlacklightGlassWorld(); var first = new Control("first") { Focusable = true }; var second = new Control("second") { Focusable = true }; world.screen.Controls.Add(first); world.screen.Controls.Add(second); world.screen.KeyboardManager.TrySetFocus(second); var held = new global::Blacklight.Core.Keyboard.KeyState( global::Blacklight.Core.Keyboard.KeyCode.ShiftLeft); world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Tab, held); CheckEqual(first, world.screen.KeyboardManager.Focused); } public void Escape_WithAFocusedControlAndNoClickLock_BlursIt() { var world = new BlacklightGlassWorld(); var control = new Control { Focusable = true }; world.screen.Controls.Add(control); world.screen.KeyboardManager.TrySetFocus(control); CheckTrue(world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Escape, default)); CheckNull(world.screen.KeyboardManager.Focused); } public void Escape_WithBothAClickLockAndAFocusedControl_CancelsTheDragAndLeavesFocusAlone() { var world = new BlacklightGlassWorld(); var control = new Control { Focusable = true }; world.screen.Controls.Add(control); world.screen.KeyboardManager.TrySetFocus(control); ClickLockedControl(world); world.KeyDown(global::Blacklight.Core.Keyboard.KeyCode.Escape, default); CheckEqual(control, world.screen.KeyboardManager.Focused); } } public class PointerDownTests : TestFixture { private static readonly Rect AroundTheOrigin = Rect.FromTwoPoints(new Vector(-5, -5), new Vector(5, 5)); [IgnoreTest] private static BlacklightGlassWorld NewWorld() { return new BlacklightGlassWorld { camera = new ScreenSpaceCamera { Magnification = 1 } }; } [IgnoreTest] private static PointerInput PressAt(Vector position, PointerButtons buttons = PointerButtons.Left) { return new PointerInput { PixelPos = position, Buttons = buttons }; } public void OnAControlThatTakesFocusOnClick_FocusesIt() { BlacklightGlassWorld world = NewWorld(); var control = new Control { Bounds = AroundTheOrigin, Focusable = true, FocusOnClick = true }; world.screen.Controls.Add(control); world.PointerDown(PressAt(Vector.Zero)); CheckEqual(control, world.screen.KeyboardManager.Focused); } public void OnAControlThatTakesFocusOnClick_ClaimsThePress() { BlacklightGlassWorld world = NewWorld(); world.screen.Controls.Add( new Control { Bounds = AroundTheOrigin, Focusable = true, FocusOnClick = true }); CheckTrue(world.PointerDown(PressAt(Vector.Zero))); } public void WithAnyMouseButton_FocusesIt() { BlacklightGlassWorld world = NewWorld(); var control = new Control { Bounds = AroundTheOrigin, Focusable = true, FocusOnClick = true }; world.screen.Controls.Add(control); world.PointerDown(PressAt(Vector.Zero, PointerButtons.Right)); CheckEqual(control, world.screen.KeyboardManager.Focused); } public void OnAControlThatClaimsThePressWithoutTakingFocus_LeavesFocusAlone() { BlacklightGlassWorld world = NewWorld(); var focused = new Control { Bounds = Rect.FromTwoPoints(new Vector(50, 50), new Vector(60, 60)), Focusable = true, FocusOnClick = true, }; var button = new Control { Bounds = AroundTheOrigin, Focusable = true }; button.OnClick += (in MouseState _, MouseButtonFlags __) => { }; world.screen.Controls.Add(focused); world.screen.Controls.Add(button); world.screen.KeyboardManager.TrySetFocus(focused); world.PointerDown(PressAt(Vector.Zero)); CheckEqual(focused, world.screen.KeyboardManager.Focused); } public void OnNothing_ClearsFocus() { BlacklightGlassWorld world = NewWorld(); var focused = new Control { Focusable = true }; world.screen.Controls.Add(focused); world.screen.KeyboardManager.TrySetFocus(focused); world.PointerDown(PressAt(new Vector(100, 100))); CheckNull(world.screen.KeyboardManager.Focused); } public void OnNothing_DoesNotClaimThePress() { CheckFalse(NewWorld().PointerDown(PressAt(new Vector(100, 100)))); } } public class WheelTests : TestFixture { private static readonly Rect AroundTheOrigin = Rect.FromTwoPoints(new Vector(-5, -5), new Vector(5, 5)); [IgnoreTest] private static BlacklightGlassWorld NewWorld(Scalar magnification) { return new BlacklightGlassWorld { camera = new ScreenSpaceCamera { Magnification = magnification } }; } public void OverAControlThatHandlesIt_ReturnsTrue() { BlacklightGlassWorld world = NewWorld(magnification: 1); var control = new Control { Bounds = AroundTheOrigin }; control.OnMouseWheel += (in MouseState _, Scalar __) => { }; world.screen.Controls.Add(control); CheckTrue(world.Wheel(ticks: 120, Vector.Zero)); } public void NothingHandlingIt_ReturnsFalse() { BlacklightGlassWorld world = NewWorld(magnification: 1); world.screen.Controls.Add(new Control { Bounds = AroundTheOrigin }); CheckFalse(world.Wheel(ticks: 120, Vector.Zero)); } public void ReportsAHundredAndTwentyTicksAsOneNotch() { BlacklightGlassWorld world = NewWorld(magnification: 1); Scalar? heard = null; var control = new Control { Bounds = AroundTheOrigin }; control.OnMouseWheel += (in MouseState _, Scalar notches) => heard = notches; world.screen.Controls.Add(control); world.Wheel(ticks: -180, Vector.Zero); CheckEqual((Scalar)(-1.5), heard); } public void ReportsThePositionInGlassSpace() { BlacklightGlassWorld world = NewWorld(magnification: 2); Vector? heardAt = null; var control = new Control { Bounds = Rect.FromTwoPoints(Vector.Zero, new Vector(20, 20)) }; control.OnMouseWheel += (in MouseState state, Scalar _) => heardAt = state.Position; world.screen.Controls.Add(control); world.Wheel(ticks: 120, new Vector(20, 20)); CheckEqual(new Vector(10, 10), heardAt); } public void ReportsNoButtonsHeld() { BlacklightGlassWorld world = NewWorld(magnification: 1); MouseButtonFlags? heard = null; var control = new Control { Bounds = AroundTheOrigin }; control.OnMouseWheel += (in MouseState state, Scalar _) => heard = state.Buttons; world.screen.Controls.Add(control); world.Wheel(ticks: 120, Vector.Zero); CheckEqual(MouseButtonFlags.None, heard); } } } }