1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-07 21:32:57 +08:00

Merge pull request #6557 from smoogipoo/fix-hitcircle-selection-size

Fix hitcircle selection area being too large
This commit is contained in:
Dean Herbert 2019-10-21 18:43:48 +09:00 committed by GitHub
commit ed8b8e3ad0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 63 additions and 57 deletions

View File

@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
public class HoldNoteSelectionBlueprint : ManiaSelectionBlueprint public class HoldNoteSelectionBlueprint : ManiaSelectionBlueprint
{ {
public new DrawableHoldNote HitObject => (DrawableHoldNote)base.HitObject; public new DrawableHoldNote DrawableObject => (DrawableHoldNote)base.DrawableObject;
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>(); private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
new HoldNoteNoteSelectionBlueprint(HitObject.Head), new HoldNoteNoteSelectionBlueprint(DrawableObject.Head),
new HoldNoteNoteSelectionBlueprint(HitObject.Tail), new HoldNoteNoteSelectionBlueprint(DrawableObject.Tail),
new BodyPiece new BodyPiece
{ {
AccentColour = Color4.Transparent, AccentColour = Color4.Transparent,
@ -54,13 +54,13 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
base.Update(); base.Update();
Size = HitObject.DrawSize + new Vector2(0, HitObject.Tail.DrawHeight); Size = DrawableObject.DrawSize + new Vector2(0, DrawableObject.Tail.DrawHeight);
// This is a side-effect of not matching the hitobject's anchors/origins, which is kinda hard to do // This is a side-effect of not matching the hitobject's anchors/origins, which is kinda hard to do
// When scrolling upwards our origin is already at the top of the head note (which is the intended location), // When scrolling upwards our origin is already at the top of the head note (which is the intended location),
// but when scrolling downwards our origin is at the _bottom_ of the tail note (where we need to be at the _top_ of the tail note) // but when scrolling downwards our origin is at the _bottom_ of the tail note (where we need to be at the _top_ of the tail note)
if (direction.Value == ScrollingDirection.Down) if (direction.Value == ScrollingDirection.Down)
Y -= HitObject.Tail.DrawHeight; Y -= DrawableObject.Tail.DrawHeight;
} }
public override Quad SelectionQuad => ScreenSpaceDrawQuad; public override Quad SelectionQuad => ScreenSpaceDrawQuad;
@ -77,10 +77,10 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
base.Update(); base.Update();
Anchor = HitObject.Anchor; Anchor = DrawableObject.Anchor;
Origin = HitObject.Origin; Origin = DrawableObject.Origin;
Position = HitObject.DrawPosition; Position = DrawableObject.DrawPosition;
} }
// Todo: This is temporary, since the note masks don't do anything special yet. In the future they will handle input. // Todo: This is temporary, since the note masks don't do anything special yet. In the future they will handle input.

View File

@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
public Vector2 ScreenSpaceDragPosition { get; private set; } public Vector2 ScreenSpaceDragPosition { get; private set; }
public Vector2 DragPosition { get; private set; } public Vector2 DragPosition { get; private set; }
public new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject; public new DrawableManiaHitObject DrawableObject => (DrawableManiaHitObject)base.DrawableObject;
protected IClock EditorClock { get; private set; } protected IClock EditorClock { get; private set; }
@ -28,8 +28,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
[Resolved] [Resolved]
private IManiaHitObjectComposer composer { get; set; } private IManiaHitObjectComposer composer { get; set; }
public ManiaSelectionBlueprint(DrawableHitObject hitObject) public ManiaSelectionBlueprint(DrawableHitObject drawableObject)
: base(hitObject) : base(drawableObject)
{ {
RelativeSizeAxes = Axes.None; RelativeSizeAxes = Axes.None;
} }
@ -44,13 +44,13 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
base.Update(); base.Update();
Position = Parent.ToLocalSpace(HitObject.ToScreenSpace(Vector2.Zero)); Position = Parent.ToLocalSpace(DrawableObject.ToScreenSpace(Vector2.Zero));
} }
protected override bool OnMouseDown(MouseDownEvent e) protected override bool OnMouseDown(MouseDownEvent e)
{ {
ScreenSpaceDragPosition = e.ScreenSpaceMousePosition; ScreenSpaceDragPosition = e.ScreenSpaceMousePosition;
DragPosition = HitObject.ToLocalSpace(e.ScreenSpaceMousePosition); DragPosition = DrawableObject.ToLocalSpace(e.ScreenSpaceMousePosition);
return base.OnMouseDown(e); return base.OnMouseDown(e);
} }
@ -60,20 +60,20 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
var result = base.OnDrag(e); var result = base.OnDrag(e);
ScreenSpaceDragPosition = e.ScreenSpaceMousePosition; ScreenSpaceDragPosition = e.ScreenSpaceMousePosition;
DragPosition = HitObject.ToLocalSpace(e.ScreenSpaceMousePosition); DragPosition = DrawableObject.ToLocalSpace(e.ScreenSpaceMousePosition);
return result; return result;
} }
public override void Show() public override void Show()
{ {
HitObject.AlwaysAlive = true; DrawableObject.AlwaysAlive = true;
base.Show(); base.Show();
} }
public override void Hide() public override void Hide()
{ {
HitObject.AlwaysAlive = false; DrawableObject.AlwaysAlive = false;
base.Hide(); base.Hide();
} }
} }

View File

@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
{ {
base.Update(); base.Update();
Size = HitObject.DrawSize; Size = DrawableObject.DrawSize;
} }
} }
} }

View File

@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mania.Edit
public override void HandleMovement(MoveSelectionEvent moveEvent) public override void HandleMovement(MoveSelectionEvent moveEvent)
{ {
var maniaBlueprint = (ManiaSelectionBlueprint)moveEvent.Blueprint; var maniaBlueprint = (ManiaSelectionBlueprint)moveEvent.Blueprint;
int lastColumn = maniaBlueprint.HitObject.HitObject.Column; int lastColumn = maniaBlueprint.DrawableObject.HitObject.Column;
adjustOrigins(maniaBlueprint); adjustOrigins(maniaBlueprint);
performDragMovement(moveEvent); performDragMovement(moveEvent);
@ -48,19 +48,19 @@ namespace osu.Game.Rulesets.Mania.Edit
/// <param name="reference">The <see cref="ManiaSelectionBlueprint"/> that received the drag event.</param> /// <param name="reference">The <see cref="ManiaSelectionBlueprint"/> that received the drag event.</param>
private void adjustOrigins(ManiaSelectionBlueprint reference) private void adjustOrigins(ManiaSelectionBlueprint reference)
{ {
var referenceParent = (HitObjectContainer)reference.HitObject.Parent; var referenceParent = (HitObjectContainer)reference.DrawableObject.Parent;
float offsetFromReferenceOrigin = reference.DragPosition.Y - reference.HitObject.OriginPosition.Y; float offsetFromReferenceOrigin = reference.DragPosition.Y - reference.DrawableObject.OriginPosition.Y;
float targetPosition = referenceParent.ToLocalSpace(reference.ScreenSpaceDragPosition).Y - offsetFromReferenceOrigin; float targetPosition = referenceParent.ToLocalSpace(reference.ScreenSpaceDragPosition).Y - offsetFromReferenceOrigin;
// Flip the vertical coordinate space when scrolling downwards // Flip the vertical coordinate space when scrolling downwards
if (scrollingInfo.Direction.Value == ScrollingDirection.Down) if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
targetPosition = targetPosition - referenceParent.DrawHeight; targetPosition = targetPosition - referenceParent.DrawHeight;
float movementDelta = targetPosition - reference.HitObject.Position.Y; float movementDelta = targetPosition - reference.DrawableObject.Position.Y;
foreach (var b in SelectedBlueprints.OfType<ManiaSelectionBlueprint>()) foreach (var b in SelectedBlueprints.OfType<ManiaSelectionBlueprint>())
b.HitObject.Y += movementDelta; b.DrawableObject.Y += movementDelta;
} }
private void performDragMovement(MoveSelectionEvent moveEvent) private void performDragMovement(MoveSelectionEvent moveEvent)
@ -70,11 +70,11 @@ namespace osu.Game.Rulesets.Mania.Edit
// When scrolling downwards the anchor position is at the bottom of the screen, however the movement event assumes the anchor is at the top of the screen. // When scrolling downwards the anchor position is at the bottom of the screen, however the movement event assumes the anchor is at the top of the screen.
// This causes the delta to assume a positive hitobject position, and which can be corrected for by subtracting the parent height. // This causes the delta to assume a positive hitobject position, and which can be corrected for by subtracting the parent height.
if (scrollingInfo.Direction.Value == ScrollingDirection.Down) if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
delta -= moveEvent.Blueprint.HitObject.Parent.DrawHeight; delta -= moveEvent.Blueprint.DrawableObject.Parent.DrawHeight;
foreach (var b in SelectedBlueprints) foreach (var b in SelectedBlueprints)
{ {
var hitObject = b.HitObject; var hitObject = b.DrawableObject;
var objectParent = (HitObjectContainer)hitObject.Parent; var objectParent = (HitObjectContainer)hitObject.Parent;
// StartTime could be used to adjust the position if only one movement event was received per frame. // StartTime could be used to adjust the position if only one movement event was received per frame.

View File

@ -9,8 +9,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Masks
{ {
public abstract class ManiaSelectionBlueprint : SelectionBlueprint public abstract class ManiaSelectionBlueprint : SelectionBlueprint
{ {
protected ManiaSelectionBlueprint(DrawableHitObject hitObject) protected ManiaSelectionBlueprint(DrawableHitObject drawableObject)
: base(hitObject) : base(drawableObject)
{ {
RelativeSizeAxes = Axes.None; RelativeSizeAxes = Axes.None;
} }

View File

@ -63,8 +63,8 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
public new HitCirclePiece CirclePiece => base.CirclePiece; public new HitCirclePiece CirclePiece => base.CirclePiece;
public TestBlueprint(DrawableHitCircle hitCircle) public TestBlueprint(DrawableHitCircle drawableCircle)
: base(hitCircle) : base(drawableCircle)
{ {
} }
} }

View File

@ -1,18 +1,22 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// 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 osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables;
using osuTK;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
{ {
public class HitCircleSelectionBlueprint : OsuSelectionBlueprint<HitCircle> public class HitCircleSelectionBlueprint : OsuSelectionBlueprint<HitCircle>
{ {
protected new DrawableHitCircle DrawableObject => (DrawableHitCircle)base.DrawableObject;
protected readonly HitCirclePiece CirclePiece; protected readonly HitCirclePiece CirclePiece;
public HitCircleSelectionBlueprint(DrawableHitCircle hitCircle) public HitCircleSelectionBlueprint(DrawableHitCircle drawableCircle)
: base(hitCircle) : base(drawableCircle)
{ {
InternalChild = CirclePiece = new HitCirclePiece(); InternalChild = CirclePiece = new HitCirclePiece();
} }
@ -23,5 +27,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
CirclePiece.UpdateFrom(HitObject); CirclePiece.UpdateFrom(HitObject);
} }
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.HitArea.ReceivePositionalInputAt(screenSpacePos);
public override Quad SelectionQuad => DrawableObject.HitArea.ScreenSpaceDrawQuad;
} }
} }

View File

@ -10,10 +10,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints
public abstract class OsuSelectionBlueprint<T> : SelectionBlueprint public abstract class OsuSelectionBlueprint<T> : SelectionBlueprint
where T : OsuHitObject where T : OsuHitObject
{ {
protected new T HitObject => (T)base.HitObject.HitObject; protected T HitObject => (T)DrawableObject.HitObject;
protected OsuSelectionBlueprint(DrawableHitObject hitObject) protected OsuSelectionBlueprint(DrawableHitObject drawableObject)
: base(hitObject) : base(drawableObject)
{ {
} }
} }

View File

@ -24,14 +24,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
private readonly IBindable<int> stackHeightBindable = new Bindable<int>(); private readonly IBindable<int> stackHeightBindable = new Bindable<int>();
private readonly IBindable<float> scaleBindable = new Bindable<float>(); private readonly IBindable<float> scaleBindable = new Bindable<float>();
public OsuAction? HitAction => hitArea.HitAction; public OsuAction? HitAction => HitArea.HitAction;
public readonly HitReceptor HitArea;
public readonly SkinnableDrawable CirclePiece;
private readonly Container scaleContainer; private readonly Container scaleContainer;
private readonly HitArea hitArea;
public SkinnableDrawable CirclePiece { get; }
public DrawableHitCircle(HitCircle h) public DrawableHitCircle(HitCircle h)
: base(h) : base(h)
{ {
@ -48,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Children = new Drawable[] Children = new Drawable[]
{ {
hitArea = new HitArea HitArea = new HitReceptor
{ {
Hit = () => Hit = () =>
{ {
@ -69,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
}, },
}; };
Size = hitArea.DrawSize; Size = HitArea.DrawSize;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -153,7 +151,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Expire(true); Expire(true);
hitArea.HitAction = null; HitArea.HitAction = null;
break; break;
case ArmedState.Miss: case ArmedState.Miss:
@ -172,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public Drawable ProxiedLayer => ApproachCircle; public Drawable ProxiedLayer => ApproachCircle;
private class HitArea : Drawable, IKeyBindingHandler<OsuAction> public class HitReceptor : Drawable, IKeyBindingHandler<OsuAction>
{ {
// IsHovered is used // IsHovered is used
public override bool HandlePositionalInput => true; public override bool HandlePositionalInput => true;
@ -181,7 +179,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public OsuAction? HitAction; public OsuAction? HitAction;
public HitArea() public HitReceptor()
{ {
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);

View File

@ -43,20 +43,20 @@ namespace osu.Game.Rulesets.Edit
/// <summary> /// <summary>
/// The <see cref="DrawableHitObject"/> which this <see cref="SelectionBlueprint"/> applies to. /// The <see cref="DrawableHitObject"/> which this <see cref="SelectionBlueprint"/> applies to.
/// </summary> /// </summary>
public readonly DrawableHitObject HitObject; public readonly DrawableHitObject DrawableObject;
/// <summary> /// <summary>
/// The screen-space position of <see cref="HitObject"/> prior to handling a movement event. /// The screen-space position of <see cref="DrawableObject"/> prior to handling a movement event.
/// </summary> /// </summary>
internal Vector2 ScreenSpaceMovementStartPosition { get; private set; } internal Vector2 ScreenSpaceMovementStartPosition { get; private set; }
protected override bool ShouldBeAlive => (HitObject.IsAlive && HitObject.IsPresent) || State == SelectionState.Selected; protected override bool ShouldBeAlive => (DrawableObject.IsAlive && DrawableObject.IsPresent) || State == SelectionState.Selected;
public override bool HandlePositionalInput => ShouldBeAlive; public override bool HandlePositionalInput => ShouldBeAlive;
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;
protected SelectionBlueprint(DrawableHitObject hitObject) protected SelectionBlueprint(DrawableHitObject drawableObject)
{ {
HitObject = hitObject; DrawableObject = drawableObject;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Edit
public bool IsSelected => State == SelectionState.Selected; public bool IsSelected => State == SelectionState.Selected;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObject.ReceivePositionalInputAt(screenSpacePos); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos);
private bool selectionRequested; private bool selectionRequested;
@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Edit
protected override bool OnDragStart(DragStartEvent e) protected override bool OnDragStart(DragStartEvent e)
{ {
ScreenSpaceMovementStartPosition = HitObject.ToScreenSpace(HitObject.OriginPosition); ScreenSpaceMovementStartPosition = DrawableObject.ToScreenSpace(DrawableObject.OriginPosition);
return true; return true;
} }
@ -151,11 +151,11 @@ namespace osu.Game.Rulesets.Edit
/// <summary> /// <summary>
/// The screen-space point that causes this <see cref="SelectionBlueprint"/> to be selected. /// The screen-space point that causes this <see cref="SelectionBlueprint"/> to be selected.
/// </summary> /// </summary>
public virtual Vector2 SelectionPoint => HitObject.ScreenSpaceDrawQuad.Centre; public virtual Vector2 SelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre;
/// <summary> /// <summary>
/// The screen-space quad that outlines this <see cref="SelectionBlueprint"/> for selections. /// The screen-space quad that outlines this <see cref="SelectionBlueprint"/> for selections.
/// </summary> /// </summary>
public virtual Quad SelectionQuad => HitObject.ScreenSpaceDrawQuad; public virtual Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad;
} }
} }

View File

@ -101,7 +101,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void removeBlueprintFor(HitObject hitObject) private void removeBlueprintFor(HitObject hitObject)
{ {
var blueprint = selectionBlueprints.Single(m => m.HitObject.HitObject == hitObject); var blueprint = selectionBlueprints.Single(m => m.DrawableObject.HitObject == hitObject);
if (blueprint == null) if (blueprint == null)
return; return;
@ -252,7 +252,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
return d; return d;
// Put earlier hitobjects towards the end of the list, so they handle input first // Put earlier hitobjects towards the end of the list, so they handle input first
int i = y.HitObject.HitObject.StartTime.CompareTo(x.HitObject.HitObject.StartTime); int i = y.DrawableObject.HitObject.StartTime.CompareTo(x.DrawableObject.HitObject.StartTime);
return i == 0 ? CompareReverseChildID(x, y) : i; return i == 0 ? CompareReverseChildID(x, y) : i;
} }
} }

View File

@ -40,7 +40,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
ScreenSpaceStartPosition = screenSpaceStartPosition; ScreenSpaceStartPosition = screenSpaceStartPosition;
ScreenSpacePosition = screenSpacePosition; ScreenSpacePosition = screenSpacePosition;
InstantDelta = Blueprint.HitObject.Parent.ToLocalSpace(ScreenSpacePosition) - Blueprint.HitObject.Position; InstantDelta = Blueprint.DrawableObject.Parent.ToLocalSpace(ScreenSpacePosition) - Blueprint.DrawableObject.Position;
} }
} }
} }

View File

@ -29,7 +29,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected IEnumerable<SelectionBlueprint> SelectedBlueprints => selectedBlueprints; protected IEnumerable<SelectionBlueprint> SelectedBlueprints => selectedBlueprints;
private readonly List<SelectionBlueprint> selectedBlueprints; private readonly List<SelectionBlueprint> selectedBlueprints;
protected IEnumerable<HitObject> SelectedHitObjects => selectedBlueprints.Select(b => b.HitObject.HitObject); protected IEnumerable<HitObject> SelectedHitObjects => selectedBlueprints.Select(b => b.DrawableObject.HitObject);
private Drawable outline; private Drawable outline;
@ -81,7 +81,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
case Key.Delete: case Key.Delete:
foreach (var h in selectedBlueprints.ToList()) foreach (var h in selectedBlueprints.ToList())
placementHandler.Delete(h.HitObject.HitObject); placementHandler.Delete(h.DrawableObject.HitObject);
return true; return true;
} }