1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 12:42:54 +08:00

Add basic visualisation of different control point types

This commit is contained in:
Dean Herbert 2019-10-18 17:46:39 +09:00
parent f22ec6f5bd
commit 71d45d41d1
2 changed files with 105 additions and 34 deletions

View File

@ -36,6 +36,12 @@ namespace osu.Game.Beatmaps.ControlPoints
[JsonProperty] [JsonProperty]
public SortedList<EffectControlPoint> EffectPoints { get; private set; } = new SortedList<EffectControlPoint>(Comparer<EffectControlPoint>.Default); public SortedList<EffectControlPoint> EffectPoints { get; private set; } = new SortedList<EffectControlPoint>(Comparer<EffectControlPoint>.Default);
public IReadOnlyList<ControlPoint> AllControlPoints =>
TimingPoints
.Concat((IEnumerable<ControlPoint>)DifficultyPoints)
.Concat(SamplePoints)
.Concat(EffectPoints).ToArray();
/// <summary> /// <summary>
/// Finds the difficulty control point that is active at <paramref name="time"/>. /// Finds the difficulty control point that is active at <paramref name="time"/>.
/// </summary> /// </summary>

View File

@ -2,13 +2,13 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -16,6 +16,7 @@ using osu.Game.Beatmaps.ControlPoints;
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 osuTK;
namespace osu.Game.Screens.Edit.Timing namespace osu.Game.Screens.Edit.Timing
{ {
@ -64,7 +65,7 @@ namespace osu.Game.Screens.Edit.Timing
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Child = new ControlPointTable Child = new ControlPointTable
{ {
ControlPoints = Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints ControlPoints = Beatmap.Value.Beatmap.ControlPointInfo.AllControlPoints
} }
} }
}; };
@ -115,7 +116,7 @@ namespace osu.Game.Screens.Edit.Timing
}); });
} }
public IReadOnlyList<ControlPoint> ControlPoints public IEnumerable<ControlPoint> ControlPoints
{ {
set set
{ {
@ -125,14 +126,15 @@ namespace osu.Game.Screens.Edit.Timing
if (value?.Any() != true) if (value?.Any() != true)
return; return;
for (int i = 0; i < value.Count; i++) var grouped = value.GroupBy(cp => cp.Time, cp => cp);
foreach (var group in grouped)
{ {
var cp = value[i]; backgroundFlow.Add(new RowBackground { Action = () => controlPoint.Value = group.First() });
backgroundFlow.Add(new RowBackground { Action = () => controlPoint.Value = cp });
} }
Columns = createHeaders(); Columns = createHeaders();
Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); Content = grouped.Select((s, i) => createContent(i, s)).ToArray().ToRectangular();
} }
} }
@ -141,41 +143,104 @@ namespace osu.Game.Screens.Edit.Timing
var columns = new List<TableColumn> var columns = new List<TableColumn>
{ {
new TableColumn(string.Empty, Anchor.Centre, new Dimension(GridSizeMode.AutoSize)), new TableColumn(string.Empty, Anchor.Centre, new Dimension(GridSizeMode.AutoSize)),
new TableColumn("offset", Anchor.Centre), new TableColumn("time", Anchor.Centre, new Dimension(GridSizeMode.AutoSize)),
new TableColumn("BPM", Anchor.Centre), new TableColumn("Attributes", Anchor.Centre),
new TableColumn("Meter", Anchor.Centre),
new TableColumn("Sample Set", Anchor.Centre),
new TableColumn("Volume", Anchor.Centre),
}; };
return columns.ToArray(); return columns.ToArray();
} }
private Drawable[] createContent(int index, ControlPoint controlPoint) private Drawable[] createContent(int index, IGrouping<double, ControlPoint> controlPoints) => new Drawable[]
{ {
return new Drawable[] new OsuSpriteText
{ {
new OsuSpriteText Text = $"#{index + 1}",
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold),
Margin = new MarginPadding(10)
},
new OsuSpriteText
{
Text = $"{controlPoints.Key:n0}ms",
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
ChildrenEnumerable = controlPoints.Select(createAttribute).Where(c => c != null),
Padding = new MarginPadding(10),
Spacing = new Vector2(10)
},
};
private Drawable createAttribute(ControlPoint controlPoint)
{
if (controlPoint.AutoGenerated)
return null;
switch (controlPoint)
{
case TimingControlPoint timing:
return new RowAttribute("timing", $"{60000 / timing.BeatLength:n1}bpm {timing.TimeSignature}");
case DifficultyControlPoint difficulty:
return new RowAttribute("difficulty", $"{difficulty.SpeedMultiplier:n2}x");
case EffectControlPoint effect:
return new RowAttribute("effect", $"{(effect.KiaiMode ? "Kiai " : "")}{(effect.OmitFirstBarLine ? "NoBarLine " : "")}");
case SampleControlPoint sample:
return new RowAttribute("sample", $"{sample.SampleBank} {sample.SampleVolume}%");
}
return null;
}
private class RowAttribute : CompositeDrawable, IHasTooltip
{
private readonly string header;
private readonly string content;
public RowAttribute(string header, string content)
{
this.header = header;
this.content = content;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AutoSizeAxes = Axes.X;
Height = 20;
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
Masking = true;
CornerRadius = 5;
InternalChildren = new Drawable[]
{ {
Text = $"#{index + 1}", new Box
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) {
}, Colour = colours.Yellow,
new OsuSpriteText RelativeSizeAxes = Axes.Both,
{ },
Text = $"{controlPoint.Time}", new OsuSpriteText
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) {
}, Padding = new MarginPadding(2),
new OsuSpriteText Anchor = Anchor.Centre,
{ Origin = Anchor.Centre,
Text = $"{(controlPoint as TimingControlPoint)?.BeatLength.ToString(CultureInfo.InvariantCulture) ?? "-"}", Font = OsuFont.Default.With(weight: FontWeight.SemiBold, size: 12),
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) Text = header,
}, Colour = colours.Gray3
new OsuSpriteText },
{ };
Text = $"{(controlPoint as TimingControlPoint)?.TimeSignature.ToString() ?? "-"}", }
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
}, public string TooltipText => content;
};
} }
protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? string.Empty); protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? string.Empty);