mirror of
https://github.com/ppy/osu.git
synced 2024-11-06 09:47:52 +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>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
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;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using System.Collections.Generic;
|
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 EditRulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new ManiaEditRulesetContainer(ruleset, beatmap);
|
||||||
|
|
||||||
protected override IReadOnlyList<ICompositionTool> CompositionTools => new ICompositionTool[]
|
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => Array.Empty<HitObjectCompositionTool>();
|
||||||
{
|
|
||||||
new HitObjectCompositionTool<Note>("Note"),
|
|
||||||
new HitObjectCompositionTool<HoldNote>("Hold"),
|
|
||||||
};
|
|
||||||
|
|
||||||
public override SelectionMask CreateMaskFor(DrawableHitObject hitObject)
|
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
|
public class HitCircleMask : CompositeDrawable
|
||||||
{
|
{
|
||||||
|
private readonly HitCircle hitCircle;
|
||||||
|
|
||||||
public HitCircleMask(HitCircle hitCircle)
|
public HitCircleMask(HitCircle hitCircle)
|
||||||
{
|
{
|
||||||
|
this.hitCircle = hitCircle;
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
Size = new Vector2((float)OsuHitObject.OBJECT_RADIUS * 2);
|
Size = new Vector2((float)OsuHitObject.OBJECT_RADIUS * 2);
|
||||||
Scale = new Vector2(hitCircle.Scale);
|
|
||||||
|
|
||||||
CornerRadius = Size.X / 2;
|
CornerRadius = Size.X / 2;
|
||||||
|
|
||||||
@ -31,5 +33,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Masks
|
|||||||
{
|
{
|
||||||
Colour = colours.Yellow;
|
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 System.Collections.Generic;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
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;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Edit.Masks;
|
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.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Game.Rulesets.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 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 HitCircleCompositionTool(),
|
||||||
new HitObjectCompositionTool<Slider>(),
|
|
||||||
new HitObjectCompositionTool<Spinner>()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override ScalableContainer CreateLayerContainer() => new ScalableContainer(OsuPlayfield.BASE_SIZE.X) { RelativeSizeAxes = Axes.Both };
|
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;
|
public IEnumerable<DrawableHitObject> HitObjects => rulesetContainer.Playfield.AllHitObjects;
|
||||||
|
|
||||||
protected ICompositionTool CurrentTool { get; private set; }
|
|
||||||
protected IRulesetConfigManager Config { get; private set; }
|
protected IRulesetConfigManager Config { get; private set; }
|
||||||
|
|
||||||
private readonly List<Container> layerContainers = new List<Container>();
|
private readonly List<Container> layerContainers = new List<Container>();
|
||||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
|
private Container placementContainer;
|
||||||
private EditRulesetContainer rulesetContainer;
|
private EditRulesetContainer rulesetContainer;
|
||||||
|
|
||||||
protected HitObjectComposer(Ruleset ruleset)
|
protected HitObjectComposer(Ruleset ruleset)
|
||||||
@ -64,7 +64,11 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
};
|
};
|
||||||
|
|
||||||
var layerAboveRuleset = CreateLayerContainer();
|
var layerAboveRuleset = CreateLayerContainer();
|
||||||
layerAboveRuleset.Child = new HitObjectMaskLayer();
|
layerAboveRuleset.Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new HitObjectMaskLayer(),
|
||||||
|
placementContainer = new Container { RelativeSizeAxes = Axes.Both }
|
||||||
|
};
|
||||||
|
|
||||||
layerContainers.Add(layerBelowRuleset);
|
layerContainers.Add(layerBelowRuleset);
|
||||||
layerContainers.Add(layerAboveRuleset);
|
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 EditRulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap);
|
||||||
|
|
||||||
protected abstract IReadOnlyList<ICompositionTool> CompositionTools { get; }
|
protected abstract IReadOnlyList<HitObjectCompositionTool> CompositionTools { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a <see cref="SelectionMask"/> for a specific <see cref="DrawableHitObject"/>.
|
/// 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>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Game.Rulesets.Objects;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Tools
|
namespace osu.Game.Rulesets.Edit.Tools
|
||||||
{
|
{
|
||||||
public class HitObjectCompositionTool<T> : ICompositionTool
|
public abstract class HitObjectCompositionTool
|
||||||
where T : HitObject
|
|
||||||
{
|
{
|
||||||
public string Name { get; }
|
public readonly string Name;
|
||||||
|
|
||||||
public HitObjectCompositionTool()
|
protected HitObjectCompositionTool(string name)
|
||||||
: this(typeof(T).Name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public HitObjectCompositionTool(string name)
|
|
||||||
{
|
{
|
||||||
Name = 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