From f5edad16e67d3a9151dd0118f11d5b48bf4c2e91 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 19:43:13 +0900 Subject: [PATCH] Improve visuals --- .../Timeline/TimelineHitObjectBlueprint.cs | 184 ++++++++++++------ 1 file changed, 125 insertions(+), 59 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 5a15cb42fa..b46a373818 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -2,14 +2,17 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -22,8 +25,6 @@ public class TimelineHitObjectBlueprint : SelectionBlueprint { private readonly Circle circle; - private readonly Container extensionBar; - protected override bool ShouldBeConsideredForInput(Drawable child) => true; [UsedImplicitly] @@ -31,11 +32,20 @@ public class TimelineHitObjectBlueprint : SelectionBlueprint public Action OnDragHandled; - public const float THICKNESS = 5; + private readonly DragBar dragBar; + + private readonly List shadowComponents = new List(); + + private const float thickness = 5; + + private const float shadow_radius = 5; private const float circle_size = 16; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || circle.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + base.ReceivePositionalInputAt(screenSpacePos) || + circle.ReceivePositionalInputAt(screenSpacePos) || + dragBar?.ReceivePositionalInputAt(screenSpacePos) == true; public TimelineHitObjectBlueprint(HitObject hitObject) : base(hitObject) @@ -51,7 +61,7 @@ public TimelineHitObjectBlueprint(HitObject hitObject) RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - AddInternal(circle = new Circle + circle = new Circle { Size = new Vector2(circle_size), Anchor = Anchor.CentreLeft, @@ -59,34 +69,126 @@ public TimelineHitObjectBlueprint(HitObject hitObject) RelativePositionAxes = Axes.X, AlwaysPresent = true, Colour = Color4.White, - BorderColour = Color4.Black, - BorderThickness = THICKNESS, - }); + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius, + Colour = Color4.Black + }, + }; + + shadowComponents.Add(circle); if (hitObject is IHasEndTime) { + DragBar dragBarUnderlay; + Container extensionBar; + AddRangeInternal(new Drawable[] { extensionBar = new Container { - CornerRadius = 2, Masking = true, - Size = new Vector2(1, THICKNESS), + Size = new Vector2(1, thickness), Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativePositionAxes = Axes.X, RelativeSizeAxes = Axes.X, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius, + Colour = Color4.Black + }, Child = new Box { RelativeSizeAxes = Axes.Both, } }, - new DragBar(hitObject) { OnDragHandled = e => OnDragHandled?.Invoke(e) } + circle, + // only used for drawing the shadow + dragBarUnderlay = new DragBar(null), + // cover up the shadow on the join + new Box + { + Height = thickness, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + }, + dragBar = new DragBar(hitObject) { OnDragHandled = e => OnDragHandled?.Invoke(e) }, }); + + shadowComponents.Add(dragBarUnderlay); + shadowComponents.Add(extensionBar); + } + else + { + AddInternal(circle); + } + + updateShadows(); + } + + protected override void Update() + { + base.Update(); + + // no bindable so we perform this every update + Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); + } + + protected override void OnSelected() + { + updateShadows(); + } + + private void updateShadows() + { + foreach (var s in shadowComponents) + { + if (State == SelectionState.Selected) + { + s.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius / 2, + Colour = Color4.Orange, + }; + } + else + { + s.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius, + Colour = State == SelectionState.Selected ? Color4.Orange : Color4.Black + }; + } } } - public class DragBar : CompositeDrawable + protected override void OnDeselected() + { + updateShadows(); + } + + public override Quad SelectionQuad + { + get + { + // correctly include the circle in the selection quad region, as it is usually outside the blueprint itself. + var leftQuad = circle.ScreenSpaceDrawQuad; + var rightQuad = dragBar?.ScreenSpaceDrawQuad ?? ScreenSpaceDrawQuad; + + return new Quad(leftQuad.TopLeft, Vector2.ComponentMax(rightQuad.TopRight, leftQuad.TopRight), + leftQuad.BottomLeft, Vector2.ComponentMax(rightQuad.BottomRight, leftQuad.BottomRight)); + } + } + + public override Vector2 SelectionPoint => ScreenSpaceDrawQuad.TopLeft; + + public class DragBar : Container { private readonly HitObject hitObject; @@ -95,20 +197,26 @@ public class DragBar : CompositeDrawable public Action OnDragHandled; + public override bool HandlePositionalInput => hitObject != null; + public DragBar(HitObject hitObject) { this.hitObject = hitObject; CornerRadius = 2; Masking = true; - Size = new Vector2(THICKNESS, 1.5f); + Size = new Vector2(5, 1); Anchor = Anchor.CentreRight; - Origin = Anchor.CentreRight; + Origin = Anchor.Centre; RelativePositionAxes = Axes.X; RelativeSizeAxes = Axes.Y; - InternalChild = new Box + + InternalChildren = new Drawable[] { - RelativeSizeAxes = Axes.Both, + new Box + { + RelativeSizeAxes = Axes.Both, + } }; } @@ -143,12 +251,7 @@ protected override void OnMouseUp(MouseUpEvent e) private void updateState() { - if (IsHovered || hasMouseDown) - Colour = Color4.Orange; - else - { - Colour = Color4.White; - } + Colour = IsHovered || hasMouseDown ? Color4.OrangeRed : Color4.White; } protected override bool OnDragStart(DragStartEvent e) => true; @@ -200,42 +303,5 @@ protected override void OnDragEnd(DragEndEvent e) OnDragHandled?.Invoke(null); } } - - protected override void Update() - { - base.Update(); - - // no bindable so we perform this every update - Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); - } - - protected override void OnSelected() - { - circle.BorderColour = Color4.Orange; - if (extensionBar != null) - extensionBar.BorderColour = Color4.Orange; - } - - protected override void OnDeselected() - { - circle.BorderColour = Color4.Black; - if (extensionBar != null) - extensionBar.BorderColour = Color4.Black; - } - - public override Quad SelectionQuad - { - get - { - // correctly include the circle in the selection quad region, as it is usually outside the blueprint itself. - var circleQuad = circle.ScreenSpaceDrawQuad; - var actualQuad = ScreenSpaceDrawQuad; - - return new Quad(circleQuad.TopLeft, Vector2.ComponentMax(actualQuad.TopRight, circleQuad.TopRight), - circleQuad.BottomLeft, Vector2.ComponentMax(actualQuad.BottomRight, circleQuad.BottomRight)); - } - } - - public override Vector2 SelectionPoint => ScreenSpaceDrawQuad.TopLeft; } }