mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 06:57:39 +08:00
Re-implement composition tools + implement placement masks
This commit is contained in:
parent
540a010fbb
commit
3420e0c7eb
@ -1,10 +1,10 @@
|
||||
// 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;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using System.Collections.Generic;
|
||||
@ -33,11 +33,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
|
||||
protected override EditRulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new ManiaEditRulesetContainer(ruleset, beatmap);
|
||||
|
||||
protected override IReadOnlyList<ICompositionTool> CompositionTools => new ICompositionTool[]
|
||||
{
|
||||
new HitObjectCompositionTool<Note>("Note"),
|
||||
new HitObjectCompositionTool<HoldNote>("Hold"),
|
||||
};
|
||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => Array.Empty<HitObjectCompositionTool>();
|
||||
|
||||
public override SelectionMask CreateMaskFor(DrawableHitObject hitObject)
|
||||
{
|
||||
|
20
osu.Game.Rulesets.Osu/Edit/HitCircleCompositionTool.cs
Normal file
20
osu.Game.Rulesets.Osu/Edit/HitCircleCompositionTool.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.Osu.Edit.Masks;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public class HitCircleCompositionTool : HitObjectCompositionTool
|
||||
{
|
||||
public HitCircleCompositionTool()
|
||||
: base(nameof(HitCircle))
|
||||
{
|
||||
}
|
||||
|
||||
public override PlacementMask CreatePlacementMask() => new HitCirclePlacementMask();
|
||||
}
|
||||
}
|
@ -13,13 +13,15 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks
|
||||
{
|
||||
public class HitCircleMask : CompositeDrawable
|
||||
{
|
||||
private readonly HitCircle hitCircle;
|
||||
|
||||
public HitCircleMask(HitCircle hitCircle)
|
||||
{
|
||||
this.hitCircle = hitCircle;
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Size = new Vector2((float)OsuHitObject.OBJECT_RADIUS * 2);
|
||||
Scale = new Vector2(hitCircle.Scale);
|
||||
|
||||
CornerRadius = Size.X / 2;
|
||||
|
||||
@ -31,5 +33,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks
|
||||
{
|
||||
Colour = colours.Yellow;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Scale = new Vector2(hitCircle.Scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
osu.Game.Rulesets.Osu/Edit/Masks/HitCirclePlacementMask.cs
Normal file
36
osu.Game.Rulesets.Osu/Edit/Masks/HitCirclePlacementMask.cs
Normal file
@ -0,0 +1,36 @@
|
||||
// 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.Framework.Input.Events;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Edit.Masks
|
||||
{
|
||||
public class HitCirclePlacementMask : PlacementMask
|
||||
{
|
||||
public new HitCircle HitObject => (HitCircle)base.HitObject;
|
||||
|
||||
public HitCirclePlacementMask()
|
||||
: base(new HitCircle())
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
InternalChild = new HitCircleMask(HitObject);
|
||||
}
|
||||
|
||||
protected override bool OnClick(ClickEvent e)
|
||||
{
|
||||
Finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
HitObject.Position = e.MousePosition;
|
||||
return base.OnMouseMove(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,13 +3,11 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Edit.Tools;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Edit.Masks;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Rulesets.UI;
|
||||
@ -25,11 +23,9 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
|
||||
protected override EditRulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new OsuEditRulesetContainer(ruleset, beatmap);
|
||||
|
||||
protected override IReadOnlyList<ICompositionTool> CompositionTools => new ICompositionTool[]
|
||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new[]
|
||||
{
|
||||
new HitObjectCompositionTool<HitCircle>(),
|
||||
new HitObjectCompositionTool<Slider>(),
|
||||
new HitObjectCompositionTool<Spinner>()
|
||||
new HitCircleCompositionTool(),
|
||||
};
|
||||
|
||||
protected override ScalableContainer CreateLayerContainer() => new ScalableContainer(OsuPlayfield.BASE_SIZE.X) { RelativeSizeAxes = Axes.Both };
|
||||
|
@ -26,12 +26,12 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
public IEnumerable<DrawableHitObject> HitObjects => rulesetContainer.Playfield.AllHitObjects;
|
||||
|
||||
protected ICompositionTool CurrentTool { get; private set; }
|
||||
protected IRulesetConfigManager Config { get; private set; }
|
||||
|
||||
private readonly List<Container> layerContainers = new List<Container>();
|
||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
|
||||
private Container placementContainer;
|
||||
private EditRulesetContainer rulesetContainer;
|
||||
|
||||
protected HitObjectComposer(Ruleset ruleset)
|
||||
@ -64,7 +64,11 @@ namespace osu.Game.Rulesets.Edit
|
||||
};
|
||||
|
||||
var layerAboveRuleset = CreateLayerContainer();
|
||||
layerAboveRuleset.Child = new HitObjectMaskLayer();
|
||||
layerAboveRuleset.Children = new Drawable[]
|
||||
{
|
||||
new HitObjectMaskLayer(),
|
||||
placementContainer = new Container { RelativeSizeAxes = Axes.Both }
|
||||
};
|
||||
|
||||
layerContainers.Add(layerBelowRuleset);
|
||||
layerContainers.Add(layerAboveRuleset);
|
||||
@ -144,11 +148,28 @@ namespace osu.Game.Rulesets.Edit
|
||||
});
|
||||
}
|
||||
|
||||
private void setCompositionTool(ICompositionTool tool) => CurrentTool = tool;
|
||||
private void setCompositionTool(HitObjectCompositionTool tool)
|
||||
{
|
||||
placementContainer.Clear(true);
|
||||
|
||||
if (tool != null)
|
||||
{
|
||||
var mask = tool.CreatePlacementMask();
|
||||
mask.PlacementFinished += h =>
|
||||
{
|
||||
rulesetContainer.AddHitObject(h);
|
||||
|
||||
// Re-construct the mask
|
||||
setCompositionTool(tool);
|
||||
};
|
||||
|
||||
placementContainer.Child = mask;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract EditRulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap);
|
||||
|
||||
protected abstract IReadOnlyList<ICompositionTool> CompositionTools { get; }
|
||||
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="SelectionMask"/> for a specific <see cref="DrawableHitObject"/>.
|
||||
|
71
osu.Game/Rulesets/Edit/PlacementMask.cs
Normal file
71
osu.Game/Rulesets/Edit/PlacementMask.cs
Normal file
@ -0,0 +1,71 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit
|
||||
{
|
||||
public class PlacementMask : CompositeDrawable, IRequireHighFrequencyMousePosition
|
||||
{
|
||||
/// <summary>
|
||||
/// Invoked when the placement of <see cref="HitObject"/> has finished.
|
||||
/// </summary>
|
||||
public event Action<HitObject> PlacementFinished;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="HitObject"/> that is being placed.
|
||||
/// </summary>
|
||||
protected readonly HitObject HitObject;
|
||||
|
||||
public PlacementMask(HitObject hitObject)
|
||||
{
|
||||
HitObject = hitObject;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindableBeatmap workingBeatmap)
|
||||
{
|
||||
HitObject.ApplyDefaults(workingBeatmap.Value.Beatmap.ControlPointInfo, workingBeatmap.Value.Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finishes the placement of <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
public void Finish() => PlacementFinished?.Invoke(HitObject);
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Parent?.ReceivePositionalInputAt(screenSpacePos) ?? false;
|
||||
|
||||
protected override bool Handle(UIEvent e)
|
||||
{
|
||||
base.Handle(e);
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case MouseEvent _:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
Position = e.MousePosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
PlacementFinished = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +1,17 @@
|
||||
// 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.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Tools
|
||||
{
|
||||
public class HitObjectCompositionTool<T> : ICompositionTool
|
||||
where T : HitObject
|
||||
public abstract class HitObjectCompositionTool
|
||||
{
|
||||
public string Name { get; }
|
||||
public readonly string Name;
|
||||
|
||||
public HitObjectCompositionTool()
|
||||
: this(typeof(T).Name)
|
||||
{
|
||||
}
|
||||
|
||||
public HitObjectCompositionTool(string name)
|
||||
protected HitObjectCompositionTool(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public abstract PlacementMask CreatePlacementMask();
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Tools
|
||||
{
|
||||
public interface ICompositionTool
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user