1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 10:03:05 +08:00

Add beat snap grid to the composer

This commit is contained in:
smoogipoo 2019-10-16 20:20:07 +09:00
parent d3e38f5e5a
commit c4704f6a29
2 changed files with 92 additions and 6 deletions

View File

@ -2,10 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
@ -52,5 +54,31 @@ namespace osu.Game.Rulesets.Osu.Edit
return base.CreateBlueprintFor(hitObject);
}
protected override DistanceSnapGrid CreateDistanceSnapGrid(IEnumerable<HitObject> selectedHitObjects)
{
var objects = selectedHitObjects.ToList();
if (objects.Count == 0)
{
var lastObject = EditorBeatmap.HitObjects.LastOrDefault(h => h.StartTime < EditorClock.CurrentTime);
if (lastObject == null)
return null;
return new OsuDistanceSnapGrid(lastObject);
}
else
{
double minTime = objects.Min(h => h.StartTime);
var lastObject = EditorBeatmap.HitObjects.LastOrDefault(h => h.StartTime < minTime);
if (lastObject == null)
return null;
return new OsuDistanceSnapGrid(lastObject);
}
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -33,12 +34,17 @@ namespace osu.Game.Rulesets.Edit
protected EditorBeatmap<TObject> EditorBeatmap { get; private set; }
protected readonly Ruleset Ruleset;
[Resolved]
protected IFrameBasedClock EditorClock { get; private set; }
private IWorkingBeatmap workingBeatmap;
private Beatmap<TObject> playableBeatmap;
private IBeatmapProcessor beatmapProcessor;
private DrawableEditRulesetWrapper<TObject> drawableRulesetWrapper;
private BlueprintContainer blueprintContainer;
private Container distanceSnapGridContainer;
private DistanceSnapGrid distanceSnapGrid;
private readonly List<Container> layerContainers = new List<Container>();
private InputManager inputManager;
@ -65,11 +71,13 @@ namespace osu.Game.Rulesets.Edit
return;
}
var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer();
layerBelowRuleset.Child = new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both };
var layerBelowRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChildren(new Drawable[]
{
distanceSnapGridContainer = new Container { RelativeSizeAxes = Axes.Both },
new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both }
});
var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer();
layerAboveRuleset.Child = blueprintContainer = new BlueprintContainer();
var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChild(blueprintContainer = new BlueprintContainer());
layerContainers.Add(layerBelowRuleset);
layerContainers.Add(layerAboveRuleset);
@ -112,11 +120,13 @@ namespace osu.Game.Rulesets.Edit
};
toolboxCollection.Items =
CompositionTools.Select(t => new RadioButton(t.Name, () => blueprintContainer.CurrentTool = t))
.Prepend(new RadioButton("Select", () => blueprintContainer.CurrentTool = null))
CompositionTools.Select(t => new RadioButton(t.Name, () => selectTool(t)))
.Prepend(new RadioButton("Select", () => selectTool(null)))
.ToList();
toolboxCollection.Items[0].Select();
blueprintContainer.SelectionChanged += selectionChanged;
}
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
@ -149,6 +159,14 @@ namespace osu.Game.Rulesets.Edit
inputManager = GetContainingInputManager();
}
protected override void Update()
{
base.Update();
if (EditorClock.ElapsedFrameTime != 0 && blueprintContainer.CurrentTool != null)
showGridFor(Enumerable.Empty<HitObject>());
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
@ -162,6 +180,38 @@ namespace osu.Game.Rulesets.Edit
});
}
private void selectionChanged(IEnumerable<HitObject> selectedHitObjects)
{
var hitObjects = selectedHitObjects.ToArray();
if (!hitObjects.Any())
distanceSnapGridContainer.Hide();
else
showGridFor(hitObjects);
}
private void selectTool(HitObjectCompositionTool tool)
{
blueprintContainer.CurrentTool = tool;
if (tool == null)
distanceSnapGridContainer.Hide();
else
showGridFor(Enumerable.Empty<HitObject>());
}
private void showGridFor(IEnumerable<HitObject> selectedHitObjects)
{
distanceSnapGridContainer.Clear();
distanceSnapGrid = CreateDistanceSnapGrid(selectedHitObjects);
if (distanceSnapGrid != null)
{
distanceSnapGridContainer.Child = distanceSnapGrid;
distanceSnapGridContainer.Show();
}
}
private void addHitObject(HitObject hitObject) => updateHitObject(hitObject);
private void removeHitObject(HitObject hitObject)
@ -232,5 +282,13 @@ namespace osu.Game.Rulesets.Edit
/// Creates a <see cref="SelectionHandler"/> which outlines <see cref="DrawableHitObject"/>s and handles movement of selections.
/// </summary>
public virtual SelectionHandler CreateSelectionHandler() => new SelectionHandler();
/// <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"/>.</returns>
[CanBeNull]
protected virtual DistanceSnapGrid CreateDistanceSnapGrid([NotNull] IEnumerable<HitObject> selectedHitObjects) => null;
}
}