Improve visuals

This commit is contained in:
Dean Herbert 2020-02-05 19:43:13 +09:00
parent 98ab1f9862
commit f5edad16e6

View File

@ -2,14 +2,17 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@ -22,8 +25,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
private readonly Circle circle; private readonly Circle circle;
private readonly Container extensionBar;
protected override bool ShouldBeConsideredForInput(Drawable child) => true; protected override bool ShouldBeConsideredForInput(Drawable child) => true;
[UsedImplicitly] [UsedImplicitly]
@ -31,11 +32,20 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
public Action<DragEvent> OnDragHandled; public Action<DragEvent> OnDragHandled;
public const float THICKNESS = 5; private readonly DragBar dragBar;
private readonly List<Container> shadowComponents = new List<Container>();
private const float thickness = 5;
private const float shadow_radius = 5;
private const float circle_size = 16; 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) public TimelineHitObjectBlueprint(HitObject hitObject)
: base(hitObject) : base(hitObject)
@ -51,7 +61,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
AddInternal(circle = new Circle circle = new Circle
{ {
Size = new Vector2(circle_size), Size = new Vector2(circle_size),
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
@ -59,34 +69,126 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
RelativePositionAxes = Axes.X, RelativePositionAxes = Axes.X,
AlwaysPresent = true, AlwaysPresent = true,
Colour = Color4.White, Colour = Color4.White,
BorderColour = Color4.Black, EdgeEffect = new EdgeEffectParameters
BorderThickness = THICKNESS, {
}); Type = EdgeEffectType.Shadow,
Radius = shadow_radius,
Colour = Color4.Black
},
};
shadowComponents.Add(circle);
if (hitObject is IHasEndTime) if (hitObject is IHasEndTime)
{ {
DragBar dragBarUnderlay;
Container extensionBar;
AddRangeInternal(new Drawable[] AddRangeInternal(new Drawable[]
{ {
extensionBar = new Container extensionBar = new Container
{ {
CornerRadius = 2,
Masking = true, Masking = true,
Size = new Vector2(1, THICKNESS), Size = new Vector2(1, thickness),
Anchor = Anchor.CentreLeft, Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft, Origin = Anchor.CentreLeft,
RelativePositionAxes = Axes.X, RelativePositionAxes = Axes.X,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Radius = shadow_radius,
Colour = Color4.Black
},
Child = new Box Child = new Box
{ {
RelativeSizeAxes = Axes.Both, 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; private readonly HitObject hitObject;
@ -95,20 +197,26 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
public Action<DragEvent> OnDragHandled; public Action<DragEvent> OnDragHandled;
public override bool HandlePositionalInput => hitObject != null;
public DragBar(HitObject hitObject) public DragBar(HitObject hitObject)
{ {
this.hitObject = hitObject; this.hitObject = hitObject;
CornerRadius = 2; CornerRadius = 2;
Masking = true; Masking = true;
Size = new Vector2(THICKNESS, 1.5f); Size = new Vector2(5, 1);
Anchor = Anchor.CentreRight; Anchor = Anchor.CentreRight;
Origin = Anchor.CentreRight; Origin = Anchor.Centre;
RelativePositionAxes = Axes.X; RelativePositionAxes = Axes.X;
RelativeSizeAxes = Axes.Y; RelativeSizeAxes = Axes.Y;
InternalChild = new Box
InternalChildren = new Drawable[]
{ {
RelativeSizeAxes = Axes.Both, new Box
{
RelativeSizeAxes = Axes.Both,
}
}; };
} }
@ -143,12 +251,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
private void updateState() private void updateState()
{ {
if (IsHovered || hasMouseDown) Colour = IsHovered || hasMouseDown ? Color4.OrangeRed : Color4.White;
Colour = Color4.Orange;
else
{
Colour = Color4.White;
}
} }
protected override bool OnDragStart(DragStartEvent e) => true; protected override bool OnDragStart(DragStartEvent e) => true;
@ -200,42 +303,5 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
OnDragHandled?.Invoke(null); 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;
} }
} }