mirror of
https://github.com/osukey/osukey.git
synced 2025-06-05 21:07:18 +09:00
Merge pull request #9078 from peppy/editor-move-distance-snap-grid
Move distance snap grid to osu! HitObjectComposer
This commit is contained in:
commit
2f9cc0c15a
@ -4,6 +4,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Caching;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Tools;
|
using osu.Game.Rulesets.Edit.Tools;
|
||||||
@ -12,6 +16,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit
|
namespace osu.Game.Rulesets.Osu.Edit
|
||||||
{
|
{
|
||||||
@ -32,9 +37,80 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
new SpinnerCompositionTool()
|
new SpinnerCompositionTool()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
LayerBelowRuleset.Add(distanceSnapGridContainer = new Container { RelativeSizeAxes = Axes.Both });
|
||||||
|
|
||||||
|
EditorBeatmap.SelectedHitObjects.CollectionChanged += (_, __) => updateDistanceSnapGrid();
|
||||||
|
EditorBeatmap.PlacementObject.ValueChanged += _ => updateDistanceSnapGrid();
|
||||||
|
}
|
||||||
|
|
||||||
protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(HitObjects);
|
protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(HitObjects);
|
||||||
|
|
||||||
protected override DistanceSnapGrid CreateDistanceSnapGrid(IEnumerable<HitObject> selectedHitObjects)
|
private DistanceSnapGrid distanceSnapGrid;
|
||||||
|
private Container distanceSnapGridContainer;
|
||||||
|
|
||||||
|
private readonly Cached distanceSnapGridCache = new Cached();
|
||||||
|
private double? lastDistanceSnapGridTime;
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (!(BlueprintContainer.CurrentTool is SelectTool))
|
||||||
|
{
|
||||||
|
if (EditorClock.CurrentTime != lastDistanceSnapGridTime)
|
||||||
|
{
|
||||||
|
distanceSnapGridCache.Invalidate();
|
||||||
|
lastDistanceSnapGridTime = EditorClock.CurrentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!distanceSnapGridCache.IsValid)
|
||||||
|
updateDistanceSnapGrid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition)
|
||||||
|
{
|
||||||
|
if (distanceSnapGrid == null)
|
||||||
|
return base.SnapScreenSpacePositionToValidTime(screenSpacePosition);
|
||||||
|
|
||||||
|
(Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition));
|
||||||
|
|
||||||
|
return new SnapResult(distanceSnapGrid.ToScreenSpace(pos), time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDistanceSnapGrid()
|
||||||
|
{
|
||||||
|
distanceSnapGridContainer.Clear();
|
||||||
|
distanceSnapGridCache.Invalidate();
|
||||||
|
|
||||||
|
switch (BlueprintContainer.CurrentTool)
|
||||||
|
{
|
||||||
|
case SelectTool _:
|
||||||
|
if (!EditorBeatmap.SelectedHitObjects.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
distanceSnapGrid = createDistanceSnapGrid(EditorBeatmap.SelectedHitObjects);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!CursorInPlacementArea)
|
||||||
|
return;
|
||||||
|
|
||||||
|
distanceSnapGrid = createDistanceSnapGrid(Enumerable.Empty<HitObject>());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distanceSnapGrid != null)
|
||||||
|
{
|
||||||
|
distanceSnapGridContainer.Add(distanceSnapGrid);
|
||||||
|
distanceSnapGridCache.Validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DistanceSnapGrid createDistanceSnapGrid(IEnumerable<HitObject> selectedHitObjects)
|
||||||
{
|
{
|
||||||
if (BlueprintContainer.CurrentTool is SpinnerCompositionTool)
|
if (BlueprintContainer.CurrentTool is SpinnerCompositionTool)
|
||||||
return null;
|
return null;
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -52,8 +52,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
protected ComposeBlueprintContainer BlueprintContainer { get; private set; }
|
protected ComposeBlueprintContainer BlueprintContainer { get; private set; }
|
||||||
|
|
||||||
private DrawableEditRulesetWrapper<TObject> drawableRulesetWrapper;
|
private DrawableEditRulesetWrapper<TObject> drawableRulesetWrapper;
|
||||||
private Container distanceSnapGridContainer;
|
|
||||||
private DistanceSnapGrid distanceSnapGrid;
|
protected readonly Container LayerBelowRuleset = new Container { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
private readonly List<Container> layerContainers = new List<Container>();
|
private readonly List<Container> layerContainers = new List<Container>();
|
||||||
|
|
||||||
private InputManager inputManager;
|
private InputManager inputManager;
|
||||||
@ -87,7 +88,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
|
var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
|
||||||
{
|
{
|
||||||
distanceSnapGridContainer = new Container { RelativeSizeAxes = Axes.Both },
|
LayerBelowRuleset,
|
||||||
new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
|
new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
setSelectTool();
|
setSelectTool();
|
||||||
|
|
||||||
BlueprintContainer.SelectionChanged += selectionChanged;
|
EditorBeatmap.SelectedHitObjects.CollectionChanged += selectionChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
@ -165,16 +166,6 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
inputManager = GetContainingInputManager();
|
inputManager = GetContainingInputManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
private double lastGridUpdateTime;
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
if (EditorClock.CurrentTime != lastGridUpdateTime && !(BlueprintContainer.CurrentTool is SelectTool))
|
|
||||||
showGridFor(Enumerable.Empty<HitObject>());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
protected override void UpdateAfterChildren()
|
||||||
{
|
{
|
||||||
base.UpdateAfterChildren();
|
base.UpdateAfterChildren();
|
||||||
@ -188,19 +179,13 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectionChanged(IEnumerable<HitObject> selectedHitObjects)
|
private void selectionChanged(object sender, NotifyCollectionChangedEventArgs changedArgs)
|
||||||
{
|
{
|
||||||
var hitObjects = selectedHitObjects.ToArray();
|
if (EditorBeatmap.SelectedHitObjects.Any())
|
||||||
|
|
||||||
if (hitObjects.Any())
|
|
||||||
{
|
{
|
||||||
// ensure in selection mode if a selection is made.
|
// ensure in selection mode if a selection is made.
|
||||||
setSelectTool();
|
setSelectTool();
|
||||||
|
|
||||||
showGridFor(hitObjects);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
distanceSnapGridContainer.Hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSelectTool() => toolboxCollection.Items.First().Select();
|
private void setSelectTool() => toolboxCollection.Items.First().Select();
|
||||||
@ -209,30 +194,12 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
{
|
{
|
||||||
BlueprintContainer.CurrentTool = tool;
|
BlueprintContainer.CurrentTool = tool;
|
||||||
|
|
||||||
if (tool is SelectTool)
|
if (!(tool is SelectTool))
|
||||||
distanceSnapGridContainer.Hide();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EditorBeatmap.SelectedHitObjects.Clear();
|
EditorBeatmap.SelectedHitObjects.Clear();
|
||||||
showGridFor(Enumerable.Empty<HitObject>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showGridFor(IEnumerable<HitObject> selectedHitObjects)
|
|
||||||
{
|
|
||||||
distanceSnapGridContainer.Clear();
|
|
||||||
distanceSnapGrid = CreateDistanceSnapGrid(selectedHitObjects);
|
|
||||||
|
|
||||||
if (distanceSnapGrid != null)
|
|
||||||
{
|
|
||||||
distanceSnapGridContainer.Child = distanceSnapGrid;
|
|
||||||
distanceSnapGridContainer.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
lastGridUpdateTime = EditorClock.CurrentTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<DrawableHitObject> HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects;
|
public override IEnumerable<DrawableHitObject> HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects;
|
||||||
|
|
||||||
public override bool CursorInPlacementArea => drawableRulesetWrapper.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
public override bool CursorInPlacementArea => drawableRulesetWrapper.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
||||||
|
|
||||||
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
||||||
@ -257,21 +224,11 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
if (adjustableClock.CurrentTime < hitObject.StartTime)
|
if (adjustableClock.CurrentTime < hitObject.StartTime)
|
||||||
adjustableClock.Seek(hitObject.StartTime);
|
adjustableClock.Seek(hitObject.StartTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
showGridFor(Enumerable.Empty<HitObject>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete(HitObject hitObject) => EditorBeatmap.Remove(hitObject);
|
public void Delete(HitObject hitObject) => EditorBeatmap.Remove(hitObject);
|
||||||
|
|
||||||
public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition)
|
public override SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, null);
|
||||||
{
|
|
||||||
if (distanceSnapGrid == null) return new SnapResult(screenSpacePosition, null);
|
|
||||||
|
|
||||||
// TODO: move distance snap grid to OsuHitObjectComposer.
|
|
||||||
(Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition));
|
|
||||||
|
|
||||||
return new SnapResult(distanceSnapGrid.ToScreenSpace(pos), time);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override float GetBeatSnapDistanceAt(double referenceTime)
|
public override float GetBeatSnapDistanceAt(double referenceTime)
|
||||||
{
|
{
|
||||||
@ -321,14 +278,6 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract bool CursorInPlacementArea { get; }
|
public abstract bool CursorInPlacementArea { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates the <see cref="DistanceSnapGrid"/> applicable for a <see cref="HitObject"/> selection.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="selectedHitObjects">The <see cref="HitObject"/> selection.</param>
|
|
||||||
/// <returns>The <see cref="DistanceSnapGrid"/> for <paramref name="selectedHitObjects"/>. If empty, a grid is returned for the current point in time.</returns>
|
|
||||||
[CanBeNull]
|
|
||||||
protected virtual DistanceSnapGrid CreateDistanceSnapGrid([NotNull] IEnumerable<HitObject> selectedHitObjects) => null;
|
|
||||||
|
|
||||||
public abstract SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition);
|
public abstract SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition);
|
||||||
|
|
||||||
public abstract float GetBeatSnapDistanceAt(double referenceTime);
|
public abstract float GetBeatSnapDistanceAt(double referenceTime);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// 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 System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -29,8 +28,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BlueprintContainer : CompositeDrawable, IKeyBindingHandler<PlatformAction>
|
public abstract class BlueprintContainer : CompositeDrawable, IKeyBindingHandler<PlatformAction>
|
||||||
{
|
{
|
||||||
public event Action<IEnumerable<HitObject>> SelectionChanged;
|
|
||||||
|
|
||||||
protected DragBox DragBox { get; private set; }
|
protected DragBox DragBox { get; private set; }
|
||||||
|
|
||||||
protected Container<SelectionBlueprint> SelectionBlueprints { get; private set; }
|
protected Container<SelectionBlueprint> SelectionBlueprints { get; private set; }
|
||||||
@ -88,8 +85,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
|
SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionChanged?.Invoke(selectedHitObjects);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user