mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 08:49:59 +09:00
Add the ability to add new ControlPoint types to existing groups
This commit is contained in:
@ -17,6 +17,11 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
{
|
{
|
||||||
typeof(ControlPointTable),
|
typeof(ControlPointTable),
|
||||||
typeof(ControlPointSettings),
|
typeof(ControlPointSettings),
|
||||||
|
typeof(Section<>),
|
||||||
|
typeof(TimingSection),
|
||||||
|
typeof(EffectSection),
|
||||||
|
typeof(SampleSection),
|
||||||
|
typeof(DifficultySection),
|
||||||
typeof(RowAttribute)
|
typeof(RowAttribute)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// 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;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.ControlPoints
|
namespace osu.Game.Beatmaps.ControlPoints
|
||||||
{
|
{
|
||||||
@ -17,9 +17,9 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public double Time { get; }
|
public double Time { get; }
|
||||||
|
|
||||||
public IReadOnlyList<ControlPoint> ControlPoints => controlPoints;
|
public IBindableList<ControlPoint> ControlPoints => controlPoints;
|
||||||
|
|
||||||
private readonly List<ControlPoint> controlPoints = new List<ControlPoint>();
|
private readonly BindableList<ControlPoint> controlPoints = new BindableList<ControlPoint>();
|
||||||
|
|
||||||
public ControlPointGroup(double time)
|
public ControlPointGroup(double time)
|
||||||
{
|
{
|
||||||
|
@ -2,17 +2,12 @@
|
|||||||
// 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.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
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.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.UserInterface;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Timing
|
namespace osu.Game.Screens.Edit.Timing
|
||||||
{
|
{
|
||||||
@ -51,190 +46,5 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
new SampleSection(),
|
new SampleSection(),
|
||||||
new EffectSection(),
|
new EffectSection(),
|
||||||
};
|
};
|
||||||
|
|
||||||
private class TimingSection : Section<TimingControlPoint>
|
|
||||||
{
|
|
||||||
private OsuSpriteText bpm;
|
|
||||||
private OsuSpriteText timeSignature;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
Flow.AddRange(new[]
|
|
||||||
{
|
|
||||||
bpm = new OsuSpriteText(),
|
|
||||||
timeSignature = new OsuSpriteText(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
ControlPoint.BindValueChanged(point =>
|
|
||||||
{
|
|
||||||
bpm.Text = $"BPM: {point.NewValue?.BeatLength}";
|
|
||||||
timeSignature.Text = $"Signature: {point.NewValue?.TimeSignature}";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DifficultySection : Section<DifficultyControlPoint>
|
|
||||||
{
|
|
||||||
private OsuSpriteText multiplier;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
Flow.AddRange(new[]
|
|
||||||
{
|
|
||||||
multiplier = new OsuSpriteText(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
ControlPoint.BindValueChanged(point => { multiplier.Text = $"Multiplier: {point.NewValue?.SpeedMultiplier}"; });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SampleSection : Section<SampleControlPoint>
|
|
||||||
{
|
|
||||||
private OsuSpriteText bank;
|
|
||||||
private OsuSpriteText volume;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
Flow.AddRange(new[]
|
|
||||||
{
|
|
||||||
bank = new OsuSpriteText(),
|
|
||||||
volume = new OsuSpriteText(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
ControlPoint.BindValueChanged(point =>
|
|
||||||
{
|
|
||||||
bank.Text = $"Bank: {point.NewValue?.SampleBank}";
|
|
||||||
volume.Text = $"Volume: {point.NewValue?.SampleVolume}";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class EffectSection : Section<EffectControlPoint>
|
|
||||||
{
|
|
||||||
private OsuSpriteText kiai;
|
|
||||||
private OsuSpriteText omitBarLine;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
Flow.AddRange(new[]
|
|
||||||
{
|
|
||||||
kiai = new OsuSpriteText(),
|
|
||||||
omitBarLine = new OsuSpriteText(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
ControlPoint.BindValueChanged(point =>
|
|
||||||
{
|
|
||||||
kiai.Text = $"Kiai: {point.NewValue?.KiaiMode}";
|
|
||||||
omitBarLine.Text = $"Skip Bar Line: {point.NewValue?.OmitFirstBarLine}";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Section<T> : CompositeDrawable
|
|
||||||
where T : ControlPoint
|
|
||||||
{
|
|
||||||
private OsuCheckbox checkbox;
|
|
||||||
private Container content;
|
|
||||||
|
|
||||||
protected FillFlowContainer Flow { get; private set; }
|
|
||||||
|
|
||||||
protected Bindable<T> ControlPoint { get; } = new Bindable<T>();
|
|
||||||
|
|
||||||
private const float header_height = 20;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Bindable<ControlPointGroup> selectedPoints { get; set; }
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(OsuColour colours)
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X;
|
|
||||||
AutoSizeDuration = 200;
|
|
||||||
AutoSizeEasing = Easing.OutQuint;
|
|
||||||
AutoSizeAxes = Axes.Y;
|
|
||||||
|
|
||||||
Masking = true;
|
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
Colour = colours.Gray1,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Height = header_height,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
checkbox = new OsuCheckbox
|
|
||||||
{
|
|
||||||
LabelText = typeof(T).Name.Replace(typeof(ControlPoint).Name, string.Empty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content = new Container
|
|
||||||
{
|
|
||||||
Y = header_height,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
Colour = colours.Gray2,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
Flow = new FillFlowContainer
|
|
||||||
{
|
|
||||||
Padding = new MarginPadding(10),
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
selectedPoints.BindValueChanged(points =>
|
|
||||||
{
|
|
||||||
ControlPoint.Value = points.NewValue?.ControlPoints.OfType<T>().FirstOrDefault();
|
|
||||||
|
|
||||||
checkbox.Current.Value = ControlPoint.Value != null;
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
checkbox.Current.BindValueChanged(selected => { content.BypassAutoSizeAxes = selected.NewValue ? Axes.None : Axes.Y; }, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,35 +92,57 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
Text = $"{group.Time:n0}ms",
|
Text = $"{group.Time:n0}ms",
|
||||||
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
|
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold)
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
new ControlGroupAttributes(group),
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Direction = FillDirection.Horizontal,
|
|
||||||
ChildrenEnumerable = group.ControlPoints.Select(createAttribute).Where(c => c != null),
|
|
||||||
Padding = new MarginPadding(10),
|
|
||||||
Spacing = new Vector2(2)
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private Drawable createAttribute(ControlPoint controlPoint)
|
private class ControlGroupAttributes : CompositeDrawable
|
||||||
{
|
{
|
||||||
switch (controlPoint)
|
private readonly IBindableList<ControlPoint> controlPoints;
|
||||||
|
|
||||||
|
private readonly FillFlowContainer fill;
|
||||||
|
|
||||||
|
public ControlGroupAttributes(ControlPointGroup group)
|
||||||
{
|
{
|
||||||
case TimingControlPoint timing:
|
InternalChild = fill = new FillFlowContainer
|
||||||
return new RowAttribute("timing", $"{60000 / timing.BeatLength:n1}bpm {timing.TimeSignature}");
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Padding = new MarginPadding(10),
|
||||||
|
Spacing = new Vector2(2)
|
||||||
|
};
|
||||||
|
|
||||||
case DifficultyControlPoint difficulty:
|
controlPoints = group.ControlPoints.GetBoundCopy();
|
||||||
|
controlPoints.ItemsAdded += _ => createChildren();
|
||||||
|
controlPoints.ItemsRemoved += _ => createChildren();
|
||||||
|
|
||||||
return new RowAttribute("difficulty", $"{difficulty.SpeedMultiplier:n2}x");
|
createChildren();
|
||||||
|
|
||||||
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 void createChildren()
|
||||||
|
{
|
||||||
|
fill.ChildrenEnumerable = controlPoints.Select(createAttribute).Where(c => c != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable createAttribute(ControlPoint controlPoint)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
37
osu.Game/Screens/Edit/Timing/DifficultySection.cs
Normal file
37
osu.Game/Screens/Edit/Timing/DifficultySection.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Timing
|
||||||
|
{
|
||||||
|
internal class DifficultySection : Section<DifficultyControlPoint>
|
||||||
|
{
|
||||||
|
private OsuSpriteText multiplier;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Flow.AddRange(new[]
|
||||||
|
{
|
||||||
|
multiplier = new OsuSpriteText(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
ControlPoint.BindValueChanged(point => { multiplier.Text = $"Multiplier: {point.NewValue?.SpeedMultiplier}"; });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DifficultyControlPoint CreatePoint()
|
||||||
|
{
|
||||||
|
var reference = Beatmap.Value.Beatmap.ControlPointInfo.DifficultyPointAt(SelectedGroup.Value.Time);
|
||||||
|
|
||||||
|
return new DifficultyControlPoint
|
||||||
|
{
|
||||||
|
SpeedMultiplier = reference.SpeedMultiplier,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
osu.Game/Screens/Edit/Timing/EffectSection.cs
Normal file
44
osu.Game/Screens/Edit/Timing/EffectSection.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Timing
|
||||||
|
{
|
||||||
|
internal class EffectSection : Section<EffectControlPoint>
|
||||||
|
{
|
||||||
|
private OsuSpriteText kiai;
|
||||||
|
private OsuSpriteText omitBarLine;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Flow.AddRange(new[]
|
||||||
|
{
|
||||||
|
kiai = new OsuSpriteText(),
|
||||||
|
omitBarLine = new OsuSpriteText(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
ControlPoint.BindValueChanged(point =>
|
||||||
|
{
|
||||||
|
kiai.Text = $"Kiai: {point.NewValue?.KiaiMode}";
|
||||||
|
omitBarLine.Text = $"Skip Bar Line: {point.NewValue?.OmitFirstBarLine}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override EffectControlPoint CreatePoint()
|
||||||
|
{
|
||||||
|
var reference = Beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(SelectedGroup.Value.Time);
|
||||||
|
|
||||||
|
return new EffectControlPoint
|
||||||
|
{
|
||||||
|
KiaiMode = reference.KiaiMode,
|
||||||
|
OmitFirstBarLine = reference.OmitFirstBarLine
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
osu.Game/Screens/Edit/Timing/SampleSection.cs
Normal file
44
osu.Game/Screens/Edit/Timing/SampleSection.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Timing
|
||||||
|
{
|
||||||
|
internal class SampleSection : Section<SampleControlPoint>
|
||||||
|
{
|
||||||
|
private OsuSpriteText bank;
|
||||||
|
private OsuSpriteText volume;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Flow.AddRange(new[]
|
||||||
|
{
|
||||||
|
bank = new OsuSpriteText(),
|
||||||
|
volume = new OsuSpriteText(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SampleControlPoint CreatePoint()
|
||||||
|
{
|
||||||
|
var reference = Beatmap.Value.Beatmap.ControlPointInfo.SamplePointAt(SelectedGroup.Value.Time);
|
||||||
|
|
||||||
|
return new SampleControlPoint
|
||||||
|
{
|
||||||
|
SampleBank = reference.SampleBank,
|
||||||
|
SampleVolume = reference.SampleVolume,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
ControlPoint.BindValueChanged(point =>
|
||||||
|
{
|
||||||
|
bank.Text = $"Bank: {point.NewValue?.SampleBank}";
|
||||||
|
volume.Text = $"Volume: {point.NewValue?.SampleVolume}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
126
osu.Game/Screens/Edit/Timing/Section.cs
Normal file
126
osu.Game/Screens/Edit/Timing/Section.cs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Timing
|
||||||
|
{
|
||||||
|
internal abstract class Section<T> : CompositeDrawable
|
||||||
|
where T : ControlPoint
|
||||||
|
{
|
||||||
|
private OsuCheckbox checkbox;
|
||||||
|
private Container content;
|
||||||
|
|
||||||
|
protected FillFlowContainer Flow { get; private set; }
|
||||||
|
|
||||||
|
protected Bindable<T> ControlPoint { get; } = new Bindable<T>();
|
||||||
|
|
||||||
|
private const float header_height = 20;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
protected IBindable<WorkingBeatmap> Beatmap { get; private set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
protected Bindable<ControlPointGroup> SelectedGroup { get; private set; }
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
AutoSizeDuration = 200;
|
||||||
|
AutoSizeEasing = Easing.OutQuint;
|
||||||
|
AutoSizeAxes = Axes.Y;
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = colours.Gray1,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = header_height,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
checkbox = new OsuCheckbox
|
||||||
|
{
|
||||||
|
LabelText = typeof(T).Name.Replace(typeof(ControlPoint).Name, string.Empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = new Container
|
||||||
|
{
|
||||||
|
Y = header_height,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = colours.Gray2,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
Flow = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Padding = new MarginPadding(10),
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
checkbox.Current.BindValueChanged(selected =>
|
||||||
|
{
|
||||||
|
if (selected.NewValue)
|
||||||
|
{
|
||||||
|
if (SelectedGroup.Value == null)
|
||||||
|
{
|
||||||
|
checkbox.Current.Value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ControlPoint.Value == null)
|
||||||
|
SelectedGroup.Value.Add(ControlPoint.Value = CreatePoint());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ControlPoint.Value != null)
|
||||||
|
{
|
||||||
|
SelectedGroup.Value.Remove(ControlPoint.Value);
|
||||||
|
ControlPoint.Value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content.BypassAutoSizeAxes = selected.NewValue ? Axes.None : Axes.Y;
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
SelectedGroup.BindValueChanged(points =>
|
||||||
|
{
|
||||||
|
ControlPoint.Value = points.NewValue?.ControlPoints.OfType<T>().FirstOrDefault();
|
||||||
|
checkbox.Current.Value = ControlPoint.Value != null;
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T CreatePoint();
|
||||||
|
}
|
||||||
|
}
|
44
osu.Game/Screens/Edit/Timing/TimingSection.cs
Normal file
44
osu.Game/Screens/Edit/Timing/TimingSection.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Edit.Timing
|
||||||
|
{
|
||||||
|
internal class TimingSection : Section<TimingControlPoint>
|
||||||
|
{
|
||||||
|
private OsuSpriteText bpm;
|
||||||
|
private OsuSpriteText timeSignature;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Flow.AddRange(new[]
|
||||||
|
{
|
||||||
|
bpm = new OsuSpriteText(),
|
||||||
|
timeSignature = new OsuSpriteText(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
ControlPoint.BindValueChanged(point =>
|
||||||
|
{
|
||||||
|
bpm.Text = $"BPM: {point.NewValue?.BeatLength}";
|
||||||
|
timeSignature.Text = $"Signature: {point.NewValue?.TimeSignature}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TimingControlPoint CreatePoint()
|
||||||
|
{
|
||||||
|
var reference = Beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(SelectedGroup.Value.Time);
|
||||||
|
|
||||||
|
return new TimingControlPoint
|
||||||
|
{
|
||||||
|
BeatLength = reference.BeatLength,
|
||||||
|
TimeSignature = reference.TimeSignature
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user