Improve visuals

This commit is contained in:
Dean Herbert 2020-02-05 19:43:13 +09:00
parent 98ab1f9862
commit f5edad16e6
1 changed files with 125 additions and 59 deletions

View File

@ -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<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;
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<DragEvent> 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;
}
}