1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-14 01:42:59 +08:00

Merge pull request #7753 from peppy/placement-display-in-timeline

Show current placement blueprint in timeline
This commit is contained in:
Dan Balasescu 2020-02-10 14:47:39 +09:00 committed by GitHub
commit 36414e9a53
12 changed files with 78 additions and 25 deletions

View File

@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
protected override void OnMouseUp(MouseUpEvent e)
{
EndPlacement();
EndPlacement(true);
base.OnMouseUp(e);
}

View File

@ -30,12 +30,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
protected override bool OnClick(ClickEvent e)
{
EndPlacement();
EndPlacement(true);
return true;
}
public override void UpdatePosition(Vector2 screenSpacePosition)
{
BeginPlacement();
HitObject.Position = ToLocalSpace(screenSpacePosition);
}
}

View File

@ -68,6 +68,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
switch (state)
{
case PlacementState.Initial:
BeginPlacement();
HitObject.Position = ToLocalSpace(screenSpacePosition);
break;
@ -132,7 +133,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
private void endCurve()
{
updateSlider();
EndPlacement();
EndPlacement(true);
}
protected override void Update()

View File

@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
return false;
HitObject.EndTime = EditorClock.CurrentTime;
EndPlacement();
EndPlacement(true);
}
else
{

View File

@ -251,15 +251,22 @@ namespace osu.Game.Rulesets.Edit
public void BeginPlacement(HitObject hitObject)
{
EditorBeatmap.PlacementObject.Value = hitObject;
if (distanceSnapGrid != null)
hitObject.StartTime = GetSnappedPosition(distanceSnapGrid.ToLocalSpace(inputManager.CurrentState.Mouse.Position), hitObject.StartTime).time;
}
public void EndPlacement(HitObject hitObject)
public void EndPlacement(HitObject hitObject, bool commit)
{
EditorBeatmap.Add(hitObject);
EditorBeatmap.PlacementObject.Value = null;
adjustableClock.Seek(hitObject.StartTime);
if (commit)
{
EditorBeatmap.Add(hitObject);
adjustableClock.Seek(hitObject.StartTime);
}
showGridFor(Enumerable.Empty<HitObject>());
}

View File

@ -103,11 +103,12 @@ namespace osu.Game.Rulesets.Edit
/// Signals that the placement of <see cref="HitObject"/> has finished.
/// This will destroy this <see cref="PlacementBlueprint"/>, and add the <see cref="HitObject"/> to the <see cref="Beatmap"/>.
/// </summary>
protected void EndPlacement()
/// <param name="commit">Whether the object should be committed.</param>
public void EndPlacement(bool commit)
{
if (!PlacementBegun)
BeginPlacement();
placementHandler.EndPlacement(HitObject);
placementHandler.EndPlacement(HitObject, commit);
}
/// <summary>

View File

@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected DragBox DragBox { get; private set; }
private Container<SelectionBlueprint> selectionBlueprints;
protected Container<SelectionBlueprint> SelectionBlueprints { get; private set; }
private SelectionHandler selectionHandler;
@ -62,7 +62,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
DragBox = CreateDragBox(select),
selectionHandler,
selectionBlueprints = CreateSelectionBlueprintContainer(),
SelectionBlueprints = CreateSelectionBlueprintContainer(),
DragBox.CreateProxy().With(p => p.Depth = float.MinValue)
});
@ -73,7 +73,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
selectedHitObjects.ItemsAdded += objects =>
{
foreach (var o in objects)
selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select();
SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select();
SelectionChanged?.Invoke(selectedHitObjects);
};
@ -81,7 +81,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
selectedHitObjects.ItemsRemoved += objects =>
{
foreach (var o in objects)
selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
SelectionChanged?.Invoke(selectedHitObjects);
};
@ -230,7 +230,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void removeBlueprintFor(HitObject hitObject)
{
var blueprint = selectionBlueprints.SingleOrDefault(m => m.HitObject == hitObject);
var blueprint = SelectionBlueprints.SingleOrDefault(m => m.HitObject == hitObject);
if (blueprint == null)
return;
@ -239,7 +239,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
blueprint.Selected -= onBlueprintSelected;
blueprint.Deselected -= onBlueprintDeselected;
selectionBlueprints.Remove(blueprint);
SelectionBlueprints.Remove(blueprint);
}
protected virtual void AddBlueprintFor(HitObject hitObject)
@ -251,7 +251,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
blueprint.Selected += onBlueprintSelected;
blueprint.Deselected += onBlueprintDeselected;
selectionBlueprints.Add(blueprint);
SelectionBlueprints.Add(blueprint);
}
#endregion
@ -278,7 +278,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (!allowDeselection && selectionHandler.SelectedBlueprints.Any(s => s.IsHovered))
return;
foreach (SelectionBlueprint blueprint in selectionBlueprints.AliveChildren)
foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren)
{
if (blueprint.IsHovered)
{
@ -308,7 +308,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// <param name="rect">The rectangle to perform a selection on in screen-space coordinates.</param>
private void select(RectangleF rect)
{
foreach (var blueprint in selectionBlueprints)
foreach (var blueprint in SelectionBlueprints)
{
if (blueprint.IsAlive && blueprint.IsPresent && rect.Contains(blueprint.SelectionPoint))
blueprint.Select();
@ -322,7 +322,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// </summary>
private void selectAll()
{
selectionBlueprints.ToList().ForEach(m => m.Select());
SelectionBlueprints.ToList().ForEach(m => m.Select());
selectionHandler.UpdateVisibility();
}
@ -334,14 +334,14 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void onBlueprintSelected(SelectionBlueprint blueprint)
{
selectionHandler.HandleSelected(blueprint);
selectionBlueprints.ChangeChildDepth(blueprint, 1);
SelectionBlueprints.ChangeChildDepth(blueprint, 1);
beatmap.SelectedHitObjects.Add(blueprint.HitObject);
}
private void onBlueprintDeselected(SelectionBlueprint blueprint)
{
selectionHandler.HandleDeselected(blueprint);
selectionBlueprints.ChangeChildDepth(blueprint, 0);
SelectionBlueprints.ChangeChildDepth(blueprint, 0);
beatmap.SelectedHitObjects.Remove(blueprint.HitObject);
}

View File

@ -63,6 +63,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void refreshTool()
{
placementBlueprintContainer.Clear();
currentPlacement?.EndPlacement(false);
currentPlacement = null;
var blueprint = CurrentTool?.CreatePlacementBlueprint();

View File

@ -3,6 +3,7 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
@ -21,8 +22,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
[Resolved(CanBeNull = true)]
private Timeline timeline { get; set; }
[Resolved]
private EditorBeatmap beatmap { get; set; }
private DragEvent lastDragEvent;
private Bindable<HitObject> placement;
private SelectionBlueprint placementBlueprint;
public TimelineBlueprintContainer()
{
RelativeSizeAxes = Axes.Both;
@ -43,6 +51,29 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
base.LoadComplete();
DragBox.Alpha = 0;
placement = beatmap.PlacementObject.GetBoundCopy();
placement.ValueChanged += placementChanged;
}
private void placementChanged(ValueChangedEvent<HitObject> obj)
{
if (obj.NewValue == null)
{
if (placementBlueprint != null)
{
SelectionBlueprints.Remove(placementBlueprint);
placementBlueprint = null;
}
}
else
{
placementBlueprint = CreateBlueprintFor(obj.NewValue);
placementBlueprint.Colour = Color4.MediumPurple;
SelectionBlueprints.Add(placementBlueprint);
}
}
protected override Container<SelectionBlueprint> CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both };

View File

@ -17,7 +17,8 @@ namespace osu.Game.Screens.Edit.Compose
/// Notifies that a placement has finished.
/// </summary>
/// <param name="hitObject">The <see cref="HitObject"/> that has been placed.</param>
void EndPlacement(HitObject hitObject);
/// <param name="commit">Whether the object should be committed.</param>
void EndPlacement(HitObject hitObject, bool commit);
/// <summary>
/// Deletes a <see cref="HitObject"/>.

View File

@ -33,7 +33,15 @@ namespace osu.Game.Screens.Edit
/// </summary>
public event Action<HitObject> StartTimeChanged;
public BindableList<HitObject> SelectedHitObjects { get; } = new BindableList<HitObject>();
/// <summary>
/// All currently selected <see cref="HitObject"/>s.
/// </summary>
public readonly BindableList<HitObject> SelectedHitObjects = new BindableList<HitObject>();
/// <summary>
/// The current placement. Null if there's no active placement.
/// </summary>
public readonly Bindable<HitObject> PlacementObject = new Bindable<HitObject>();
public readonly IBeatmap PlayableBeatmap;

View File

@ -53,9 +53,10 @@ namespace osu.Game.Tests.Visual
{
}
public void EndPlacement(HitObject hitObject)
public void EndPlacement(HitObject hitObject, bool commit)
{
AddHitObject(CreateHitObject(hitObject));
if (commit)
AddHitObject(CreateHitObject(hitObject));
Remove(currentBlueprint);
Add(currentBlueprint = CreateBlueprint());