mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 06:17:23 +08:00
Merge branch 'master' into scoredatabase
This commit is contained in:
commit
271dcded3c
@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Rulesets.Mania.Edit;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
[Cached(Type = typeof(IManiaHitObjectComposer))]
|
||||
public abstract class ManiaPlacementBlueprintTestCase : PlacementBlueprintTestCase, IManiaHitObjectComposer
|
||||
{
|
||||
private readonly Column column;
|
||||
|
||||
protected ManiaPlacementBlueprintTestCase()
|
||||
{
|
||||
Add(column = new Column(0)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AccentColour = Color4.OrangeRed,
|
||||
Clock = new FramedClock(new StopwatchClock()), // No scroll
|
||||
});
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
dependencies.CacheAs(((ScrollingTestContainer)HitObjectContainer).ScrollingInfo);
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
protected override Container CreateHitObjectContainer() => new ScrollingTestContainer(ScrollingDirection.Down) { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
protected override void AddHitObject(DrawableHitObject hitObject) => column.Add((DrawableManiaHitObject)hitObject);
|
||||
|
||||
public Column ColumnAt(Vector2 screenSpacePosition) => column;
|
||||
|
||||
public int TotalColumns => 1;
|
||||
}
|
||||
}
|
@ -2,14 +2,37 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Rulesets.Mania.Edit;
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
public abstract class ManiaSelectionBlueprintTestCase : SelectionBlueprintTestCase
|
||||
[Cached(Type = typeof(IManiaHitObjectComposer))]
|
||||
public abstract class ManiaSelectionBlueprintTestCase : SelectionBlueprintTestCase, IManiaHitObjectComposer
|
||||
{
|
||||
[Cached(Type = typeof(IAdjustableClock))]
|
||||
private readonly IAdjustableClock clock = new StopwatchClock();
|
||||
|
||||
private readonly Column column;
|
||||
|
||||
protected ManiaSelectionBlueprintTestCase()
|
||||
{
|
||||
Add(column = new Column(0)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AccentColour = Color4.OrangeRed,
|
||||
Clock = new FramedClock(new StopwatchClock()), // No scroll
|
||||
});
|
||||
}
|
||||
|
||||
public Column ColumnAt(Vector2 screenSpacePosition) => column;
|
||||
|
||||
public int TotalColumns => 1;
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
Spacing = new Vector2(20, 0),
|
||||
Children = new[]
|
||||
{
|
||||
createColumn(ScrollingDirection.Up, ManiaAction.Key1),
|
||||
createColumn(ScrollingDirection.Down, ManiaAction.Key2)
|
||||
createColumn(ScrollingDirection.Up, ManiaAction.Key1, 0),
|
||||
createColumn(ScrollingDirection.Down, ManiaAction.Key2, 1)
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -85,9 +85,9 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable createColumn(ScrollingDirection direction, ManiaAction action)
|
||||
private Drawable createColumn(ScrollingDirection direction, ManiaAction action, int index)
|
||||
{
|
||||
var column = new Column
|
||||
var column = new Column(index)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
public class TestCaseHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
|
||||
{
|
||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHoldNote((HoldNote)hitObject);
|
||||
protected override PlacementBlueprint CreateBlueprint() => new HoldNotePlacementBlueprint();
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
public class TestCaseNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
|
||||
{
|
||||
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableNote((Note)hitObject);
|
||||
protected override PlacementBlueprint CreateBlueprint() => new NotePlacementBlueprint();
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints.Components
|
||||
{
|
||||
public class EditBodyPiece : BodyPiece
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
AccentColour = colours.Yellow;
|
||||
|
||||
Background.Alpha = 0.5f;
|
||||
Foreground.Alpha = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
{
|
||||
public class HoldNotePlacementBlueprint : ManiaPlacementBlueprint<HoldNote>
|
||||
{
|
||||
private readonly EditBodyPiece bodyPiece;
|
||||
private readonly EditNotePiece headPiece;
|
||||
private readonly EditNotePiece tailPiece;
|
||||
|
||||
public HoldNotePlacementBlueprint()
|
||||
: base(new HoldNote())
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
bodyPiece = new EditBodyPiece { Origin = Anchor.TopCentre },
|
||||
headPiece = new EditNotePiece { Origin = Anchor.Centre },
|
||||
tailPiece = new EditNotePiece { Origin = Anchor.Centre }
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (Column != null)
|
||||
{
|
||||
headPiece.Y = PositionAt(HitObject.StartTime);
|
||||
tailPiece.Y = PositionAt(HitObject.EndTime);
|
||||
}
|
||||
|
||||
var topPosition = new Vector2(headPiece.DrawPosition.X, Math.Min(headPiece.DrawPosition.Y, tailPiece.DrawPosition.Y));
|
||||
var bottomPosition = new Vector2(headPiece.DrawPosition.X, Math.Max(headPiece.DrawPosition.Y, tailPiece.DrawPosition.Y));
|
||||
|
||||
bodyPiece.Position = topPosition;
|
||||
bodyPiece.Width = headPiece.Width;
|
||||
bodyPiece.Height = (bottomPosition - topPosition).Y;
|
||||
}
|
||||
|
||||
private double originalStartTime;
|
||||
|
||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
|
||||
if (PlacementBegun)
|
||||
{
|
||||
var endTime = TimeAt(e.ScreenSpaceMousePosition);
|
||||
|
||||
HitObject.StartTime = endTime < originalStartTime ? endTime : originalStartTime;
|
||||
HitObject.Duration = Math.Abs(endTime - originalStartTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
headPiece.Width = tailPiece.Width = SnappedWidth;
|
||||
headPiece.X = tailPiece.X = SnappedMousePosition.X;
|
||||
|
||||
originalStartTime = HitObject.StartTime = TimeAt(e.ScreenSpaceMousePosition);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
{
|
||||
public abstract class ManiaPlacementBlueprint<T> : PlacementBlueprint,
|
||||
IRequireHighFrequencyMousePosition // the playfield could be moving behind us
|
||||
where T : ManiaHitObject
|
||||
{
|
||||
protected new T HitObject => (T)base.HitObject;
|
||||
|
||||
protected Column Column;
|
||||
|
||||
/// <summary>
|
||||
/// The current mouse position, snapped to the closest column.
|
||||
/// </summary>
|
||||
protected Vector2 SnappedMousePosition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The width of the closest column to the current mouse position.
|
||||
/// </summary>
|
||||
protected float SnappedWidth { get; private set; }
|
||||
|
||||
[Resolved]
|
||||
private IManiaHitObjectComposer composer { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IScrollingInfo scrollingInfo { get; set; }
|
||||
|
||||
protected ManiaPlacementBlueprint(T hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
RelativeSizeAxes = Axes.None;
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
if (Column == null)
|
||||
return base.OnMouseDown(e);
|
||||
|
||||
HitObject.StartTime = TimeAt(e.ScreenSpaceMousePosition);
|
||||
HitObject.Column = Column.Index;
|
||||
|
||||
BeginPlacement();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
EndPlacement();
|
||||
return base.OnMouseUp(e);
|
||||
}
|
||||
|
||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
if (!PlacementBegun)
|
||||
Column = ColumnAt(e.ScreenSpaceMousePosition);
|
||||
|
||||
if (Column == null) return false;
|
||||
|
||||
SnappedWidth = Column.DrawWidth;
|
||||
|
||||
// Snap to the column
|
||||
var parentPos = Parent.ToLocalSpace(Column.ToScreenSpace(new Vector2(Column.DrawWidth / 2, 0)));
|
||||
SnappedMousePosition = new Vector2(parentPos.X, e.MousePosition.Y);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected double TimeAt(Vector2 screenSpacePosition)
|
||||
{
|
||||
if (Column == null)
|
||||
return 0;
|
||||
|
||||
var hitObjectContainer = Column.HitObjectContainer;
|
||||
|
||||
// If we're scrolling downwards, a position of 0 is actually further away from the hit target
|
||||
// so we need to flip the vertical coordinate in the hitobject container's space
|
||||
var hitObjectPos = Column.HitObjectContainer.ToLocalSpace(applyPositionOffset(screenSpacePosition, false)).Y;
|
||||
if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
|
||||
hitObjectPos = hitObjectContainer.DrawHeight - hitObjectPos;
|
||||
|
||||
return scrollingInfo.Algorithm.TimeAt(hitObjectPos,
|
||||
EditorClock.CurrentTime,
|
||||
scrollingInfo.TimeRange.Value,
|
||||
hitObjectContainer.DrawHeight);
|
||||
}
|
||||
|
||||
protected float PositionAt(double time)
|
||||
{
|
||||
var pos = scrollingInfo.Algorithm.PositionAt(time,
|
||||
EditorClock.CurrentTime,
|
||||
scrollingInfo.TimeRange.Value,
|
||||
Column.HitObjectContainer.DrawHeight);
|
||||
|
||||
return applyPositionOffset(Column.HitObjectContainer.ToSpaceOfOtherDrawable(new Vector2(0, pos), Parent), true).Y;
|
||||
}
|
||||
|
||||
protected Column ColumnAt(Vector2 screenSpacePosition)
|
||||
=> composer.ColumnAt(applyPositionOffset(screenSpacePosition, false));
|
||||
|
||||
private Vector2 applyPositionOffset(Vector2 position, bool reverse)
|
||||
{
|
||||
position.Y += (scrollingInfo.Direction.Value == ScrollingDirection.Up && !reverse ? -1 : 1) * NotePiece.NOTE_HEIGHT / 2;
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
{
|
||||
public class ManiaSelectionBlueprint : SelectionBlueprint
|
||||
{
|
||||
public Vector2 ScreenSpaceDragPosition { get; private set; }
|
||||
public Vector2 DragPosition { get; private set; }
|
||||
|
||||
protected new DrawableManiaHitObject HitObject => (DrawableManiaHitObject)base.HitObject;
|
||||
|
||||
protected IClock EditorClock { get; private set; }
|
||||
@ -22,6 +25,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
[Resolved]
|
||||
private IScrollingInfo scrollingInfo { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IManiaHitObjectComposer composer { get; set; }
|
||||
|
||||
public ManiaSelectionBlueprint(DrawableHitObject hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
@ -41,27 +47,22 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
Position = Parent.ToLocalSpace(HitObject.ToScreenSpace(Vector2.Zero));
|
||||
}
|
||||
|
||||
public override void AdjustPosition(DragEvent dragEvent)
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
var objectParent = HitObject.Parent;
|
||||
ScreenSpaceDragPosition = e.ScreenSpaceMousePosition;
|
||||
DragPosition = HitObject.ToLocalSpace(e.ScreenSpaceMousePosition);
|
||||
|
||||
// Using the hitobject position is required since AdjustPosition can be invoked multiple times per frame
|
||||
// without the position having been updated by the parenting ScrollingHitObjectContainer
|
||||
HitObject.Y += dragEvent.Delta.Y;
|
||||
return base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
float targetPosition;
|
||||
protected override bool OnDrag(DragEvent e)
|
||||
{
|
||||
var result = base.OnDrag(e);
|
||||
|
||||
// If we're scrolling downwards, a position of 0 is actually further away from the hit target
|
||||
// so we need to flip the vertical coordinate in the hitobject container's space
|
||||
if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
|
||||
targetPosition = -HitObject.Position.Y;
|
||||
else
|
||||
targetPosition = HitObject.Position.Y;
|
||||
ScreenSpaceDragPosition = e.ScreenSpaceMousePosition;
|
||||
DragPosition = HitObject.ToLocalSpace(e.ScreenSpaceMousePosition);
|
||||
|
||||
HitObject.HitObject.StartTime = scrollingInfo.Algorithm.TimeAt(targetPosition,
|
||||
EditorClock.CurrentTime,
|
||||
scrollingInfo.TimeRange.Value,
|
||||
objectParent.DrawHeight);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
|
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
{
|
||||
public class NotePlacementBlueprint : ManiaPlacementBlueprint<Note>
|
||||
{
|
||||
public NotePlacementBlueprint()
|
||||
: base(new Note())
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChild = new EditNotePiece { RelativeSizeAxes = Axes.X };
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Width = SnappedWidth;
|
||||
Position = SnappedMousePosition;
|
||||
}
|
||||
}
|
||||
}
|
19
osu.Game.Rulesets.Mania/Edit/HoldNoteCompositionTool.cs
Normal file
19
osu.Game.Rulesets.Mania/Edit/HoldNoteCompositionTool.cs
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public class HoldNoteCompositionTool : HitObjectCompositionTool
|
||||
{
|
||||
public HoldNoteCompositionTool()
|
||||
: base("Hold")
|
||||
{
|
||||
}
|
||||
|
||||
public override PlacementBlueprint CreatePlacementBlueprint() => new HoldNotePlacementBlueprint();
|
||||
}
|
||||
}
|
15
osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs
Normal file
15
osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public interface IManiaHitObjectComposer
|
||||
{
|
||||
Column ColumnAt(Vector2 screenSpacePosition);
|
||||
|
||||
int TotalColumns { get; }
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
@ -11,33 +10,54 @@ using osu.Game.Rulesets.Objects.Drawables;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>
|
||||
[Cached(Type = typeof(IManiaHitObjectComposer))]
|
||||
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>, IManiaHitObjectComposer
|
||||
{
|
||||
protected new ManiaEditRulesetContainer RulesetContainer { get; private set; }
|
||||
|
||||
public ManiaHitObjectComposer(Ruleset ruleset)
|
||||
: base(ruleset)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the column that intersects a screen-space position.
|
||||
/// </summary>
|
||||
/// <param name="screenSpacePosition">The screen-space position.</param>
|
||||
/// <returns>The column which intersects with <paramref name="screenSpacePosition"/>.</returns>
|
||||
public Column ColumnAt(Vector2 screenSpacePosition) => RulesetContainer.GetColumnByPosition(screenSpacePosition);
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
public int TotalColumns => ((ManiaPlayfield)RulesetContainer.Playfield).TotalColumns;
|
||||
|
||||
protected override RulesetContainer<ManiaHitObject> CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
{
|
||||
var rulesetContainer = new ManiaEditRulesetContainer(ruleset, beatmap);
|
||||
RulesetContainer = new ManiaEditRulesetContainer(ruleset, beatmap);
|
||||
|
||||
// This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it
|
||||
dependencies.CacheAs(rulesetContainer.ScrollingInfo);
|
||||
dependencies.CacheAs(RulesetContainer.ScrollingInfo);
|
||||
|
||||
return rulesetContainer;
|
||||
return RulesetContainer;
|
||||
}
|
||||
|
||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => Array.Empty<HitObjectCompositionTool>();
|
||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
|
||||
{
|
||||
new NoteCompositionTool(),
|
||||
new HoldNoteCompositionTool()
|
||||
};
|
||||
|
||||
public override SelectionHandler CreateSelectionHandler() => new ManiaSelectionHandler();
|
||||
|
||||
public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
|
||||
{
|
||||
|
125
osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
Normal file
125
osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
Normal file
@ -0,0 +1,125 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public class ManiaSelectionHandler : SelectionHandler
|
||||
{
|
||||
[Resolved]
|
||||
private IScrollingInfo scrollingInfo { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IManiaHitObjectComposer composer { get; set; }
|
||||
|
||||
private IClock editorClock;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IAdjustableClock clock)
|
||||
{
|
||||
editorClock = clock;
|
||||
}
|
||||
|
||||
public override void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent)
|
||||
{
|
||||
adjustOrigins((ManiaSelectionBlueprint)blueprint);
|
||||
performDragMovement(dragEvent);
|
||||
performColumnMovement(dragEvent);
|
||||
|
||||
base.HandleDrag(blueprint, dragEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the position of hitobjects remains centred to the mouse position.
|
||||
/// E.g. The hitobject position will change if the editor scrolls while a hitobject is dragged.
|
||||
/// </summary>
|
||||
/// <param name="reference">The <see cref="ManiaSelectionBlueprint"/> that received the drag event.</param>
|
||||
private void adjustOrigins(ManiaSelectionBlueprint reference)
|
||||
{
|
||||
var referenceParent = (HitObjectContainer)reference.HitObject.Parent;
|
||||
|
||||
float offsetFromReferenceOrigin = reference.DragPosition.Y - reference.HitObject.OriginPosition.Y;
|
||||
float targetPosition = referenceParent.ToLocalSpace(reference.ScreenSpaceDragPosition).Y - offsetFromReferenceOrigin;
|
||||
|
||||
// Flip the vertical coordinate space when scrolling downwards
|
||||
if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
|
||||
targetPosition = targetPosition - referenceParent.DrawHeight;
|
||||
|
||||
float movementDelta = targetPosition - reference.HitObject.Position.Y;
|
||||
|
||||
foreach (var b in SelectedBlueprints.OfType<ManiaSelectionBlueprint>())
|
||||
b.HitObject.Y += movementDelta;
|
||||
}
|
||||
|
||||
private void performDragMovement(DragEvent dragEvent)
|
||||
{
|
||||
foreach (var b in SelectedBlueprints)
|
||||
{
|
||||
var hitObject = b.HitObject;
|
||||
|
||||
var objectParent = (HitObjectContainer)hitObject.Parent;
|
||||
|
||||
// Using the hitobject position is required since AdjustPosition can be invoked multiple times per frame
|
||||
// without the position having been updated by the parenting ScrollingHitObjectContainer
|
||||
hitObject.Y += dragEvent.Delta.Y;
|
||||
|
||||
float targetPosition;
|
||||
|
||||
// If we're scrolling downwards, a position of 0 is actually further away from the hit target
|
||||
// so we need to flip the vertical coordinate in the hitobject container's space
|
||||
if (scrollingInfo.Direction.Value == ScrollingDirection.Down)
|
||||
targetPosition = -hitObject.Position.Y;
|
||||
else
|
||||
targetPosition = hitObject.Position.Y;
|
||||
|
||||
objectParent.Remove(hitObject);
|
||||
|
||||
hitObject.HitObject.StartTime = scrollingInfo.Algorithm.TimeAt(targetPosition,
|
||||
editorClock.CurrentTime,
|
||||
scrollingInfo.TimeRange.Value,
|
||||
objectParent.DrawHeight);
|
||||
|
||||
objectParent.Add(hitObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void performColumnMovement(DragEvent dragEvent)
|
||||
{
|
||||
var lastColumn = composer.ColumnAt(dragEvent.ScreenSpaceLastMousePosition);
|
||||
var currentColumn = composer.ColumnAt(dragEvent.ScreenSpaceMousePosition);
|
||||
if (lastColumn == null || currentColumn == null)
|
||||
return;
|
||||
|
||||
int columnDelta = currentColumn.Index - lastColumn.Index;
|
||||
if (columnDelta == 0)
|
||||
return;
|
||||
|
||||
int minColumn = int.MaxValue;
|
||||
int maxColumn = int.MinValue;
|
||||
|
||||
foreach (var obj in SelectedHitObjects.OfType<ManiaHitObject>())
|
||||
{
|
||||
if (obj.Column < minColumn)
|
||||
minColumn = obj.Column;
|
||||
if (obj.Column > maxColumn)
|
||||
maxColumn = obj.Column;
|
||||
}
|
||||
|
||||
columnDelta = MathHelper.Clamp(columnDelta, -minColumn, composer.TotalColumns - 1 - maxColumn);
|
||||
|
||||
foreach (var obj in SelectedHitObjects.OfType<ManiaHitObject>())
|
||||
obj.Column += columnDelta;
|
||||
}
|
||||
}
|
||||
}
|
20
osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs
Normal file
20
osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public class NoteCompositionTool : HitObjectCompositionTool
|
||||
{
|
||||
public NoteCompositionTool()
|
||||
: base(nameof(Note))
|
||||
{
|
||||
}
|
||||
|
||||
public override PlacementBlueprint CreatePlacementBlueprint() => new NotePlacementBlueprint();
|
||||
}
|
||||
}
|
@ -15,12 +15,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
/// <summary>
|
||||
/// Represents length-wise portion of a hold note.
|
||||
/// </summary>
|
||||
internal class BodyPiece : Container, IHasAccentColour
|
||||
public class BodyPiece : Container, IHasAccentColour
|
||||
{
|
||||
private readonly Container subtractionLayer;
|
||||
|
||||
private readonly Drawable background;
|
||||
private readonly BufferedContainer foreground;
|
||||
protected readonly Drawable Background;
|
||||
protected readonly BufferedContainer Foreground;
|
||||
private readonly BufferedContainer subtractionContainer;
|
||||
|
||||
public BodyPiece()
|
||||
@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
background = new Box { RelativeSizeAxes = Axes.Both },
|
||||
foreground = new BufferedContainer
|
||||
Background = new Box { RelativeSizeAxes = Axes.Both },
|
||||
Foreground = new BufferedContainer
|
||||
{
|
||||
Blending = BlendingMode.Additive,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
Radius = DrawWidth
|
||||
};
|
||||
|
||||
foreground.ForceRedraw();
|
||||
Foreground.ForceRedraw();
|
||||
subtractionContainer.ForceRedraw();
|
||||
|
||||
subtractionCache.Validate();
|
||||
@ -137,18 +137,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
if (!IsLoaded)
|
||||
return;
|
||||
|
||||
foreground.Colour = AccentColour.Opacity(0.5f);
|
||||
background.Colour = AccentColour.Opacity(0.7f);
|
||||
Foreground.Colour = AccentColour.Opacity(0.5f);
|
||||
Background.Colour = AccentColour.Opacity(0.7f);
|
||||
|
||||
const float animation_length = 50;
|
||||
|
||||
foreground.ClearTransforms(false, nameof(foreground.Colour));
|
||||
Foreground.ClearTransforms(false, nameof(Foreground.Colour));
|
||||
if (hitting)
|
||||
{
|
||||
// wait for the next sync point
|
||||
double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2);
|
||||
using (foreground.BeginDelayedSequence(synchronisedOffset))
|
||||
foreground.FadeColour(AccentColour.Lighten(0.2f), animation_length).Then().FadeColour(foreground.Colour, animation_length).Loop();
|
||||
using (Foreground.BeginDelayedSequence(synchronisedOffset))
|
||||
Foreground.FadeColour(AccentColour.Lighten(0.2f), animation_length).Then().FadeColour(Foreground.Colour, animation_length).Loop();
|
||||
}
|
||||
|
||||
subtractionCache.Invalidate();
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Game.Rulesets.Mania.Objects.Types;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
@ -8,7 +9,13 @@ namespace osu.Game.Rulesets.Mania.Objects
|
||||
{
|
||||
public abstract class ManiaHitObject : HitObject, IHasColumn
|
||||
{
|
||||
public virtual int Column { get; set; }
|
||||
public readonly Bindable<int> ColumnBindable = new Bindable<int>();
|
||||
|
||||
public virtual int Column
|
||||
{
|
||||
get => ColumnBindable;
|
||||
set => ColumnBindable.Value = value;
|
||||
}
|
||||
|
||||
protected override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.UI.Components;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
@ -21,6 +22,11 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
private const float column_width = 45;
|
||||
private const float special_column_width = 70;
|
||||
|
||||
/// <summary>
|
||||
/// The index of this column as part of the whole playfield.
|
||||
/// </summary>
|
||||
public readonly int Index;
|
||||
|
||||
public readonly Bindable<ManiaAction> Action = new Bindable<ManiaAction>();
|
||||
|
||||
private readonly ColumnBackground background;
|
||||
@ -30,8 +36,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
internal readonly Container TopLevelContainer;
|
||||
private readonly Container explosionContainer;
|
||||
|
||||
public Column()
|
||||
public Column(int index)
|
||||
{
|
||||
Index = index;
|
||||
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Width = column_width;
|
||||
|
||||
@ -137,11 +145,13 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
HitObjectContainer.Add(hitObject);
|
||||
}
|
||||
|
||||
public override void Remove(DrawableHitObject h)
|
||||
public override bool Remove(DrawableHitObject h)
|
||||
{
|
||||
h.OnNewResult -= OnNewResult;
|
||||
if (!base.Remove(h))
|
||||
return false;
|
||||
|
||||
HitObjectContainer.Remove(h);
|
||||
h.OnNewResult -= OnNewResult;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
|
||||
@ -172,5 +182,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
}
|
||||
|
||||
public bool OnReleased(ManiaAction action) => false;
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos)
|
||||
// This probably shouldn't exist as is, but the columns in the stage are separated by a 1px border
|
||||
=> DrawRectangle.Inflate(new Vector2(ManiaStage.COLUMN_SPACING / 2, 0)).Contains(ToLocalSpace(screenSpacePos));
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
@ -17,6 +18,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => stages.Any(s => s.ReceivePositionalInputAt(screenSpacePos));
|
||||
|
||||
public ManiaPlayfield(List<StageDefinition> stageDefinitions)
|
||||
{
|
||||
if (stageDefinitions == null)
|
||||
@ -52,10 +55,42 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
public override void Add(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Add(h);
|
||||
|
||||
public override void Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h);
|
||||
public override bool Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h);
|
||||
|
||||
public void Add(BarLine barline) => stages.ForEach(s => s.Add(barline));
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a column from a screen-space position.
|
||||
/// </summary>
|
||||
/// <param name="screenSpacePosition">The screen-space position.</param>
|
||||
/// <returns>The column which the <paramref name="screenSpacePosition"/> lies in.</returns>
|
||||
public Column GetColumnByPosition(Vector2 screenSpacePosition)
|
||||
{
|
||||
Column found = null;
|
||||
|
||||
foreach (var stage in stages)
|
||||
{
|
||||
foreach (var column in stage.Columns)
|
||||
{
|
||||
if (column.ReceivePositionalInputAt(screenSpacePosition))
|
||||
{
|
||||
found = column;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found != null)
|
||||
break;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the total amount of columns across all stages in this playfield.
|
||||
/// </summary>
|
||||
public int TotalColumns => stages.Sum(s => s.Columns.Count);
|
||||
|
||||
private ManiaStage getStageByColumn(int column)
|
||||
{
|
||||
int sum = 0;
|
||||
|
@ -25,6 +25,7 @@ using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
@ -80,6 +81,13 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
Config.BindWith(ManiaSetting.ScrollTime, TimeRange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the column that intersects a screen-space position.
|
||||
/// </summary>
|
||||
/// <param name="screenSpacePosition">The screen-space position.</param>
|
||||
/// <returns>The column which intersects with <paramref name="screenSpacePosition"/>.</returns>
|
||||
public Column GetColumnByPosition(Vector2 screenSpacePosition) => Playfield.GetColumnByPosition(screenSpacePosition);
|
||||
|
||||
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
|
@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
/// </summary>
|
||||
public class ManiaStage : ScrollingPlayfield
|
||||
{
|
||||
public const float COLUMN_SPACING = 1;
|
||||
|
||||
public const float HIT_TARGET_POSITION = 50;
|
||||
|
||||
public IReadOnlyList<Column> Columns => columnFlow.Children;
|
||||
@ -40,6 +42,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
private List<Color4> normalColumnColours = new List<Color4>();
|
||||
private Color4 specialColumnColour;
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Columns.Any(c => c.ReceivePositionalInputAt(screenSpacePos));
|
||||
|
||||
private readonly int firstColumnIndex;
|
||||
|
||||
public ManiaStage(int firstColumnIndex, StageDefinition definition, ref ManiaAction normalColumnStartAction, ref ManiaAction specialColumnStartAction)
|
||||
@ -84,8 +88,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding { Left = 1, Right = 1 },
|
||||
Spacing = new Vector2(1, 0)
|
||||
Padding = new MarginPadding { Left = COLUMN_SPACING, Right = COLUMN_SPACING },
|
||||
Spacing = new Vector2(COLUMN_SPACING, 0)
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -123,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
for (int i = 0; i < definition.Columns; i++)
|
||||
{
|
||||
var isSpecial = definition.IsSpecialColumn(i);
|
||||
var column = new Column
|
||||
var column = new Column(firstColumnIndex + i)
|
||||
{
|
||||
IsSpecial = isSpecial,
|
||||
Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }
|
||||
@ -152,18 +156,29 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
public override void Add(DrawableHitObject h)
|
||||
{
|
||||
var maniaObject = (ManiaHitObject)h.HitObject;
|
||||
int columnIndex = maniaObject.Column - firstColumnIndex;
|
||||
Columns.ElementAt(columnIndex).Add(h);
|
||||
|
||||
int columnIndex = -1;
|
||||
|
||||
maniaObject.ColumnBindable.BindValueChanged(_ =>
|
||||
{
|
||||
if (columnIndex != -1)
|
||||
Columns.ElementAt(columnIndex).Remove(h);
|
||||
|
||||
columnIndex = maniaObject.Column - firstColumnIndex;
|
||||
Columns.ElementAt(columnIndex).Add(h);
|
||||
}, true);
|
||||
|
||||
h.OnNewResult += OnNewResult;
|
||||
}
|
||||
|
||||
public override void Remove(DrawableHitObject h)
|
||||
public override bool Remove(DrawableHitObject h)
|
||||
{
|
||||
var maniaObject = (ManiaHitObject)h.HitObject;
|
||||
int columnIndex = maniaObject.Column - firstColumnIndex;
|
||||
Columns.ElementAt(columnIndex).Remove(h);
|
||||
|
||||
h.OnNewResult -= OnNewResult;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Add(BarLine barline) => base.Add(new DrawableBarLine(barline));
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
@ -16,7 +15,5 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints
|
||||
: base(hitObject)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AdjustPosition(DragEvent dragEvent) => OsuObject.Position += dragEvent.Delta;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
@ -10,13 +9,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||
{
|
||||
public class SliderCircleSelectionBlueprint : OsuSelectionBlueprint
|
||||
{
|
||||
private readonly Slider slider;
|
||||
|
||||
public SliderCircleSelectionBlueprint(DrawableOsuHitObject hitObject, Slider slider, SliderPosition position)
|
||||
: base(hitObject)
|
||||
{
|
||||
this.slider = slider;
|
||||
|
||||
InternalChild = new SliderCirclePiece(slider, position);
|
||||
|
||||
Select();
|
||||
@ -24,7 +19,5 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||
|
||||
// Todo: This is temporary, since the slider circle masks don't do anything special yet. In the future they will handle input.
|
||||
public override bool HandlePositionalInput => false;
|
||||
|
||||
public override void AdjustPosition(DragEvent dragEvent) => slider.Position += dragEvent.Delta;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
@ -20,10 +19,5 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
|
||||
}
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => piece.ReceivePositionalInputAt(screenSpacePos);
|
||||
|
||||
public override void AdjustPosition(DragEvent dragEvent)
|
||||
{
|
||||
// Spinners don't support position adjustments
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
@ -35,6 +36,8 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
new SpinnerCompositionTool()
|
||||
};
|
||||
|
||||
public override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler();
|
||||
|
||||
protected override Container CreateLayerContainer() => new PlayfieldAdjustmentContainer { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
|
||||
|
30
osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
Normal file
30
osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public class OsuSelectionHandler : SelectionHandler
|
||||
{
|
||||
public override void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent)
|
||||
{
|
||||
foreach (var h in SelectedHitObjects.OfType<OsuHitObject>())
|
||||
{
|
||||
if (h is Spinner)
|
||||
{
|
||||
// Spinners don't support position adjustments
|
||||
continue;
|
||||
}
|
||||
|
||||
h.Position += dragEvent.Delta;
|
||||
}
|
||||
|
||||
base.HandleDrag(blueprint, dragEvent);
|
||||
}
|
||||
}
|
||||
}
|
@ -16,8 +16,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
public class DrawableOsuHitObject : DrawableHitObject<OsuHitObject>
|
||||
{
|
||||
public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Clock?.CurrentTime >= HitObject.StartTime - HitObject.TimePreempt;
|
||||
|
||||
private readonly ShakeContainer shakeContainer;
|
||||
|
||||
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
||||
|
@ -217,6 +217,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Idle:
|
||||
Expire(true);
|
||||
break;
|
||||
case ArmedState.Hit:
|
||||
sequence.ScaleTo(Scale * 1.2f, 320, Easing.Out);
|
||||
break;
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(SelectionBox),
|
||||
typeof(SelectionHandler),
|
||||
typeof(DragBox),
|
||||
typeof(HitObjectComposer),
|
||||
typeof(OsuHitObjectComposer),
|
||||
|
@ -43,6 +43,7 @@ namespace osu.Game.Input.Bindings
|
||||
|
||||
new KeyBinding(InputKey.Space, GlobalAction.Select),
|
||||
new KeyBinding(InputKey.Enter, GlobalAction.Select),
|
||||
new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select),
|
||||
};
|
||||
|
||||
public IEnumerable<KeyBinding> InGameKeyBindings => new[]
|
||||
|
@ -178,6 +178,7 @@ namespace osu.Game.Online.API
|
||||
AddParameter("grant_type", GrantType);
|
||||
AddParameter("client_id", ClientId);
|
||||
AddParameter("client_secret", ClientSecret);
|
||||
AddParameter("scope", "*");
|
||||
|
||||
base.PrePerform();
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ namespace osu.Game.Rulesets.Edit
|
||||
// Process object
|
||||
var processor = ruleset.CreateBeatmapProcessor(beatmap);
|
||||
|
||||
processor.PreProcess();
|
||||
processor?.PreProcess();
|
||||
tObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty);
|
||||
processor.PostProcess();
|
||||
processor?.PostProcess();
|
||||
|
||||
// Add visual representation
|
||||
var drawableObject = rulesetContainer.GetVisualRepresentation(tObject);
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
public abstract class HitObjectComposer : CompositeDrawable
|
||||
{
|
||||
public IEnumerable<DrawableHitObject> HitObjects => rulesetContainer.Playfield.AllHitObjects;
|
||||
public IEnumerable<DrawableHitObject> HitObjects => RulesetContainer.Playfield.AllHitObjects;
|
||||
|
||||
protected readonly Ruleset Ruleset;
|
||||
|
||||
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
private readonly List<Container> layerContainers = new List<Container>();
|
||||
|
||||
private EditRulesetContainer rulesetContainer;
|
||||
protected EditRulesetContainer RulesetContainer { get; private set; }
|
||||
|
||||
private BlueprintContainer blueprintContainer;
|
||||
|
||||
@ -54,8 +54,8 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
try
|
||||
{
|
||||
rulesetContainer = CreateRulesetContainer();
|
||||
rulesetContainer.Clock = framedClock;
|
||||
RulesetContainer = CreateRulesetContainer();
|
||||
RulesetContainer.Clock = framedClock;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
Children = new Drawable[]
|
||||
{
|
||||
layerBelowRuleset,
|
||||
rulesetContainer,
|
||||
RulesetContainer,
|
||||
layerAboveRuleset
|
||||
}
|
||||
}
|
||||
@ -140,25 +140,25 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
layerContainers.ForEach(l =>
|
||||
{
|
||||
l.Anchor = rulesetContainer.Playfield.Anchor;
|
||||
l.Origin = rulesetContainer.Playfield.Origin;
|
||||
l.Position = rulesetContainer.Playfield.Position;
|
||||
l.Size = rulesetContainer.Playfield.Size;
|
||||
l.Anchor = RulesetContainer.Playfield.Anchor;
|
||||
l.Origin = RulesetContainer.Playfield.Origin;
|
||||
l.Position = RulesetContainer.Playfield.Position;
|
||||
l.Size = RulesetContainer.Playfield.Size;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the user's cursor is currently in an area of the <see cref="HitObjectComposer"/> that is valid for placement.
|
||||
/// </summary>
|
||||
public virtual bool CursorInPlacementArea => rulesetContainer.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
||||
public virtual bool CursorInPlacementArea => RulesetContainer.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmaps.Beatmap"/> and visualises it.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to add.</param>
|
||||
public void Add(HitObject hitObject) => blueprintContainer.AddBlueprintFor(rulesetContainer.Add(hitObject));
|
||||
public void Add(HitObject hitObject) => blueprintContainer.AddBlueprintFor(RulesetContainer.Add(hitObject));
|
||||
|
||||
public void Remove(HitObject hitObject) => blueprintContainer.RemoveBlueprintFor(rulesetContainer.Remove(hitObject));
|
||||
public void Remove(HitObject hitObject) => blueprintContainer.RemoveBlueprintFor(RulesetContainer.Remove(hitObject));
|
||||
|
||||
internal abstract EditRulesetContainer CreateRulesetContainer();
|
||||
|
||||
@ -171,10 +171,9 @@ namespace osu.Game.Rulesets.Edit
|
||||
public virtual SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject) => null;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="SelectionBox"/> which outlines <see cref="DrawableHitObject"/>s
|
||||
/// and handles hitobject pattern adjustments.
|
||||
/// Creates a <see cref="SelectionHandler"/> which outlines <see cref="DrawableHitObject"/>s and handles movement of selections.
|
||||
/// </summary>
|
||||
public virtual SelectionBox CreateSelectionBox() => new SelectionBox();
|
||||
public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="ScalableContainer"/> which provides a layer above or below the <see cref="Playfield"/>.
|
||||
|
@ -7,7 +7,6 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
/// <summary>
|
||||
/// A blueprint which governs the creation of a new <see cref="HitObject"/> to actualisation.
|
||||
/// </summary>
|
||||
public abstract class PlacementBlueprint : CompositeDrawable, IStateful<PlacementState>, IRequireHighFrequencyMousePosition
|
||||
public abstract class PlacementBlueprint : CompositeDrawable, IStateful<PlacementState>
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when <see cref="State"/> has changed.
|
||||
@ -50,6 +49,10 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
// This is required to allow the blueprint's position to be updated via OnMouseMove/Handle
|
||||
// on the same frame it is made visible via a PlacementState change.
|
||||
AlwaysPresent = true;
|
||||
|
||||
Alpha = 0;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
/// <summary>
|
||||
/// Invoked when this <see cref="SelectionBlueprint"/> has requested drag.
|
||||
/// </summary>
|
||||
public event Action<DragEvent> DragRequested;
|
||||
public event Action<SelectionBlueprint, DragEvent> DragRequested;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DrawableHitObject"/> which this <see cref="SelectionBlueprint"/> applies to.
|
||||
@ -130,12 +130,10 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
protected override bool OnDrag(DragEvent e)
|
||||
{
|
||||
DragRequested?.Invoke(e);
|
||||
DragRequested?.Invoke(this, e);
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void AdjustPosition(DragEvent dragEvent);
|
||||
|
||||
/// <summary>
|
||||
/// The screen-space point that causes this <see cref="SelectionBlueprint"/> to be selected.
|
||||
/// </summary>
|
||||
|
@ -84,6 +84,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
public override bool RemoveCompletedTransforms => false;
|
||||
protected override bool RequiresChildrenUpdate => true;
|
||||
|
||||
public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Clock?.CurrentTime >= LifetimeStart;
|
||||
|
||||
public readonly Bindable<ArmedState> State = new Bindable<ArmedState>();
|
||||
|
||||
protected DrawableHitObject(HitObject hitObject)
|
||||
|
@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// Remove a DrawableHitObject from this Playfield.
|
||||
/// </summary>
|
||||
/// <param name="h">The DrawableHitObject to remove.</param>
|
||||
public virtual void Remove(DrawableHitObject h) => HitObjectContainer.Remove(h);
|
||||
public virtual bool Remove(DrawableHitObject h) => HitObjectContainer.Remove(h);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a <see cref="Playfield"/> as a nested <see cref="Playfield"/>.
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
private Container<PlacementBlueprint> placementBlueprintContainer;
|
||||
private PlacementBlueprint currentPlacement;
|
||||
|
||||
private SelectionBox selectionBox;
|
||||
private SelectionHandler selectionHandler;
|
||||
|
||||
private IEnumerable<SelectionBlueprint> selections => selectionBlueprints.Children.Where(c => c.IsAlive);
|
||||
|
||||
@ -37,16 +37,16 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
selectionBox = composer.CreateSelectionBox();
|
||||
selectionBox.DeselectAll = deselectAll;
|
||||
selectionHandler = composer.CreateSelectionHandler();
|
||||
selectionHandler.DeselectAll = deselectAll;
|
||||
|
||||
var dragBox = new DragBox(select);
|
||||
dragBox.DragEnd += () => selectionBox.UpdateVisibility();
|
||||
dragBox.DragEnd += () => selectionHandler.UpdateVisibility();
|
||||
|
||||
InternalChildren = new[]
|
||||
{
|
||||
dragBox,
|
||||
selectionBox,
|
||||
selectionHandler,
|
||||
selectionBlueprints = new SelectionBlueprintContainer { RelativeSizeAxes = Axes.Both },
|
||||
placementBlueprintContainer = new Container<PlacementBlueprint> { RelativeSizeAxes = Axes.Both },
|
||||
dragBox.CreateProxy()
|
||||
@ -168,19 +168,19 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
|
||||
private void onBlueprintSelected(SelectionBlueprint blueprint)
|
||||
{
|
||||
selectionBox.HandleSelected(blueprint);
|
||||
selectionHandler.HandleSelected(blueprint);
|
||||
selectionBlueprints.ChangeChildDepth(blueprint, 1);
|
||||
}
|
||||
|
||||
private void onBlueprintDeselected(SelectionBlueprint blueprint)
|
||||
{
|
||||
selectionBox.HandleDeselected(blueprint);
|
||||
selectionHandler.HandleDeselected(blueprint);
|
||||
selectionBlueprints.ChangeChildDepth(blueprint, 0);
|
||||
}
|
||||
|
||||
private void onSelectionRequested(SelectionBlueprint blueprint, InputState state) => selectionBox.HandleSelectionRequested(blueprint, state);
|
||||
private void onSelectionRequested(SelectionBlueprint blueprint, InputState state) => selectionHandler.HandleSelectionRequested(blueprint, state);
|
||||
|
||||
private void onDragRequested(DragEvent dragEvent) => selectionBox.HandleDrag(dragEvent);
|
||||
private void onDragRequested(SelectionBlueprint blueprint, DragEvent dragEvent) => selectionHandler.HandleDrag(blueprint, dragEvent);
|
||||
|
||||
private class SelectionBlueprintContainer : Container<SelectionBlueprint>
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
Masking = true,
|
||||
BorderColour = Color4.White,
|
||||
BorderThickness = SelectionBox.BORDER_RADIUS,
|
||||
BorderThickness = SelectionHandler.BORDER_RADIUS,
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
@ -12,26 +12,31 @@ using osu.Framework.Input.Events;
|
||||
using osu.Framework.Input.States;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// A box which surrounds <see cref="SelectionBlueprint"/>s and provides interactive handles, context menus etc.
|
||||
/// A component which outlines <see cref="DrawableHitObject"/>s and handles movement of selections.
|
||||
/// </summary>
|
||||
public class SelectionBox : CompositeDrawable
|
||||
public class SelectionHandler : CompositeDrawable
|
||||
{
|
||||
public const float BORDER_RADIUS = 2;
|
||||
|
||||
protected IEnumerable<SelectionBlueprint> SelectedBlueprints => selectedBlueprints;
|
||||
private readonly List<SelectionBlueprint> selectedBlueprints;
|
||||
|
||||
protected IEnumerable<HitObject> SelectedHitObjects => selectedBlueprints.Select(b => b.HitObject.HitObject);
|
||||
|
||||
private Drawable outline;
|
||||
|
||||
[Resolved]
|
||||
private IPlacementHandler placementHandler { get; set; }
|
||||
|
||||
public SelectionBox()
|
||||
public SelectionHandler()
|
||||
{
|
||||
selectedBlueprints = new List<SelectionBlueprint>();
|
||||
|
||||
@ -59,12 +64,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
|
||||
#region User Input Handling
|
||||
|
||||
public void HandleDrag(DragEvent dragEvent)
|
||||
/// <summary>
|
||||
/// Handles the selected <see cref="DrawableHitObject"/>s being dragged.
|
||||
/// </summary>
|
||||
/// <param name="blueprint">The <see cref="SelectionBlueprint"/> that received the drag event.</param>
|
||||
/// <param name="dragEvent">The drag event.</param>
|
||||
public virtual void HandleDrag(SelectionBlueprint blueprint, DragEvent dragEvent)
|
||||
{
|
||||
// Todo: Various forms of snapping
|
||||
|
||||
foreach (var blueprint in selectedBlueprints)
|
||||
blueprint.AdjustPosition(dragEvent);
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
@ -90,19 +96,19 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
/// <summary>
|
||||
/// Bind an action to deselect all selected blueprints.
|
||||
/// </summary>
|
||||
public Action DeselectAll { private get; set; }
|
||||
internal Action DeselectAll { private get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Handle a blueprint becoming selected.
|
||||
/// </summary>
|
||||
/// <param name="blueprint">The blueprint.</param>
|
||||
public void HandleSelected(SelectionBlueprint blueprint) => selectedBlueprints.Add(blueprint);
|
||||
internal void HandleSelected(SelectionBlueprint blueprint) => selectedBlueprints.Add(blueprint);
|
||||
|
||||
/// <summary>
|
||||
/// Handle a blueprint becoming deselected.
|
||||
/// </summary>
|
||||
/// <param name="blueprint">The blueprint.</param>
|
||||
public void HandleDeselected(SelectionBlueprint blueprint)
|
||||
internal void HandleDeselected(SelectionBlueprint blueprint)
|
||||
{
|
||||
selectedBlueprints.Remove(blueprint);
|
||||
|
||||
@ -115,7 +121,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
/// Handle a blueprint requesting selection.
|
||||
/// </summary>
|
||||
/// <param name="blueprint">The blueprint.</param>
|
||||
public void HandleSelectionRequested(SelectionBlueprint blueprint, InputState state)
|
||||
internal void HandleSelectionRequested(SelectionBlueprint blueprint, InputState state)
|
||||
{
|
||||
if (state.Keyboard.ControlPressed)
|
||||
{
|
||||
@ -139,7 +145,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Updates whether this <see cref="SelectionBox"/> is visible.
|
||||
/// Updates whether this <see cref="SelectionHandler"/> is visible.
|
||||
/// </summary>
|
||||
internal void UpdateVisibility()
|
||||
{
|
@ -15,18 +15,14 @@ namespace osu.Game.Tests.Visual
|
||||
[Cached(Type = typeof(IPlacementHandler))]
|
||||
public abstract class PlacementBlueprintTestCase : OsuTestCase, IPlacementHandler
|
||||
{
|
||||
private readonly Container hitObjectContainer;
|
||||
protected readonly Container HitObjectContainer;
|
||||
private PlacementBlueprint currentBlueprint;
|
||||
|
||||
protected PlacementBlueprintTestCase()
|
||||
{
|
||||
Beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize = 2;
|
||||
|
||||
Add(hitObjectContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Clock = new FramedClock(new StopwatchClock())
|
||||
});
|
||||
Add(HitObjectContainer = CreateHitObjectContainer());
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -49,7 +45,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
public void EndPlacement(HitObject hitObject)
|
||||
{
|
||||
hitObjectContainer.Add(CreateHitObject(hitObject));
|
||||
AddHitObject(CreateHitObject(hitObject));
|
||||
|
||||
Remove(currentBlueprint);
|
||||
Add(currentBlueprint = CreateBlueprint());
|
||||
@ -59,6 +55,10 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual Container CreateHitObjectContainer() => new Container { RelativeSizeAxes = Axes.Both };
|
||||
|
||||
protected virtual void AddHitObject(DrawableHitObject hitObject) => HitObjectContainer.Add(hitObject);
|
||||
|
||||
protected abstract DrawableHitObject CreateHitObject(HitObject hitObject);
|
||||
protected abstract PlacementBlueprint CreateBlueprint();
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
public double TimeRange { set => scrollingInfo.TimeRange.Value = value; }
|
||||
|
||||
public IScrollingInfo ScrollingInfo => scrollingInfo;
|
||||
|
||||
[Cached(Type = typeof(IScrollingInfo))]
|
||||
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
||||
|
||||
|
@ -24,4 +24,4 @@
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
Loading…
Reference in New Issue
Block a user