mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 23:24:04 +09:00
Merge remote-tracking branch 'origin/master' into editor-mask-placement
# Conflicts: # osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs # osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs # osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs # osu.Game/Rulesets/UI/RulesetContainer.cs
This commit is contained in:
@ -14,6 +14,11 @@ namespace osu.Game.Rulesets.UI
|
||||
public IEnumerable<DrawableHitObject> Objects => InternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime);
|
||||
public IEnumerable<DrawableHitObject> AliveObjects => AliveInternalChildren.Cast<DrawableHitObject>().OrderBy(h => h.HitObject.StartTime);
|
||||
|
||||
public HitObjectContainer()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject);
|
||||
public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject);
|
||||
|
||||
|
@ -9,17 +9,26 @@ using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
public abstract class Playfield : ScalableContainer
|
||||
public abstract class Playfield : CompositeDrawable
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="DrawableHitObject"/> contained in this Playfield.
|
||||
/// </summary>
|
||||
public HitObjectContainer HitObjectContainer { get; private set; }
|
||||
public HitObjectContainer HitObjectContainer => hitObjectContainerLazy.Value;
|
||||
|
||||
private readonly Lazy<HitObjectContainer> hitObjectContainerLazy;
|
||||
|
||||
/// <summary>
|
||||
/// A function that converts gamefield coordinates to screen space.
|
||||
/// </summary>
|
||||
public Func<Vector2, Vector2> GamefieldToScreenSpace => HitObjectContainer.ToScreenSpace;
|
||||
|
||||
/// <summary>
|
||||
/// All the <see cref="DrawableHitObject"/>s contained in this <see cref="Playfield"/> and all <see cref="NestedPlayfields"/>.
|
||||
@ -39,18 +48,13 @@ namespace osu.Game.Rulesets.UI
|
||||
public readonly BindableBool DisplayJudgements = new BindableBool(true);
|
||||
|
||||
/// <summary>
|
||||
/// A container for keeping track of DrawableHitObjects.
|
||||
/// Creates a new <see cref="Playfield"/>.
|
||||
/// </summary>
|
||||
/// <param name="customWidth">The width to scale the internal coordinate space to.
|
||||
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
|
||||
/// </param>
|
||||
/// <param name="customHeight">The height to scale the internal coordinate space to.
|
||||
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
|
||||
/// </param>
|
||||
protected Playfield(float? customWidth = null, float? customHeight = null)
|
||||
: base(customWidth, customHeight)
|
||||
protected Playfield()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
hitObjectContainerLazy = new Lazy<HitObjectContainer>(CreateHitObjectContainer);
|
||||
}
|
||||
|
||||
private WorkingBeatmap beatmap;
|
||||
@ -59,11 +63,6 @@ namespace osu.Game.Rulesets.UI
|
||||
private void load(IBindableBeatmap beatmap)
|
||||
{
|
||||
this.beatmap = beatmap.Value;
|
||||
|
||||
HitObjectContainer = CreateHitObjectContainer();
|
||||
HitObjectContainer.RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Add(HitObjectContainer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -94,10 +93,14 @@ namespace osu.Game.Rulesets.UI
|
||||
nestedPlayfields.Value.Add(otherPlayfield);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the container that will be used to contain the <see cref="DrawableHitObject"/>s.
|
||||
/// </summary>
|
||||
protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer();
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
// in the case a consumer forgets to add the HitObjectContainer, we will add it here.
|
||||
if (HitObjectContainer.Parent == null)
|
||||
AddInternal(HitObjectContainer);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
@ -108,5 +111,10 @@ namespace osu.Game.Rulesets.UI
|
||||
if (mod is IUpdatableByPlayfield updatable)
|
||||
updatable.Update(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the container that will be used to contain the <see cref="DrawableHitObject"/>s.
|
||||
/// </summary>
|
||||
protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer();
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets.Configuration;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
@ -316,25 +315,6 @@ namespace osu.Game.Rulesets.UI
|
||||
Playfield.Add(drawableObject);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Playfield.Size = GetAspectAdjustedSize() * PlayfieldArea;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the size of the <see cref="Playfield"/> in relative coordinate space after aspect adjustments.
|
||||
/// </summary>
|
||||
/// <returns>The aspect-adjusted size.</returns>
|
||||
protected virtual Vector2 GetAspectAdjustedSize() => Vector2.One;
|
||||
|
||||
/// <summary>
|
||||
/// The area of this <see cref="RulesetContainer"/> that is available for the <see cref="Playfield"/> to use.
|
||||
/// Must be specified in relative coordinate space to this <see cref="RulesetContainer"/>.
|
||||
/// This affects the final size of the <see cref="Playfield"/> but does not affect the <see cref="Playfield"/>'s scale.
|
||||
/// </summary>
|
||||
protected virtual Vector2 PlayfieldArea => new Vector2(0.75f); // A sane default
|
||||
|
||||
/// <summary>
|
||||
/// Creates a DrawableHitObject from a HitObject.
|
||||
|
@ -73,12 +73,10 @@ namespace osu.Game.Rulesets.UI
|
||||
#region IHasReplayHandler
|
||||
|
||||
private ReplayInputHandler replayInputHandler;
|
||||
|
||||
public ReplayInputHandler ReplayInputHandler
|
||||
{
|
||||
get
|
||||
{
|
||||
return replayInputHandler;
|
||||
}
|
||||
get => replayInputHandler;
|
||||
set
|
||||
{
|
||||
if (replayInputHandler != null) RemoveHandler(replayInputHandler);
|
||||
@ -208,16 +206,20 @@ namespace osu.Game.Rulesets.UI
|
||||
mouseDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
protected override bool Handle(UIEvent e)
|
||||
{
|
||||
if (mouseDisabled.Value && (e.Button == MouseButton.Left || e.Button == MouseButton.Right)) return false;
|
||||
return base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override bool OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
if (!CurrentState.Mouse.IsPressed(e.Button)) return false;
|
||||
return base.OnMouseUp(e);
|
||||
switch (e)
|
||||
{
|
||||
case MouseDownEvent mouseDown when mouseDown.Button == MouseButton.Left || mouseDown.Button == MouseButton.Right:
|
||||
if (mouseDisabled.Value)
|
||||
return false;
|
||||
break;
|
||||
case MouseUpEvent mouseUp:
|
||||
if (!CurrentState.Mouse.IsPressed(mouseUp.Button))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return base.Handle(e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -269,7 +271,7 @@ namespace osu.Game.Rulesets.UI
|
||||
}
|
||||
|
||||
public class RulesetInputManagerInputState<T> : InputState
|
||||
where T : struct
|
||||
where T : struct
|
||||
{
|
||||
public ReplayState<T> LastReplayState;
|
||||
|
||||
|
@ -1,99 +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
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="Container"/> which can have its internal coordinate system scaled to a specific size.
|
||||
/// </summary>
|
||||
public class ScalableContainer : Container
|
||||
{
|
||||
/// <summary>
|
||||
/// A function that converts coordinates from gamefield to screen space.
|
||||
/// </summary>
|
||||
public Func<Vector2, Vector2> GamefieldToScreenSpace => scaledContent.GamefieldToScreenSpace;
|
||||
|
||||
/// <summary>
|
||||
/// The scaled content.
|
||||
/// </summary>
|
||||
private readonly ScaledContainer scaledContent;
|
||||
protected override Container<Drawable> Content => scaledContent;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Container"/> which can have its internal coordinate system scaled to a specific size.
|
||||
/// </summary>
|
||||
/// <param name="customWidth">The width to scale the internal coordinate space to.
|
||||
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
|
||||
/// </param>
|
||||
/// <param name="customHeight">The height to scale the internal coordinate space to.
|
||||
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
|
||||
/// </param>
|
||||
public ScalableContainer(float? customWidth = null, float? customHeight = null)
|
||||
{
|
||||
AddInternal(scaledContent = new ScaledContainer
|
||||
{
|
||||
CustomWidth = customWidth,
|
||||
CustomHeight = customHeight,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
});
|
||||
}
|
||||
|
||||
private class ScaledContainer : Container
|
||||
{
|
||||
/// <summary>
|
||||
/// A function that converts coordinates from gamefield to screen space.
|
||||
/// </summary>
|
||||
public Func<Vector2, Vector2> GamefieldToScreenSpace => content.ToScreenSpace;
|
||||
|
||||
/// <summary>
|
||||
/// The value to scale the width of the content to match.
|
||||
/// If null, <see cref="CustomHeight"/> is used.
|
||||
/// </summary>
|
||||
public float? CustomWidth;
|
||||
|
||||
/// <summary>
|
||||
/// The value to scale the height of the content to match.
|
||||
/// if null, <see cref="CustomWidth"/> is used.
|
||||
/// </summary>
|
||||
public float? CustomHeight;
|
||||
|
||||
private readonly Container content;
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public ScaledContainer()
|
||||
{
|
||||
AddInternal(content = new Container { RelativeSizeAxes = Axes.Both });
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
content.Scale = sizeScale;
|
||||
content.Size = Vector2.Divide(Vector2.One, sizeScale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The scale that is required for the size of the content to match <see cref="CustomWidth"/> and <see cref="CustomHeight"/>.
|
||||
/// </summary>
|
||||
private Vector2 sizeScale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CustomWidth.HasValue && CustomHeight.HasValue)
|
||||
return Vector2.Divide(DrawSize, new Vector2(CustomWidth.Value, CustomHeight.Value));
|
||||
if (CustomWidth.HasValue)
|
||||
return new Vector2(DrawSize.X / CustomWidth.Value);
|
||||
if (CustomHeight.HasValue)
|
||||
return new Vector2(DrawSize.Y / CustomHeight.Value);
|
||||
return Vector2.One;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,19 +6,19 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
public enum ScrollingDirection
|
||||
{
|
||||
/// <summary>
|
||||
/// Hitobjects will scroll vertically from the bottom of the hitobject container.
|
||||
/// Hit objects will scroll vertically from the bottom of the hitobject container.
|
||||
/// </summary>
|
||||
Up,
|
||||
/// <summary>
|
||||
/// Hitobjects will scroll vertically from the top of the hitobject container.
|
||||
/// Hit objects will scroll vertically from the top of the hitobject container.
|
||||
/// </summary>
|
||||
Down,
|
||||
/// <summary>
|
||||
/// Hitobjects will scroll horizontally from the right of the hitobject container.
|
||||
/// Hit objects will scroll horizontally from the right of the hitobject container.
|
||||
/// </summary>
|
||||
Left,
|
||||
/// <summary>
|
||||
/// Hitobjects will scroll horizontally from the left of the hitobject container.
|
||||
/// Hit objects will scroll horizontally from the left of the hitobject container.
|
||||
/// </summary>
|
||||
Right
|
||||
}
|
||||
|
@ -65,20 +65,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
|
||||
protected virtual SpeedChangeVisualisationMethod VisualisationMethod => SpeedChangeVisualisationMethod.Sequential;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ScrollingPlayfield"/>.
|
||||
/// </summary>
|
||||
/// <param name="customWidth">The width to scale the internal coordinate space to.
|
||||
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
|
||||
/// </param>
|
||||
/// <param name="customHeight">The height to scale the internal coordinate space to.
|
||||
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
|
||||
/// </param>
|
||||
protected ScrollingPlayfield(float? customWidth = null, float? customHeight = null)
|
||||
: base(customWidth, customHeight)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
|
@ -60,6 +60,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
|
||||
return new MultiplierControlPoint(c.Time)
|
||||
{
|
||||
Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier,
|
||||
TimingPoint = lastTimingPoint,
|
||||
DifficultyPoint = lastDifficultyPoint
|
||||
};
|
||||
@ -78,7 +79,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
|
||||
// If we have no control points, add a default one
|
||||
if (DefaultControlPoints.Count == 0)
|
||||
DefaultControlPoints.Add(new MultiplierControlPoint());
|
||||
DefaultControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier });
|
||||
|
||||
DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield));
|
||||
}
|
||||
@ -88,22 +89,5 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
playfield.HitObjects.AddControlPoint(controlPoint);
|
||||
playfield.NestedPlayfields?.OfType<ScrollingPlayfield>().ForEach(p => applySpeedAdjustment(controlPoint, p));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a <see cref="MultiplierControlPoint"/> with the default timing change/difficulty change from the beatmap at a time.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to create the control point at.</param>
|
||||
/// <returns>The default <see cref="MultiplierControlPoint"/> at <paramref name="time"/>.</returns>
|
||||
public MultiplierControlPoint CreateControlPointAt(double time)
|
||||
{
|
||||
if (DefaultControlPoints.Count == 0)
|
||||
return new MultiplierControlPoint(time);
|
||||
|
||||
int index = DefaultControlPoints.BinarySearch(new MultiplierControlPoint(time));
|
||||
if (index < 0)
|
||||
return new MultiplierControlPoint(time);
|
||||
|
||||
return new MultiplierControlPoint(time, DefaultControlPoints[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user