1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-06 07:02: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}", Text = $"#{index + 1}",
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold),
Margin = new MarginPadding(10)
}, },
new OsuSpriteText new OsuSpriteText
{ {
Text = $"{controlPoint.Time}", Text = $"{controlPoints.Key:n0}ms",
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
}, },
new OsuSpriteText new FillFlowContainer
{ {
Text = $"{(controlPoint as TimingControlPoint)?.BeatLength.ToString(CultureInfo.InvariantCulture) ?? "-"}", RelativeSizeAxes = Axes.Both,
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) Direction = FillDirection.Horizontal,
}, ChildrenEnumerable = controlPoints.Select(createAttribute).Where(c => c != null),
new OsuSpriteText Padding = new MarginPadding(10),
{ Spacing = new Vector2(10)
Text = $"{(controlPoint as TimingControlPoint)?.TimeSignature.ToString() ?? "-"}",
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
}, },
}; };
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[]
{
new Box
{
Colour = colours.Yellow,
RelativeSizeAxes = Axes.Both,
},
new OsuSpriteText
{
Padding = new MarginPadding(2),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.Default.With(weight: FontWeight.SemiBold, size: 12),
Text = header,
Colour = colours.Gray3
},
};
}
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);