mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 20:13:22 +08:00
Merge remote-tracking branch 'upstream/master' into dropdown-updates
This commit is contained in:
commit
30547ac064
@ -5,7 +5,6 @@ using System;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
@ -21,14 +20,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
private readonly CatcherArea catcherArea;
|
private readonly CatcherArea catcherArea;
|
||||||
|
|
||||||
protected override bool UserScrollSpeedAdjustment => false;
|
|
||||||
|
|
||||||
protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Constant;
|
|
||||||
|
|
||||||
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
|
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
|
||||||
{
|
{
|
||||||
Direction.Value = ScrollingDirection.Down;
|
|
||||||
|
|
||||||
Container explodingFruitContainer;
|
Container explodingFruitContainer;
|
||||||
|
|
||||||
Anchor = Anchor.TopCentre;
|
Anchor = Anchor.TopCentre;
|
||||||
@ -55,8 +48,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
HitObjectContainer
|
HitObjectContainer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VisibleTimeRange.Value = BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);
|
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Input.Handlers;
|
using osu.Game.Input.Handlers;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
@ -18,9 +19,15 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
{
|
{
|
||||||
public class CatchRulesetContainer : ScrollingRulesetContainer<CatchPlayfield, CatchHitObject>
|
public class CatchRulesetContainer : ScrollingRulesetContainer<CatchPlayfield, CatchHitObject>
|
||||||
{
|
{
|
||||||
|
protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Constant;
|
||||||
|
|
||||||
|
protected override bool UserScrollSpeedAdjustment => false;
|
||||||
|
|
||||||
public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
: base(ruleset, beatmap)
|
: base(ruleset, beatmap)
|
||||||
{
|
{
|
||||||
|
Direction.Value = ScrollingDirection.Down;
|
||||||
|
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
|
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
|
||||||
|
@ -1,33 +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 osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A container which provides a <see cref="IScrollingInfo"/> to children.
|
|
||||||
/// </summary>
|
|
||||||
public class ScrollingTestContainer : Container
|
|
||||||
{
|
|
||||||
[Cached(Type = typeof(IScrollingInfo))]
|
|
||||||
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
|
||||||
|
|
||||||
public ScrollingTestContainer(ScrollingDirection direction)
|
|
||||||
{
|
|
||||||
scrollingInfo.Direction.Value = direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Flip() => scrollingInfo.Direction.Value = scrollingInfo.Direction.Value == ScrollingDirection.Up ? ScrollingDirection.Down : ScrollingDirection.Up;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TestScrollingInfo : IScrollingInfo
|
|
||||||
{
|
|
||||||
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
|
||||||
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,6 +14,7 @@ using osu.Game.Rulesets.Mania.Objects.Drawables;
|
|||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Mania.UI.Components;
|
using osu.Game.Rulesets.Mania.UI.Components;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
@ -93,7 +94,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
Height = 0.85f,
|
Height = 0.85f,
|
||||||
AccentColour = Color4.OrangeRed,
|
AccentColour = Color4.OrangeRed,
|
||||||
Action = { Value = action },
|
Action = { Value = action },
|
||||||
VisibleTimeRange = { Value = 2000 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
columns.Add(column);
|
columns.Add(column);
|
||||||
@ -104,6 +104,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
TimeRange = 2000,
|
||||||
Child = column
|
Child = column
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
// 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.Graphics.Containers;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
public class TestCaseHoldNoteSelectionBlueprint : SelectionBlueprintTestCase
|
||||||
|
{
|
||||||
|
private readonly DrawableHoldNote drawableObject;
|
||||||
|
|
||||||
|
protected override Container<Drawable> Content => content ?? base.Content;
|
||||||
|
private readonly Container content;
|
||||||
|
|
||||||
|
public TestCaseHoldNoteSelectionBlueprint()
|
||||||
|
{
|
||||||
|
var holdNote = new HoldNote { Column = 0, Duration = 1000 };
|
||||||
|
holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
|
base.Content.Child = content = new ScrollingTestContainer(ScrollingDirection.Down)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Width = 50,
|
||||||
|
Child = drawableObject = new DrawableHoldNote(holdNote)
|
||||||
|
{
|
||||||
|
Height = 300,
|
||||||
|
AccentColour = OsuColour.Gray(0.3f)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
foreach (var nested in drawableObject.NestedHitObjects)
|
||||||
|
{
|
||||||
|
double finalPosition = (nested.HitObject.StartTime - drawableObject.HitObject.StartTime) / drawableObject.HitObject.Duration;
|
||||||
|
nested.Y = (float)(-finalPosition * content.DrawHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SelectionBlueprint CreateBlueprint() => new HoldNoteSelectionBlueprint(drawableObject);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
// 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.Graphics.Containers;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
public class TestCaseNoteSelectionBlueprint : SelectionBlueprintTestCase
|
||||||
|
{
|
||||||
|
private readonly DrawableNote drawableObject;
|
||||||
|
|
||||||
|
protected override Container<Drawable> Content => content ?? base.Content;
|
||||||
|
private readonly Container content;
|
||||||
|
|
||||||
|
public TestCaseNoteSelectionBlueprint()
|
||||||
|
{
|
||||||
|
var note = new Note { Column = 0 };
|
||||||
|
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
|
|
||||||
|
base.Content.Child = content = new ScrollingTestContainer(ScrollingDirection.Down)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(50, 20),
|
||||||
|
Child = drawableObject = new DrawableNote(note)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SelectionBlueprint CreateBlueprint() => new NoteSelectionBlueprint(drawableObject);
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ using osu.Game.Rulesets.Mania.Objects;
|
|||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
@ -122,7 +123,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
{
|
{
|
||||||
var specialAction = ManiaAction.Special1;
|
var specialAction = ManiaAction.Special1;
|
||||||
|
|
||||||
var stage = new ManiaStage(0, new StageDefinition { Columns = 2 }, ref action, ref specialAction) { VisibleTimeRange = { Value = 2000 } };
|
var stage = new ManiaStage(0, new StageDefinition { Columns = 2 }, ref action, ref specialAction);
|
||||||
stages.Add(stage);
|
stages.Add(stage);
|
||||||
|
|
||||||
return new ScrollingTestContainer(direction)
|
return new ScrollingTestContainer(direction)
|
||||||
@ -131,6 +132,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Y,
|
RelativeSizeAxes = Axes.Y,
|
||||||
AutoSizeAxes = Axes.X,
|
AutoSizeAxes = Axes.X,
|
||||||
|
TimeRange = 2000,
|
||||||
Child = stage
|
Child = stage
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
// 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.Allocation;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints.Components
|
||||||
|
{
|
||||||
|
public class EditNotePiece : CompositeDrawable
|
||||||
|
{
|
||||||
|
public EditNotePiece()
|
||||||
|
{
|
||||||
|
Height = NotePiece.NOTE_HEIGHT;
|
||||||
|
|
||||||
|
CornerRadius = 5;
|
||||||
|
Masking = true;
|
||||||
|
|
||||||
|
InternalChild = new NotePiece();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
Colour = colours.Yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,10 +4,10 @@
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Primitives;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
@ -58,6 +58,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
Y -= HitObject.Tail.DrawHeight;
|
Y -= HitObject.Tail.DrawHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Quad SelectionQuad => ScreenSpaceDrawQuad;
|
||||||
|
|
||||||
private class HoldNoteNoteSelectionBlueprint : NoteSelectionBlueprint
|
private class HoldNoteNoteSelectionBlueprint : NoteSelectionBlueprint
|
||||||
{
|
{
|
||||||
public HoldNoteNoteSelectionBlueprint(DrawableNote note)
|
public HoldNoteNoteSelectionBlueprint(DrawableNote note)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// 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.Framework.Graphics;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -12,6 +13,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
public ManiaSelectionBlueprint(DrawableHitObject hitObject)
|
public ManiaSelectionBlueprint(DrawableHitObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
|
RelativeSizeAxes = Axes.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AdjustPosition(DragEvent dragEvent)
|
public override void AdjustPosition(DragEvent dragEvent)
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
// 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.Framework.Allocation;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||||
{
|
{
|
||||||
@ -13,18 +12,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
public NoteSelectionBlueprint(DrawableNote note)
|
public NoteSelectionBlueprint(DrawableNote note)
|
||||||
: base(note)
|
: base(note)
|
||||||
{
|
{
|
||||||
Scale = note.Scale;
|
AddInternal(new EditNotePiece { RelativeSizeAxes = Axes.X });
|
||||||
|
|
||||||
CornerRadius = 5;
|
|
||||||
Masking = true;
|
|
||||||
|
|
||||||
AddInternal(new NotePiece());
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
Colour = colours.Yellow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -6,11 +6,14 @@ using OpenTK;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
{
|
{
|
||||||
public class ManiaEditRulesetContainer : ManiaRulesetContainer
|
public class ManiaEditRulesetContainer : ManiaRulesetContainer
|
||||||
{
|
{
|
||||||
|
public new IScrollingInfo ScrollingInfo => base.ScrollingInfo;
|
||||||
|
|
||||||
public ManiaEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
public ManiaEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
: base(ruleset, beatmap)
|
: base(ruleset, beatmap)
|
||||||
{
|
{
|
||||||
|
@ -10,31 +10,32 @@ 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;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Rulesets.Mania.Configuration;
|
|
||||||
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
using osu.Game.Rulesets.Mania.Edit.Blueprints;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
{
|
{
|
||||||
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>
|
public class ManiaHitObjectComposer : HitObjectComposer<ManiaHitObject>
|
||||||
{
|
{
|
||||||
protected new ManiaConfigManager Config => (ManiaConfigManager)base.Config;
|
|
||||||
|
|
||||||
public ManiaHitObjectComposer(Ruleset ruleset)
|
public ManiaHitObjectComposer(Ruleset ruleset)
|
||||||
: base(ruleset)
|
: base(ruleset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DependencyContainer dependencies;
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
|
||||||
dependencies.CacheAs<IScrollingInfo>(new ManiaScrollingInfo(Config));
|
|
||||||
return dependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override RulesetContainer<ManiaHitObject> CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
protected override RulesetContainer<ManiaHitObject> CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
=> new ManiaEditRulesetContainer(ruleset, beatmap);
|
{
|
||||||
|
var rulesetContainer = new ManiaEditRulesetContainer(ruleset, beatmap);
|
||||||
|
|
||||||
|
// This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it
|
||||||
|
dependencies.CacheAs(rulesetContainer.ScrollingInfo);
|
||||||
|
|
||||||
|
return rulesetContainer;
|
||||||
|
}
|
||||||
|
|
||||||
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => Array.Empty<HitObjectCompositionTool>();
|
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => Array.Empty<HitObjectCompositionTool>();
|
||||||
|
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
// 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.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Edit.Masks
|
||||||
|
{
|
||||||
|
public abstract class ManiaSelectionBlueprint : SelectionBlueprint
|
||||||
|
{
|
||||||
|
protected ManiaSelectionBlueprint(DrawableHitObject hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ using JetBrains.Annotations;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
// 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.Linq;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
@ -16,7 +16,7 @@ using osu.Game.Rulesets.UI.Scrolling;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
public class Column : ManiaScrollingPlayfield, IKeyBindingHandler<ManiaAction>, IHasAccentColour
|
public class Column : ScrollingPlayfield, IKeyBindingHandler<ManiaAction>, IHasAccentColour
|
||||||
{
|
{
|
||||||
private const float column_width = 45;
|
private const float column_width = 45;
|
||||||
private const float special_column_width = 70;
|
private const float special_column_width = 70;
|
||||||
@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
hitObject.AccentColour = AccentColour;
|
hitObject.AccentColour = AccentColour;
|
||||||
hitObject.OnNewResult += OnNewResult;
|
hitObject.OnNewResult += OnNewResult;
|
||||||
|
|
||||||
HitObjects.Add(hitObject);
|
HitObjectContainer.Add(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
|
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
|
||||||
@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
explosionContainer.Add(new HitExplosion(judgedObject)
|
explosionContainer.Add(new HitExplosion(judgedObject)
|
||||||
{
|
{
|
||||||
Anchor = Direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre
|
Anchor = Direction.Value == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,10 +154,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var nextObject =
|
var nextObject =
|
||||||
HitObjects.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
|
HitObjectContainer.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
|
||||||
// fallback to non-alive objects to find next off-screen object
|
// fallback to non-alive objects to find next off-screen object
|
||||||
HitObjects.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
|
HitObjectContainer.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ??
|
||||||
HitObjects.Objects.LastOrDefault();
|
HitObjectContainer.Objects.LastOrDefault();
|
||||||
|
|
||||||
nextObject?.PlaySamples();
|
nextObject?.PlaySamples();
|
||||||
|
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
// 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.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Configuration;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
public class ManiaPlayfield : ManiaScrollingPlayfield
|
public class ManiaPlayfield : ScrollingPlayfield
|
||||||
{
|
{
|
||||||
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
||||||
|
|
||||||
@ -41,7 +40,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
for (int i = 0; i < stageDefinitions.Count; i++)
|
for (int i = 0; i < stageDefinitions.Count; i++)
|
||||||
{
|
{
|
||||||
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
|
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
|
||||||
newStage.VisibleTimeRange.BindTo(VisibleTimeRange);
|
|
||||||
|
|
||||||
playfieldGrid.Content[0][i] = newStage;
|
playfieldGrid.Content[0][i] = newStage;
|
||||||
|
|
||||||
@ -68,11 +66,5 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(ManiaConfigManager maniaConfig)
|
|
||||||
{
|
|
||||||
maniaConfig.BindWith(ManiaSetting.ScrollTime, VisibleTimeRange);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
@ -35,6 +36,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
protected new ManiaConfigManager Config => (ManiaConfigManager)base.Config;
|
protected new ManiaConfigManager Config => (ManiaConfigManager)base.Config;
|
||||||
|
|
||||||
|
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
|
||||||
|
|
||||||
public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
: base(ruleset, beatmap)
|
: base(ruleset, beatmap)
|
||||||
{
|
{
|
||||||
@ -70,18 +73,11 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
BarLines.ForEach(Playfield.Add);
|
BarLines.ForEach(Playfield.Add);
|
||||||
}
|
|
||||||
|
|
||||||
private DependencyContainer dependencies;
|
Config.BindWith(ManiaSetting.ScrollDirection, configDirection);
|
||||||
|
configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true);
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
Config.BindWith(ManiaSetting.ScrollTime, TimeRange);
|
||||||
{
|
|
||||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
|
||||||
|
|
||||||
if (dependencies.Get<ManiaScrollingInfo>() == null)
|
|
||||||
dependencies.CacheAs<IScrollingInfo>(new ManiaScrollingInfo(Config));
|
|
||||||
|
|
||||||
return dependencies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
|
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
|
||||||
|
@ -1,23 +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 osu.Framework.Configuration;
|
|
||||||
using osu.Game.Rulesets.Mania.Configuration;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
|
||||||
{
|
|
||||||
public class ManiaScrollingInfo : IScrollingInfo
|
|
||||||
{
|
|
||||||
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
|
|
||||||
|
|
||||||
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
|
||||||
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
|
||||||
|
|
||||||
public ManiaScrollingInfo(ManiaConfigManager config)
|
|
||||||
{
|
|
||||||
config.BindWith(ManiaSetting.ScrollDirection, configDirection);
|
|
||||||
configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +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 osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Configuration;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
|
||||||
{
|
|
||||||
public abstract class ManiaScrollingPlayfield : ScrollingPlayfield
|
|
||||||
{
|
|
||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(IScrollingInfo scrollingInfo)
|
|
||||||
{
|
|
||||||
direction.BindTo(scrollingInfo.Direction);
|
|
||||||
direction.BindValueChanged(direction => Direction.Value = direction, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A collection of <see cref="Column"/>s.
|
/// A collection of <see cref="Column"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ManiaStage : ManiaScrollingPlayfield
|
public class ManiaStage : ScrollingPlayfield
|
||||||
{
|
{
|
||||||
public const float HIT_TARGET_POSITION = 50;
|
public const float HIT_TARGET_POSITION = 50;
|
||||||
|
|
||||||
@ -144,8 +144,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
public void AddColumn(Column c)
|
public void AddColumn(Column c)
|
||||||
{
|
{
|
||||||
c.VisibleTimeRange.BindTo(VisibleTimeRange);
|
|
||||||
|
|
||||||
topLevelContainer.Add(c.TopLevelContainer.CreateProxy());
|
topLevelContainer.Add(c.TopLevelContainer.CreateProxy());
|
||||||
columnFlow.Add(c);
|
columnFlow.Add(c);
|
||||||
AddNested(c);
|
AddNested(c);
|
||||||
|
@ -37,6 +37,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
|
|||||||
|
|
||||||
isPlacingEnd = true;
|
isPlacingEnd = true;
|
||||||
piece.FadeTo(1f, 150, Easing.OutQuint);
|
piece.FadeTo(1f, 150, Easing.OutQuint);
|
||||||
|
|
||||||
|
BeginPlacement();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -84,5 +84,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
judgementLayer.Add(explosion);
|
judgementLayer.Add(explosion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
@ -39,10 +38,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float left_area_size = 240;
|
private const float left_area_size = 240;
|
||||||
|
|
||||||
protected override bool UserScrollSpeedAdjustment => false;
|
|
||||||
|
|
||||||
protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping;
|
|
||||||
|
|
||||||
private readonly Container<HitExplosion> hitExplosionContainer;
|
private readonly Container<HitExplosion> hitExplosionContainer;
|
||||||
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
||||||
private readonly JudgementContainer<DrawableTaikoJudgement> judgementContainer;
|
private readonly JudgementContainer<DrawableTaikoJudgement> judgementContainer;
|
||||||
@ -59,8 +54,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
public TaikoPlayfield(ControlPointInfo controlPoints)
|
public TaikoPlayfield(ControlPointInfo controlPoints)
|
||||||
{
|
{
|
||||||
Direction.Value = ScrollingDirection.Left;
|
|
||||||
|
|
||||||
InternalChild = new PlayfieldAdjustmentContainer
|
InternalChild = new PlayfieldAdjustmentContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
@ -200,8 +193,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VisibleTimeRange.Value = 7000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -14,6 +14,7 @@ using osu.Game.Rulesets.UI;
|
|||||||
using osu.Game.Rulesets.Taiko.Replays;
|
using osu.Game.Rulesets.Taiko.Replays;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Input.Handlers;
|
using osu.Game.Input.Handlers;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
@ -21,9 +22,15 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
{
|
{
|
||||||
public class TaikoRulesetContainer : ScrollingRulesetContainer<TaikoPlayfield, TaikoHitObject>
|
public class TaikoRulesetContainer : ScrollingRulesetContainer<TaikoPlayfield, TaikoHitObject>
|
||||||
{
|
{
|
||||||
|
protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping;
|
||||||
|
|
||||||
|
protected override bool UserScrollSpeedAdjustment => false;
|
||||||
|
|
||||||
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
: base(ruleset, beatmap)
|
: base(ruleset, beatmap)
|
||||||
{
|
{
|
||||||
|
Direction.Value = ScrollingDirection.Left;
|
||||||
|
TimeRange.Value = 7000;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -13,25 +13,25 @@ using OpenTK.Input;
|
|||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
[Description("'Hold to Quit' UI element")]
|
[Description("'Hold to Quit' UI element")]
|
||||||
public class TestCaseQuitButton : ManualInputManagerTestCase
|
public class TestCaseHoldForMenuButton : ManualInputManagerTestCase
|
||||||
{
|
{
|
||||||
private bool exitAction;
|
private bool exitAction;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
QuitButton quitButton;
|
HoldForMenuButton holdForMenuButton;
|
||||||
|
|
||||||
Add(quitButton = new QuitButton
|
Add(holdForMenuButton = new HoldForMenuButton
|
||||||
{
|
{
|
||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
Action = () => exitAction = true
|
Action = () => exitAction = true
|
||||||
});
|
});
|
||||||
|
|
||||||
var text = quitButton.Children.OfType<SpriteText>().First();
|
var text = holdForMenuButton.Children.OfType<SpriteText>().First();
|
||||||
|
|
||||||
AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(quitButton));
|
AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(holdForMenuButton));
|
||||||
AddUntilStep(() => text.IsPresent && !exitAction, "Text visible");
|
AddUntilStep(() => text.IsPresent && !exitAction, "Text visible");
|
||||||
AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One));
|
AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One));
|
||||||
AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible");
|
AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible");
|
||||||
@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddStep("Trigger exit action", () =>
|
AddStep("Trigger exit action", () =>
|
||||||
{
|
{
|
||||||
exitAction = false;
|
exitAction = false;
|
||||||
InputManager.MoveMouseTo(quitButton);
|
InputManager.MoveMouseTo(holdForMenuButton);
|
||||||
InputManager.PressButton(MouseButton.Left);
|
InputManager.PressButton(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddAssert("action not triggered", () => !exitAction);
|
AddAssert("action not triggered", () => !exitAction);
|
||||||
|
|
||||||
AddStep("Trigger exit action", () => InputManager.PressButton(MouseButton.Left));
|
AddStep("Trigger exit action", () => InputManager.PressButton(MouseButton.Left));
|
||||||
AddUntilStep(() => exitAction, $"{nameof(quitButton.Action)} was triggered");
|
AddUntilStep(() => exitAction, $"{nameof(holdForMenuButton.Action)} was triggered");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ using OpenTK;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Timing;
|
using osu.Game.Rulesets.Timing;
|
||||||
@ -22,6 +23,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Playfield) };
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Playfield) };
|
||||||
|
|
||||||
|
private readonly ScrollingTestContainer[] scrollContainers = new ScrollingTestContainer[4];
|
||||||
private readonly TestPlayfield[] playfields = new TestPlayfield[4];
|
private readonly TestPlayfield[] playfields = new TestPlayfield[4];
|
||||||
|
|
||||||
public TestCaseScrollingHitObjects()
|
public TestCaseScrollingHitObjects()
|
||||||
@ -33,18 +35,38 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
playfields[0] = new TestPlayfield(ScrollingDirection.Up),
|
scrollContainers[0] = new ScrollingTestContainer(ScrollingDirection.Up)
|
||||||
playfields[1] = new TestPlayfield(ScrollingDirection.Down)
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = playfields[0] = new TestPlayfield()
|
||||||
|
},
|
||||||
|
scrollContainers[1] = new ScrollingTestContainer(ScrollingDirection.Up)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = playfields[1] = new TestPlayfield()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
playfields[2] = new TestPlayfield(ScrollingDirection.Left),
|
scrollContainers[2] = new ScrollingTestContainer(ScrollingDirection.Up)
|
||||||
playfields[3] = new TestPlayfield(ScrollingDirection.Right)
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = playfields[2] = new TestPlayfield()
|
||||||
|
},
|
||||||
|
scrollContainers[3] = new ScrollingTestContainer(ScrollingDirection.Up)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = playfields[3] = new TestPlayfield()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AddSliderStep("Time range", 100, 10000, 5000, v => playfields.ForEach(p => p.VisibleTimeRange.Value = v));
|
AddStep("Constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant));
|
||||||
|
AddStep("Overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping));
|
||||||
|
AddStep("Sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
||||||
|
|
||||||
|
AddSliderStep("Time range", 100, 10000, 5000, v => scrollContainers.ForEach(c => c.TimeRange = v));
|
||||||
AddStep("Add control point", () => addControlPoint(Time.Current + 5000));
|
AddStep("Add control point", () => addControlPoint(Time.Current + 5000));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +74,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
playfields.ForEach(p => p.HitObjects.AddControlPoint(new MultiplierControlPoint(0)));
|
scrollContainers.ForEach(c => c.ControlPoints.Add(new MultiplierControlPoint(0)));
|
||||||
|
|
||||||
for (int i = 0; i <= 5000; i += 1000)
|
for (int i = 0; i <= 5000; i += 1000)
|
||||||
addHitObject(Time.Current + i);
|
addHitObject(Time.Current + i);
|
||||||
@ -73,12 +95,15 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private void addControlPoint(double time)
|
private void addControlPoint(double time)
|
||||||
{
|
{
|
||||||
|
scrollContainers.ForEach(c =>
|
||||||
|
{
|
||||||
|
c.ControlPoints.Add(new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } });
|
||||||
|
c.ControlPoints.Add(new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } });
|
||||||
|
c.ControlPoints.Add(new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } });
|
||||||
|
});
|
||||||
|
|
||||||
playfields.ForEach(p =>
|
playfields.ForEach(p =>
|
||||||
{
|
{
|
||||||
p.HitObjects.AddControlPoint(new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } });
|
|
||||||
p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } });
|
|
||||||
p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } });
|
|
||||||
|
|
||||||
TestDrawableControlPoint createDrawablePoint(double t)
|
TestDrawableControlPoint createDrawablePoint(double t)
|
||||||
{
|
{
|
||||||
var obj = new TestDrawableControlPoint(p.Direction, t);
|
var obj = new TestDrawableControlPoint(p.Direction, t);
|
||||||
@ -111,15 +136,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setScrollAlgorithm(ScrollVisualisationMethod algorithm) => scrollContainers.ForEach(c => c.ScrollAlgorithm = algorithm);
|
||||||
|
|
||||||
private class TestPlayfield : ScrollingPlayfield
|
private class TestPlayfield : ScrollingPlayfield
|
||||||
{
|
{
|
||||||
public new ScrollingDirection Direction => base.Direction;
|
public new ScrollingDirection Direction => base.Direction.Value;
|
||||||
|
|
||||||
public TestPlayfield(ScrollingDirection direction)
|
public TestPlayfield()
|
||||||
{
|
{
|
||||||
base.Direction.Value = direction;
|
|
||||||
|
|
||||||
Padding = new MarginPadding(2);
|
Padding = new MarginPadding(2);
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -37,6 +38,8 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
|
|
||||||
private BlueprintContainer blueprintContainer;
|
private BlueprintContainer blueprintContainer;
|
||||||
|
|
||||||
|
private InputManager inputManager;
|
||||||
|
|
||||||
internal HitObjectComposer(Ruleset ruleset)
|
internal HitObjectComposer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
Ruleset = ruleset;
|
Ruleset = ruleset;
|
||||||
@ -114,6 +117,13 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
toolboxCollection.Items[0].Select();
|
toolboxCollection.Items[0].Select();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
inputManager = GetContainingInputManager();
|
||||||
|
}
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
@ -137,6 +147,11 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the user's cursor is currently in an area of the <see cref="HitObjectComposer"/> that is valid for placement.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool CursorInPlacementArea => rulesetContainer.Playfield.ReceivePositionalInputAt(inputManager.CurrentState.Mouse.Position);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmaps.Beatmap"/> and visualises it.
|
/// Adds a <see cref="HitObject"/> to the <see cref="Beatmaps.Beatmap"/> and visualises it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// 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.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -18,8 +20,18 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A blueprint which governs the creation of a new <see cref="HitObject"/> to actualisation.
|
/// A blueprint which governs the creation of a new <see cref="HitObject"/> to actualisation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PlacementBlueprint : CompositeDrawable, IRequireHighFrequencyMousePosition
|
public abstract class PlacementBlueprint : CompositeDrawable, IStateful<PlacementState>, IRequireHighFrequencyMousePosition
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when <see cref="State"/> has changed.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<PlacementState> StateChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the <see cref="HitObject"/> is currently being placed, but has not necessarily finished being placed.
|
||||||
|
/// </summary>
|
||||||
|
public bool PlacementBegun { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="HitObject"/> that is being placed.
|
/// The <see cref="HitObject"/> that is being placed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -37,6 +49,8 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
HitObject = hitObject;
|
HitObject = hitObject;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
Alpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -49,7 +63,25 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
ApplyDefaultsToHitObject();
|
ApplyDefaultsToHitObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool placementBegun;
|
private PlacementState state;
|
||||||
|
|
||||||
|
public PlacementState State
|
||||||
|
{
|
||||||
|
get => state;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (state == value)
|
||||||
|
return;
|
||||||
|
state = value;
|
||||||
|
|
||||||
|
if (state == PlacementState.Shown)
|
||||||
|
Show();
|
||||||
|
else
|
||||||
|
Hide();
|
||||||
|
|
||||||
|
StateChanged?.Invoke(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signals that the placement of <see cref="HitObject"/> has started.
|
/// Signals that the placement of <see cref="HitObject"/> has started.
|
||||||
@ -57,7 +89,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
protected void BeginPlacement()
|
protected void BeginPlacement()
|
||||||
{
|
{
|
||||||
placementHandler.BeginPlacement(HitObject);
|
placementHandler.BeginPlacement(HitObject);
|
||||||
placementBegun = true;
|
PlacementBegun = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -66,7 +98,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected void EndPlacement()
|
protected void EndPlacement()
|
||||||
{
|
{
|
||||||
if (!placementBegun)
|
if (!PlacementBegun)
|
||||||
BeginPlacement();
|
BeginPlacement();
|
||||||
placementHandler.EndPlacement(HitObject);
|
placementHandler.EndPlacement(HitObject);
|
||||||
}
|
}
|
||||||
@ -93,4 +125,10 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum PlacementState
|
||||||
|
{
|
||||||
|
Hidden,
|
||||||
|
Shown,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.UI.Scrolling
|
||||||
{
|
{
|
||||||
public interface IScrollingInfo
|
public interface IScrollingInfo
|
||||||
{
|
{
|
||||||
@ -13,5 +13,15 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
/// The direction <see cref="HitObject"/>s should scroll in.
|
/// The direction <see cref="HitObject"/>s should scroll in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IBindable<ScrollingDirection> Direction { get; }
|
IBindable<ScrollingDirection> Direction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
IBindable<double> TimeRange { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The algorithm which controls <see cref="HitObject"/> positions and sizes.
|
||||||
|
/// </summary>
|
||||||
|
IScrollAlgorithm Algorithm { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,59 +1,39 @@
|
|||||||
// 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.Framework.Allocation;
|
||||||
using osu.Framework.Caching;
|
using osu.Framework.Caching;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Lists;
|
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Timing;
|
|
||||||
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.UI.Scrolling
|
namespace osu.Game.Rulesets.UI.Scrolling
|
||||||
{
|
{
|
||||||
public class ScrollingHitObjectContainer : HitObjectContainer
|
public class ScrollingHitObjectContainer : HitObjectContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
private readonly IBindable<double> timeRange = new BindableDouble();
|
||||||
/// The duration required to scroll through one length of the <see cref="ScrollingHitObjectContainer"/> before any control point adjustments.
|
|
||||||
/// </summary>
|
|
||||||
public readonly BindableDouble TimeRange = new BindableDouble
|
|
||||||
{
|
|
||||||
MinValue = 0,
|
|
||||||
MaxValue = double.MaxValue
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
/// The control points that adjust the scrolling speed.
|
|
||||||
/// </summary>
|
|
||||||
protected readonly SortedList<MultiplierControlPoint> ControlPoints = new SortedList<MultiplierControlPoint>();
|
|
||||||
|
|
||||||
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
[Resolved]
|
||||||
|
private IScrollingInfo scrollingInfo { get; set; }
|
||||||
private readonly IScrollAlgorithm algorithm;
|
|
||||||
|
|
||||||
private Cached initialStateCache = new Cached();
|
private Cached initialStateCache = new Cached();
|
||||||
|
|
||||||
public ScrollingHitObjectContainer(ScrollVisualisationMethod visualisationMethod)
|
public ScrollingHitObjectContainer()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
}
|
||||||
|
|
||||||
TimeRange.ValueChanged += _ => initialStateCache.Invalidate();
|
[BackgroundDependencyLoader]
|
||||||
Direction.ValueChanged += _ => initialStateCache.Invalidate();
|
private void load()
|
||||||
|
{
|
||||||
|
direction.BindTo(scrollingInfo.Direction);
|
||||||
|
timeRange.BindTo(scrollingInfo.TimeRange);
|
||||||
|
|
||||||
switch (visualisationMethod)
|
direction.ValueChanged += _ => initialStateCache.Invalidate();
|
||||||
{
|
timeRange.ValueChanged += _ => initialStateCache.Invalidate();
|
||||||
case ScrollVisualisationMethod.Sequential:
|
|
||||||
algorithm = new SequentialScrollAlgorithm(ControlPoints);
|
|
||||||
break;
|
|
||||||
case ScrollVisualisationMethod.Overlapping:
|
|
||||||
algorithm = new OverlappingScrollAlgorithm(ControlPoints);
|
|
||||||
break;
|
|
||||||
case ScrollVisualisationMethod.Constant:
|
|
||||||
algorithm = new ConstantScrollAlgorithm();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Add(DrawableHitObject hitObject)
|
public override void Add(DrawableHitObject hitObject)
|
||||||
@ -70,20 +50,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddControlPoint(MultiplierControlPoint controlPoint)
|
|
||||||
{
|
|
||||||
ControlPoints.Add(controlPoint);
|
|
||||||
initialStateCache.Invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveControlPoint(MultiplierControlPoint controlPoint)
|
|
||||||
{
|
|
||||||
var result = ControlPoints.Remove(controlPoint);
|
|
||||||
if (result)
|
|
||||||
initialStateCache.Invalidate();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||||
{
|
{
|
||||||
if ((invalidation & (Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo)) > 0)
|
if ((invalidation & (Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo)) > 0)
|
||||||
@ -100,7 +66,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
if (!initialStateCache.IsValid)
|
if (!initialStateCache.IsValid)
|
||||||
{
|
{
|
||||||
switch (Direction.Value)
|
switch (direction.Value)
|
||||||
{
|
{
|
||||||
case ScrollingDirection.Up:
|
case ScrollingDirection.Up:
|
||||||
case ScrollingDirection.Down:
|
case ScrollingDirection.Down:
|
||||||
@ -111,7 +77,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
algorithm.Reset();
|
scrollingInfo.Algorithm.Reset();
|
||||||
|
|
||||||
foreach (var obj in Objects)
|
foreach (var obj in Objects)
|
||||||
computeInitialStateRecursive(obj);
|
computeInitialStateRecursive(obj);
|
||||||
@ -121,19 +87,19 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
private void computeInitialStateRecursive(DrawableHitObject hitObject)
|
private void computeInitialStateRecursive(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
hitObject.LifetimeStart = algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, TimeRange);
|
hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value);
|
||||||
|
|
||||||
if (hitObject.HitObject is IHasEndTime endTime)
|
if (hitObject.HitObject is IHasEndTime endTime)
|
||||||
{
|
{
|
||||||
switch (Direction.Value)
|
switch (direction.Value)
|
||||||
{
|
{
|
||||||
case ScrollingDirection.Up:
|
case ScrollingDirection.Up:
|
||||||
case ScrollingDirection.Down:
|
case ScrollingDirection.Down:
|
||||||
hitObject.Height = algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, TimeRange, scrollLength);
|
hitObject.Height = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, timeRange.Value, scrollLength);
|
||||||
break;
|
break;
|
||||||
case ScrollingDirection.Left:
|
case ScrollingDirection.Left:
|
||||||
case ScrollingDirection.Right:
|
case ScrollingDirection.Right:
|
||||||
hitObject.Width = algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, TimeRange, scrollLength);
|
hitObject.Width = scrollingInfo.Algorithm.GetLength(hitObject.HitObject.StartTime, endTime.EndTime, timeRange.Value, scrollLength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,19 +124,19 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
private void updatePosition(DrawableHitObject hitObject, double currentTime)
|
private void updatePosition(DrawableHitObject hitObject, double currentTime)
|
||||||
{
|
{
|
||||||
switch (Direction.Value)
|
switch (direction.Value)
|
||||||
{
|
{
|
||||||
case ScrollingDirection.Up:
|
case ScrollingDirection.Up:
|
||||||
hitObject.Y = algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength);
|
hitObject.Y = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
||||||
break;
|
break;
|
||||||
case ScrollingDirection.Down:
|
case ScrollingDirection.Down:
|
||||||
hitObject.Y = -algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength);
|
hitObject.Y = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
||||||
break;
|
break;
|
||||||
case ScrollingDirection.Left:
|
case ScrollingDirection.Left:
|
||||||
hitObject.X = algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength);
|
hitObject.X = scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
||||||
break;
|
break;
|
||||||
case ScrollingDirection.Right:
|
case ScrollingDirection.Right:
|
||||||
hitObject.X = -algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, TimeRange, scrollLength);
|
hitObject.X = -scrollingInfo.Algorithm.PositionAt(hitObject.HitObject.StartTime, currentTime, timeRange.Value, scrollLength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,6 @@
|
|||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Input.Bindings;
|
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Input.Bindings;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.UI.Scrolling
|
namespace osu.Game.Rulesets.UI.Scrolling
|
||||||
@ -14,88 +10,19 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A type of <see cref="Playfield"/> specialized towards scrolling <see cref="DrawableHitObject"/>s.
|
/// A type of <see cref="Playfield"/> specialized towards scrolling <see cref="DrawableHitObject"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ScrollingPlayfield : Playfield, IKeyBindingHandler<GlobalAction>
|
public abstract class ScrollingPlayfield : Playfield
|
||||||
{
|
{
|
||||||
/// <summary>
|
protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
||||||
/// The default span of time visible by the length of the scrolling axes.
|
|
||||||
/// This is clamped between <see cref="time_span_min"/> and <see cref="time_span_max"/>.
|
|
||||||
/// </summary>
|
|
||||||
private const double time_span_default = 1500;
|
|
||||||
|
|
||||||
/// <summary>
|
[Resolved]
|
||||||
/// The minimum span of time that may be visible by the length of the scrolling axes.
|
private IScrollingInfo scrollingInfo { get; set; }
|
||||||
/// </summary>
|
|
||||||
private const double time_span_min = 50;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The maximum span of time that may be visible by the length of the scrolling axes.
|
|
||||||
/// </summary>
|
|
||||||
private const double time_span_max = 10000;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The step increase/decrease of the span of time visible by the length of the scrolling axes.
|
|
||||||
/// </summary>
|
|
||||||
private const double time_span_step = 200;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The span of time that is visible by the length of the scrolling axes.
|
|
||||||
/// For example, only hit objects with start time less than or equal to 1000 will be visible with <see cref="VisibleTimeRange"/> = 1000.
|
|
||||||
/// </summary>
|
|
||||||
public readonly BindableDouble VisibleTimeRange = new BindableDouble(time_span_default)
|
|
||||||
{
|
|
||||||
Default = time_span_default,
|
|
||||||
MinValue = time_span_min,
|
|
||||||
MaxValue = time_span_max
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the player can change <see cref="VisibleTimeRange"/>.
|
|
||||||
/// </summary>
|
|
||||||
protected virtual bool UserScrollSpeedAdjustment => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The container that contains the <see cref="DrawableHitObject"/>s.
|
|
||||||
/// </summary>
|
|
||||||
public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)HitObjectContainer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The direction in which <see cref="DrawableHitObject"/>s in this <see cref="ScrollingPlayfield"/> should scroll.
|
|
||||||
/// </summary>
|
|
||||||
protected readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
|
||||||
|
|
||||||
protected virtual ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Sequential;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
HitObjects.TimeRange.BindTo(VisibleTimeRange);
|
Direction.BindTo(scrollingInfo.Direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(GlobalAction action)
|
protected sealed override HitObjectContainer CreateHitObjectContainer() => new ScrollingHitObjectContainer();
|
||||||
{
|
|
||||||
if (!UserScrollSpeedAdjustment)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (action)
|
|
||||||
{
|
|
||||||
case GlobalAction.IncreaseScrollSpeed:
|
|
||||||
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 200, Easing.OutQuint);
|
|
||||||
return true;
|
|
||||||
case GlobalAction.DecreaseScrollSpeed:
|
|
||||||
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 200, Easing.OutQuint);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool OnReleased(GlobalAction action) => false;
|
|
||||||
|
|
||||||
protected sealed override HitObjectContainer CreateHitObjectContainer()
|
|
||||||
{
|
|
||||||
var container = new ScrollingHitObjectContainer(VisualisationMethod);
|
|
||||||
container.Direction.BindTo(Direction);
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,18 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Lists;
|
using osu.Framework.Lists;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Timing;
|
using osu.Game.Rulesets.Timing;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.UI.Scrolling
|
namespace osu.Game.Rulesets.UI.Scrolling
|
||||||
{
|
{
|
||||||
@ -18,20 +23,82 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
/// A type of <see cref="RulesetContainer{TPlayfield,TObject}"/> that supports a <see cref="ScrollingPlayfield"/>.
|
/// A type of <see cref="RulesetContainer{TPlayfield,TObject}"/> that supports a <see cref="ScrollingPlayfield"/>.
|
||||||
/// <see cref="HitObject"/>s inside this <see cref="RulesetContainer{TPlayfield,TObject}"/> will scroll within the playfield.
|
/// <see cref="HitObject"/>s inside this <see cref="RulesetContainer{TPlayfield,TObject}"/> will scroll within the playfield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ScrollingRulesetContainer<TPlayfield, TObject> : RulesetContainer<TPlayfield, TObject>
|
public abstract class ScrollingRulesetContainer<TPlayfield, TObject> : RulesetContainer<TPlayfield, TObject>, IKeyBindingHandler<GlobalAction>
|
||||||
where TObject : HitObject
|
where TObject : HitObject
|
||||||
where TPlayfield : ScrollingPlayfield
|
where TPlayfield : ScrollingPlayfield
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The default span of time visible by the length of the scrolling axes.
|
||||||
|
/// This is clamped between <see cref="time_span_min"/> and <see cref="time_span_max"/>.
|
||||||
|
/// </summary>
|
||||||
|
private const double time_span_default = 1500;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The minimum span of time that may be visible by the length of the scrolling axes.
|
||||||
|
/// </summary>
|
||||||
|
private const double time_span_min = 50;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum span of time that may be visible by the length of the scrolling axes.
|
||||||
|
/// </summary>
|
||||||
|
private const double time_span_max = 10000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The step increase/decrease of the span of time visible by the length of the scrolling axes.
|
||||||
|
/// </summary>
|
||||||
|
private const double time_span_step = 200;
|
||||||
|
|
||||||
|
protected readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The span of time that is visible by the length of the scrolling axes.
|
||||||
|
/// For example, only hit objects with start time less than or equal to 1000 will be visible with <see cref="TimeRange"/> = 1000.
|
||||||
|
/// </summary>
|
||||||
|
protected readonly BindableDouble TimeRange = new BindableDouble(time_span_default)
|
||||||
|
{
|
||||||
|
Default = time_span_default,
|
||||||
|
MinValue = time_span_min,
|
||||||
|
MaxValue = time_span_max
|
||||||
|
};
|
||||||
|
|
||||||
|
protected virtual ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Sequential;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the player can change <see cref="VisibleTimeRange"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual bool UserScrollSpeedAdjustment => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the default <see cref="MultiplierControlPoint"/>s that adjust the scrolling rate of <see cref="HitObject"/>s
|
/// Provides the default <see cref="MultiplierControlPoint"/>s that adjust the scrolling rate of <see cref="HitObject"/>s
|
||||||
/// inside this <see cref="RulesetContainer{TPlayfield,TObject}"/>.
|
/// inside this <see cref="RulesetContainer{TPlayfield,TObject}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected readonly SortedList<MultiplierControlPoint> DefaultControlPoints = new SortedList<MultiplierControlPoint>(Comparer<MultiplierControlPoint>.Default);
|
private readonly SortedList<MultiplierControlPoint> controlPoints = new SortedList<MultiplierControlPoint>(Comparer<MultiplierControlPoint>.Default);
|
||||||
|
|
||||||
|
protected IScrollingInfo ScrollingInfo => scrollingInfo;
|
||||||
|
|
||||||
|
[Cached(Type = typeof(IScrollingInfo))]
|
||||||
|
private readonly LocalScrollingInfo scrollingInfo;
|
||||||
|
|
||||||
protected ScrollingRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
protected ScrollingRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||||
: base(ruleset, beatmap)
|
: base(ruleset, beatmap)
|
||||||
{
|
{
|
||||||
|
scrollingInfo = new LocalScrollingInfo();
|
||||||
|
scrollingInfo.Direction.BindTo(Direction);
|
||||||
|
scrollingInfo.TimeRange.BindTo(TimeRange);
|
||||||
|
|
||||||
|
switch (VisualisationMethod)
|
||||||
|
{
|
||||||
|
case ScrollVisualisationMethod.Sequential:
|
||||||
|
scrollingInfo.Algorithm = new SequentialScrollAlgorithm(controlPoints);
|
||||||
|
break;
|
||||||
|
case ScrollVisualisationMethod.Overlapping:
|
||||||
|
scrollingInfo.Algorithm = new OverlappingScrollAlgorithm(controlPoints);
|
||||||
|
break;
|
||||||
|
case ScrollVisualisationMethod.Constant:
|
||||||
|
scrollingInfo.Algorithm = new ConstantScrollAlgorithm();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -75,19 +142,40 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
// Collapse sections with the same start time
|
// Collapse sections with the same start time
|
||||||
.GroupBy(s => s.StartTime).Select(g => g.Last()).OrderBy(s => s.StartTime);
|
.GroupBy(s => s.StartTime).Select(g => g.Last()).OrderBy(s => s.StartTime);
|
||||||
|
|
||||||
DefaultControlPoints.AddRange(timingChanges);
|
controlPoints.AddRange(timingChanges);
|
||||||
|
|
||||||
// If we have no control points, add a default one
|
// If we have no control points, add a default one
|
||||||
if (DefaultControlPoints.Count == 0)
|
if (controlPoints.Count == 0)
|
||||||
DefaultControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier });
|
controlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier });
|
||||||
|
|
||||||
DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield)
|
public bool OnPressed(GlobalAction action)
|
||||||
{
|
{
|
||||||
playfield.HitObjects.AddControlPoint(controlPoint);
|
if (!UserScrollSpeedAdjustment)
|
||||||
playfield.NestedPlayfields?.OfType<ScrollingPlayfield>().ForEach(p => applySpeedAdjustment(controlPoint, p));
|
return false;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case GlobalAction.IncreaseScrollSpeed:
|
||||||
|
this.TransformBindableTo(TimeRange, TimeRange - time_span_step, 200, Easing.OutQuint);
|
||||||
|
return true;
|
||||||
|
case GlobalAction.DecreaseScrollSpeed:
|
||||||
|
this.TransformBindableTo(TimeRange, TimeRange + time_span_step, 200, Easing.OutQuint);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(GlobalAction action) => false;
|
||||||
|
|
||||||
|
private class LocalScrollingInfo : IScrollingInfo
|
||||||
|
{
|
||||||
|
public IBindable<ScrollingDirection> Direction { get; } = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
|
public IBindable<double> TimeRange { get; } = new BindableDouble();
|
||||||
|
|
||||||
|
public IScrollAlgorithm Algorithm { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
public class BlueprintContainer : CompositeDrawable
|
public class BlueprintContainer : CompositeDrawable
|
||||||
{
|
{
|
||||||
private SelectionBlueprintContainer selectionBlueprints;
|
private SelectionBlueprintContainer selectionBlueprints;
|
||||||
|
|
||||||
private Container<PlacementBlueprint> placementBlueprintContainer;
|
private Container<PlacementBlueprint> placementBlueprintContainer;
|
||||||
|
private PlacementBlueprint currentPlacement;
|
||||||
|
|
||||||
private SelectionBox selectionBox;
|
private SelectionBox selectionBox;
|
||||||
|
|
||||||
private IEnumerable<SelectionBlueprint> selections => selectionBlueprints.Children.Where(c => c.IsAlive);
|
private IEnumerable<SelectionBlueprint> selections => selectionBlueprints.Children.Where(c => c.IsAlive);
|
||||||
@ -117,19 +120,32 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (currentPlacement != null)
|
||||||
|
{
|
||||||
|
if (composer.CursorInPlacementArea)
|
||||||
|
currentPlacement.State = PlacementState.Shown;
|
||||||
|
else if (currentPlacement?.PlacementBegun == false)
|
||||||
|
currentPlacement.State = PlacementState.Hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Refreshes the current placement tool.
|
/// Refreshes the current placement tool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void refreshTool()
|
private void refreshTool()
|
||||||
{
|
{
|
||||||
placementBlueprintContainer.Clear();
|
placementBlueprintContainer.Clear();
|
||||||
|
currentPlacement = null;
|
||||||
|
|
||||||
var blueprint = CurrentTool?.CreatePlacementBlueprint();
|
var blueprint = CurrentTool?.CreatePlacementBlueprint();
|
||||||
if (blueprint != null)
|
if (blueprint != null)
|
||||||
placementBlueprintContainer.Child = blueprint;
|
placementBlueprintContainer.Child = currentPlacement = blueprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Select all masks in a given rectangle selection area.
|
/// Select all masks in a given rectangle selection area.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -8,16 +8,18 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
{
|
{
|
||||||
public class QuitButton : FillFlowContainer
|
public class HoldForMenuButton : FillFlowContainer
|
||||||
{
|
{
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
|
|
||||||
private readonly OsuSpriteText text;
|
private readonly OsuSpriteText text;
|
||||||
|
|
||||||
public QuitButton()
|
public HoldForMenuButton()
|
||||||
{
|
{
|
||||||
Direction = FillDirection.Horizontal;
|
Direction = FillDirection.Horizontal;
|
||||||
Spacing = new Vector2(20, 0);
|
Spacing = new Vector2(20, 0);
|
||||||
@ -79,7 +81,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
Alpha, MathHelper.Clamp(1 - positionalAdjust, 0.04f, 1), 0, 200, Easing.OutQuint);
|
Alpha, MathHelper.Clamp(1 - positionalAdjust, 0.04f, 1), 0, 200, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Button : HoldToConfirmContainer
|
private class Button : HoldToConfirmContainer, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
private SpriteIcon icon;
|
private SpriteIcon icon;
|
||||||
private CircularProgress circularProgress;
|
private CircularProgress circularProgress;
|
||||||
@ -90,6 +92,30 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
public Action HoverGained;
|
public Action HoverGained;
|
||||||
public Action HoverLost;
|
public Action HoverLost;
|
||||||
|
|
||||||
|
public bool OnPressed(GlobalAction action)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case GlobalAction.Back:
|
||||||
|
BeginConfirm();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(GlobalAction action)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case GlobalAction.Back:
|
||||||
|
AbortConfirm();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
@ -34,7 +34,7 @@ namespace osu.Game.Screens.Play
|
|||||||
public readonly HealthDisplay HealthDisplay;
|
public readonly HealthDisplay HealthDisplay;
|
||||||
public readonly SongProgress Progress;
|
public readonly SongProgress Progress;
|
||||||
public readonly ModDisplay ModDisplay;
|
public readonly ModDisplay ModDisplay;
|
||||||
public readonly QuitButton HoldToQuit;
|
public readonly HoldForMenuButton HoldToQuit;
|
||||||
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
||||||
|
|
||||||
private Bindable<bool> showHud;
|
private Bindable<bool> showHud;
|
||||||
@ -69,7 +69,7 @@ namespace osu.Game.Screens.Play
|
|||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
KeyCounter = CreateKeyCounter(adjustableClock as IFrameBasedClock),
|
KeyCounter = CreateKeyCounter(adjustableClock as IFrameBasedClock),
|
||||||
HoldToQuit = CreateQuitButton(),
|
HoldToQuit = CreateHoldForMenuButton(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ namespace osu.Game.Screens.Play
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
};
|
};
|
||||||
|
|
||||||
protected virtual QuitButton CreateQuitButton() => new QuitButton
|
protected virtual HoldForMenuButton CreateHoldForMenuButton() => new HoldForMenuButton
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
|
@ -35,6 +35,8 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
public class Player : ScreenWithBeatmapBackground, IProvideCursor
|
public class Player : ScreenWithBeatmapBackground, IProvideCursor
|
||||||
{
|
{
|
||||||
|
protected override bool AllowBackButton => false; // handled by HoldForMenuButton
|
||||||
|
|
||||||
protected override float BackgroundParallaxAmount => 0.1f;
|
protected override float BackgroundParallaxAmount => 0.1f;
|
||||||
|
|
||||||
protected override bool HideOverlaysOnEnter => true;
|
protected override bool HideOverlaysOnEnter => true;
|
||||||
|
95
osu.Game/Tests/Visual/ScrollingTestContainer.cs
Normal file
95
osu.Game/Tests/Visual/ScrollingTestContainer.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// 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.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Lists;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Timing;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A container which provides a <see cref="IScrollingInfo"/> to children.
|
||||||
|
/// This should only be used when testing
|
||||||
|
/// </summary>
|
||||||
|
public class ScrollingTestContainer : Container
|
||||||
|
{
|
||||||
|
public SortedList<MultiplierControlPoint> ControlPoints => scrollingInfo.Algorithm.ControlPoints;
|
||||||
|
|
||||||
|
public ScrollVisualisationMethod ScrollAlgorithm { set => scrollingInfo.Algorithm.Algorithm = value; }
|
||||||
|
|
||||||
|
public double TimeRange { set => scrollingInfo.TimeRange.Value = value; }
|
||||||
|
|
||||||
|
[Cached(Type = typeof(IScrollingInfo))]
|
||||||
|
private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo();
|
||||||
|
|
||||||
|
public ScrollingTestContainer(ScrollingDirection direction)
|
||||||
|
{
|
||||||
|
scrollingInfo.Direction.Value = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Flip() => scrollingInfo.Direction.Value = scrollingInfo.Direction.Value == ScrollingDirection.Up ? ScrollingDirection.Down : ScrollingDirection.Up;
|
||||||
|
|
||||||
|
private class TestScrollingInfo : IScrollingInfo
|
||||||
|
{
|
||||||
|
public readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
|
||||||
|
IBindable<ScrollingDirection> IScrollingInfo.Direction => Direction;
|
||||||
|
|
||||||
|
public readonly Bindable<double> TimeRange = new Bindable<double>(1000) { Value = 1000 };
|
||||||
|
IBindable<double> IScrollingInfo.TimeRange => TimeRange;
|
||||||
|
|
||||||
|
public readonly TestScrollAlgorithm Algorithm = new TestScrollAlgorithm();
|
||||||
|
IScrollAlgorithm IScrollingInfo.Algorithm => Algorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestScrollAlgorithm : IScrollAlgorithm
|
||||||
|
{
|
||||||
|
public readonly SortedList<MultiplierControlPoint> ControlPoints = new SortedList<MultiplierControlPoint>();
|
||||||
|
|
||||||
|
private IScrollAlgorithm implementation;
|
||||||
|
|
||||||
|
public TestScrollAlgorithm()
|
||||||
|
{
|
||||||
|
Algorithm = ScrollVisualisationMethod.Constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScrollVisualisationMethod Algorithm
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case ScrollVisualisationMethod.Constant:
|
||||||
|
implementation = new ConstantScrollAlgorithm();
|
||||||
|
break;
|
||||||
|
case ScrollVisualisationMethod.Overlapping:
|
||||||
|
implementation = new OverlappingScrollAlgorithm(ControlPoints);
|
||||||
|
break;
|
||||||
|
case ScrollVisualisationMethod.Sequential:
|
||||||
|
implementation = new SequentialScrollAlgorithm(ControlPoints);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetDisplayStartTime(double time, double timeRange)
|
||||||
|
=> implementation.GetDisplayStartTime(time, timeRange);
|
||||||
|
|
||||||
|
public float GetLength(double startTime, double endTime, double timeRange, float scrollLength)
|
||||||
|
=> implementation.GetLength(startTime, endTime, timeRange, scrollLength);
|
||||||
|
|
||||||
|
public float PositionAt(double time, double currentTime, double timeRange, float scrollLength)
|
||||||
|
=> implementation.PositionAt(time, currentTime, timeRange, scrollLength);
|
||||||
|
|
||||||
|
public double TimeAt(float position, double currentTime, double timeRange, float scrollLength)
|
||||||
|
=> implementation.TimeAt(position, currentTime, timeRange, scrollLength);
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
=> implementation.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -29,9 +29,12 @@ namespace osu.Game.Tests.Visual
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
base.Content.Add(blueprint = CreateBlueprint());
|
blueprint = CreateBlueprint();
|
||||||
|
blueprint.Depth = float.MinValue;
|
||||||
blueprint.SelectionRequested += (_, __) => blueprint.Select();
|
blueprint.SelectionRequested += (_, __) => blueprint.Select();
|
||||||
|
|
||||||
|
Add(blueprint);
|
||||||
|
|
||||||
AddStep("Select", () => blueprint.Select());
|
AddStep("Select", () => blueprint.Select());
|
||||||
AddStep("Deselect", () => blueprint.Deselect());
|
AddStep("Deselect", () => blueprint.Deselect());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user