1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 12:02:55 +08:00

Merge branch 'master' into beatmap-overlay-null-pp

This commit is contained in:
Salman Ahmed 2022-07-25 07:18:03 +03:00
commit 3beb1da3de
11 changed files with 474 additions and 238 deletions

View File

@ -3,10 +3,10 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -40,8 +40,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private TestReplayRecorder recorder;
[Cached]
private GameplayState gameplayState = TestGameplayState.Create(new OsuRuleset());
private GameplayState gameplayState;
[SetUpSteps]
public void SetUpSteps()
@ -52,81 +51,15 @@ namespace osu.Game.Tests.Visual.Gameplay
{
replay = new Replay();
Add(new GridContainer
gameplayState = TestGameplayState.Create(new OsuRuleset());
gameplayState.Score.Replay = replay;
Child = new DependencyProvidingContainer
{
RelativeSizeAxes = Axes.Both,
Content = new[]
{
new Drawable[]
{
recordingManager = new TestRulesetInputManager(TestCustomisableModRuleset.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
{
Recorder = recorder = new TestReplayRecorder(new Score
{
Replay = replay,
ScoreInfo =
{
BeatmapInfo = gameplayState.Beatmap.BeatmapInfo,
Ruleset = new OsuRuleset().RulesetInfo,
}
})
{
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
},
Child = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
Colour = Color4.Brown,
RelativeSizeAxes = Axes.Both,
},
new OsuSpriteText
{
Text = "Recording",
Scale = new Vector2(3),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
new TestInputConsumer()
}
},
}
},
new Drawable[]
{
playbackManager = new TestRulesetInputManager(TestCustomisableModRuleset.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
{
ReplayInputHandler = new TestFramedReplayInputHandler(replay)
{
GamefieldToScreenSpace = pos => playbackManager.ToScreenSpace(pos),
},
Child = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
Colour = Color4.DarkBlue,
RelativeSizeAxes = Axes.Both,
},
new OsuSpriteText
{
Text = "Playback",
Scale = new Vector2(3),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
new TestInputConsumer()
}
},
}
}
}
});
CachedDependencies = new (Type, object)[] { (typeof(GameplayState), gameplayState) },
Child = createContent(),
};
});
}
@ -203,6 +136,74 @@ namespace osu.Game.Tests.Visual.Gameplay
recorder = null;
}
private Drawable createContent() => new GridContainer
{
RelativeSizeAxes = Axes.Both,
Content = new[]
{
new Drawable[]
{
recordingManager = new TestRulesetInputManager(TestCustomisableModRuleset.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
{
Recorder = recorder = new TestReplayRecorder(gameplayState.Score)
{
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
},
Child = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
Colour = Color4.Brown,
RelativeSizeAxes = Axes.Both,
},
new OsuSpriteText
{
Text = "Recording",
Scale = new Vector2(3),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
new TestInputConsumer()
}
},
}
},
new Drawable[]
{
playbackManager = new TestRulesetInputManager(TestCustomisableModRuleset.CreateTestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
{
ReplayInputHandler = new TestFramedReplayInputHandler(replay)
{
GamefieldToScreenSpace = pos => playbackManager.ToScreenSpace(pos),
},
Child = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
Colour = Color4.DarkBlue,
RelativeSizeAxes = Axes.Both,
},
new OsuSpriteText
{
Text = "Playback",
Scale = new Vector2(3),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
new TestInputConsumer()
}
},
}
}
}
};
public class TestFramedReplayInputHandler : FramedReplayInputHandler<TestReplayFrame>
{
public TestFramedReplayInputHandler(Replay replay)

View File

@ -5,6 +5,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Screens;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Spectator;
@ -43,6 +44,21 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("spectator client sent correct ruleset", () => spectatorClient.WatchedUserStates[dummy_user_id].RulesetID == Ruleset.Value.OnlineID);
}
[Test]
public void TestRestart()
{
AddAssert("spectator client sees playing state", () => spectatorClient.WatchedUserStates[dummy_user_id].State == SpectatedUserState.Playing);
AddStep("exit player", () => Player.Exit());
AddStep("reload player", LoadPlayer);
AddUntilStep("wait for player load", () => Player.IsLoaded && Player.Alpha == 1);
AddAssert("spectator client sees playing state", () => spectatorClient.WatchedUserStates[dummy_user_id].State == SpectatedUserState.Playing);
AddWaitStep("wait", 5);
AddUntilStep("spectator client still sees playing state", () => spectatorClient.WatchedUserStates[dummy_user_id].State == SpectatedUserState.Playing);
}
public override void TearDownSteps()
{
base.TearDownSteps();

View File

@ -8,8 +8,10 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays;
@ -17,11 +19,26 @@ namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneLabelledSliderBar : OsuTestScene
{
[TestCase(false)]
[TestCase(true)]
public void TestSliderBar(bool hasDescription) => createSliderBar(hasDescription);
[Test]
public void TestBasic() => createSliderBar();
private void createSliderBar(bool hasDescription = false)
[Test]
public void TestDescription()
{
createSliderBar();
AddStep("set description", () => this.ChildrenOfType<LabelledSliderBar<double>>().ForEach(l => l.Description = "this text describes the component"));
}
[Test]
public void TestSize()
{
createSliderBar();
AddStep("set zero width", () => this.ChildrenOfType<LabelledSliderBar<double>>().ForEach(l => l.ResizeWidthTo(0, 200, Easing.OutQuint)));
AddStep("set negative width", () => this.ChildrenOfType<LabelledSliderBar<double>>().ForEach(l => l.ResizeWidthTo(-1, 200, Easing.OutQuint)));
AddStep("revert back", () => this.ChildrenOfType<LabelledSliderBar<double>>().ForEach(l => l.ResizeWidthTo(1, 200, Easing.OutQuint)));
}
private void createSliderBar()
{
AddStep("create component", () =>
{
@ -38,6 +55,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{
new LabelledSliderBar<double>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Current = new BindableDouble(5)
{
MinValue = 0,
@ -45,7 +64,6 @@ namespace osu.Game.Tests.Visual.UserInterface
Precision = 1,
},
Label = "a sample component",
Description = hasDescription ? "this text describes the component" : string.Empty,
},
},
};
@ -54,10 +72,14 @@ namespace osu.Game.Tests.Visual.UserInterface
{
flow.Add(new OverlayColourContainer(colour)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Child = new LabelledSliderBar<double>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Current = new BindableDouble(5)
{
MinValue = 0,
@ -65,7 +87,6 @@ namespace osu.Game.Tests.Visual.UserInterface
Precision = 1,
},
Label = "a sample component",
Description = hasDescription ? "this text describes the component" : string.Empty,
}
});
}

View File

@ -0,0 +1,77 @@
// 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.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestSceneModPresetColumn : OsuTestScene
{
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
[Test]
public void TestBasicAppearance()
{
ModPresetColumn modPresetColumn = null!;
AddStep("create content", () => Child = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(30),
Child = modPresetColumn = new ModPresetColumn
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Presets = createTestPresets().ToArray()
}
});
AddStep("change presets", () => modPresetColumn.Presets = createTestPresets().Skip(1).ToArray());
}
private static IEnumerable<ModPreset> createTestPresets() => new[]
{
new ModPreset
{
Name = "First preset",
Description = "Please ignore",
Mods = new Mod[]
{
new OsuModHardRock(),
new OsuModDoubleTime()
}
},
new ModPreset
{
Name = "AR0",
Description = "For good readers",
Mods = new Mod[]
{
new OsuModDifficultyAdjust
{
ApproachRate = { Value = 0 }
}
}
},
new ModPreset
{
Name = "This preset is going to have an extraordinarily long name",
Description = "This is done so that the capability to truncate overlong texts may be demonstrated",
Mods = new Mod[]
{
new OsuModFlashlight(),
new OsuModSpinIn()
}
}
};
}
}

View File

@ -228,10 +228,8 @@ namespace osu.Game.Graphics.UserInterface
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
LeftBox.Scale = new Vector2(Math.Clamp(
RangePadding + Nub.DrawPosition.X - Nub.DrawWidth / 2, 0, DrawWidth), 1);
RightBox.Scale = new Vector2(Math.Clamp(
DrawWidth - Nub.DrawPosition.X - RangePadding - Nub.DrawWidth / 2, 0, DrawWidth), 1);
LeftBox.Scale = new Vector2(Math.Clamp(RangePadding + Nub.DrawPosition.X - Nub.DrawWidth / 2, 0, Math.Max(0, DrawWidth)), 1);
RightBox.Scale = new Vector2(Math.Clamp(DrawWidth - Nub.DrawPosition.X - RangePadding - Nub.DrawWidth / 2, 0, Math.Max(0, DrawWidth)), 1);
}
protected override void UpdateValue(float value)

View File

@ -24,6 +24,11 @@ namespace osu.Game.Localisation
/// </summary>
public static LocalisableString ModCustomisation => new TranslatableString(getKey(@"mod_customisation"), @"Mod Customisation");
/// <summary>
/// "Personal Presets"
/// </summary>
public static LocalisableString PersonalPresets => new TranslatableString(getKey(@"personal_presets"), @"Personal Presets");
private static string getKey(string key) => $@"{prefix}:{key}";
}
}

View File

@ -206,6 +206,11 @@ namespace osu.Game.Online.Spectator
if (!IsPlaying)
return;
// Disposal can take some time, leading to EndPlaying potentially being called after a future play session.
// Account for this by ensuring the score of the current play matches the one in the provided state.
if (currentScore != state.Score)
return;
if (pendingFrames.Count > 0)
purgePendingFrames();

View File

@ -12,14 +12,10 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
using osu.Game.Overlays.Mods.Input;
@ -29,10 +25,8 @@ using osuTK.Graphics;
namespace osu.Game.Overlays.Mods
{
public class ModColumn : CompositeDrawable
public class ModColumn : ModSelectColumn
{
public readonly Container TopLevelContent;
public readonly ModType ModType;
private IReadOnlyList<ModState> availableMods = Array.Empty<ModState>();
@ -62,149 +56,29 @@ namespace osu.Game.Overlays.Mods
}
}
/// <summary>
/// Determines whether this column should accept user input.
/// </summary>
public Bindable<bool> Active = new BindableBool(true);
protected override bool ReceivePositionalInputAtSubTree(Vector2 screenSpacePos) => base.ReceivePositionalInputAtSubTree(screenSpacePos) && Active.Value;
protected virtual ModPanel CreateModPanel(ModState mod) => new ModPanel(mod);
private readonly bool allowIncompatibleSelection;
private readonly TextFlowContainer headerText;
private readonly Box headerBackground;
private readonly Container contentContainer;
private readonly Box contentBackground;
private readonly FillFlowContainer<ModPanel> panelFlow;
private readonly ToggleAllCheckbox? toggleAllCheckbox;
private Colour4 accentColour;
private Bindable<ModSelectHotkeyStyle> hotkeyStyle = null!;
private IModHotkeyHandler hotkeyHandler = null!;
private Task? latestLoadTask;
internal bool ItemsLoaded => latestLoadTask == null;
private const float header_height = 42;
public ModColumn(ModType modType, bool allowIncompatibleSelection)
{
ModType = modType;
this.allowIncompatibleSelection = allowIncompatibleSelection;
Width = 320;
RelativeSizeAxes = Axes.Y;
Shear = new Vector2(ShearedOverlayContainer.SHEAR, 0);
Container controlContainer;
InternalChildren = new Drawable[]
{
TopLevelContent = new Container
{
RelativeSizeAxes = Axes.Both,
CornerRadius = ModSelectPanel.CORNER_RADIUS,
Masking = true,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = header_height + ModSelectPanel.CORNER_RADIUS,
Children = new Drawable[]
{
headerBackground = new Box
{
RelativeSizeAxes = Axes.X,
Height = header_height + ModSelectPanel.CORNER_RADIUS
},
headerText = new OsuTextFlowContainer(t =>
{
t.Font = OsuFont.TorusAlternate.With(size: 17);
t.Shadow = false;
t.Colour = Colour4.Black;
})
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0),
Padding = new MarginPadding
{
Horizontal = 17,
Bottom = ModSelectPanel.CORNER_RADIUS
}
}
}
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = header_height },
Child = contentContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = ModSelectPanel.CORNER_RADIUS,
BorderThickness = 3,
Children = new Drawable[]
{
contentBackground = new Box
{
RelativeSizeAxes = Axes.Both
},
new GridContainer
{
RelativeSizeAxes = Axes.Both,
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension()
},
Content = new[]
{
new Drawable[]
{
controlContainer = new Container
{
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding { Horizontal = 14 }
}
},
new Drawable[]
{
new OsuScrollContainer(Direction.Vertical)
{
RelativeSizeAxes = Axes.Both,
ClampExtension = 100,
ScrollbarOverlapsContent = false,
Child = panelFlow = new FillFlowContainer<ModPanel>
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0, 7),
Padding = new MarginPadding(7)
}
}
}
}
}
}
}
}
}
}
};
createHeaderText();
HeaderText = ModType.Humanize(LetterCasing.Title);
if (allowIncompatibleSelection)
{
controlContainer.Height = 35;
controlContainer.Add(toggleAllCheckbox = new ToggleAllCheckbox(this)
ControlContainer.Height = 35;
ControlContainer.Add(toggleAllCheckbox = new ToggleAllCheckbox(this)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
@ -212,7 +86,7 @@ namespace osu.Game.Overlays.Mods
RelativeSizeAxes = Axes.X,
Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0)
});
panelFlow.Padding = new MarginPadding
ItemsFlow.Padding = new MarginPadding
{
Top = 0,
Bottom = 7,
@ -221,33 +95,17 @@ namespace osu.Game.Overlays.Mods
}
}
private void createHeaderText()
{
IEnumerable<string> headerTextWords = ModType.Humanize(LetterCasing.Title).Split(' ');
if (headerTextWords.Count() > 1)
{
headerText.AddText($"{headerTextWords.First()} ", t => t.Font = t.Font.With(weight: FontWeight.SemiBold));
headerTextWords = headerTextWords.Skip(1);
}
headerText.AddText(string.Join(' ', headerTextWords));
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider, OsuColour colours, OsuConfigManager configManager)
private void load(OsuColour colours, OsuConfigManager configManager)
{
headerBackground.Colour = accentColour = colours.ForModType(ModType);
AccentColour = colours.ForModType(ModType);
if (toggleAllCheckbox != null)
{
toggleAllCheckbox.AccentColour = accentColour;
toggleAllCheckbox.AccentHoverColour = accentColour.Lighten(0.3f);
toggleAllCheckbox.AccentColour = AccentColour;
toggleAllCheckbox.AccentHoverColour = AccentColour.Lighten(0.3f);
}
contentContainer.BorderColour = ColourInfo.GradientVertical(colourProvider.Background4, colourProvider.Background3);
contentBackground.Colour = colourProvider.Background4;
hotkeyStyle = configManager.GetBindable<ModSelectHotkeyStyle>(OsuSetting.ModSelectHotkeyStyle);
}
@ -278,7 +136,7 @@ namespace osu.Game.Overlays.Mods
latestLoadTask = loadTask = LoadComponentsAsync(panels, loaded =>
{
panelFlow.ChildrenEnumerable = loaded;
ItemsFlow.ChildrenEnumerable = loaded;
updateState();
}, (cancellationTokenSource = new CancellationTokenSource()).Token);
loadTask.ContinueWith(_ =>

View File

@ -0,0 +1,77 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Localisation;
using osu.Game.Rulesets.Mods;
using osuTK;
namespace osu.Game.Overlays.Mods
{
public class ModPresetColumn : ModSelectColumn
{
private IReadOnlyList<ModPreset> presets = Array.Empty<ModPreset>();
/// <summary>
/// Sets the collection of available mod presets.
/// </summary>
public IReadOnlyList<ModPreset> Presets
{
get => presets;
set
{
presets = value;
if (IsLoaded)
asyncLoadPanels();
}
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AccentColour = colours.Orange1;
HeaderText = ModSelectOverlayStrings.PersonalPresets;
}
protected override void LoadComplete()
{
base.LoadComplete();
asyncLoadPanels();
}
private CancellationTokenSource? cancellationTokenSource;
private Task? latestLoadTask;
internal bool ItemsLoaded => latestLoadTask == null;
private void asyncLoadPanels()
{
cancellationTokenSource?.Cancel();
var panels = presets.Select(preset => new ModPresetPanel(preset)
{
Shear = Vector2.Zero
});
Task? loadTask;
latestLoadTask = loadTask = LoadComponentsAsync(panels, loaded =>
{
ItemsFlow.ChildrenEnumerable = loaded;
}, (cancellationTokenSource = new CancellationTokenSource()).Token);
loadTask.ContinueWith(_ =>
{
if (loadTask == latestLoadTask)
latestLoadTask = null;
});
}
}
}

View File

@ -0,0 +1,177 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.Mods
{
public abstract class ModSelectColumn : CompositeDrawable, IHasAccentColour
{
public readonly Container TopLevelContent;
public LocalisableString HeaderText
{
set => createHeaderText(value);
}
public Color4 AccentColour
{
get => headerBackground.Colour;
set => headerBackground.Colour = value;
}
/// <summary>
/// Determines whether this column should accept user input.
/// </summary>
public readonly Bindable<bool> Active = new BindableBool(true);
protected override bool ReceivePositionalInputAtSubTree(Vector2 screenSpacePos) => base.ReceivePositionalInputAtSubTree(screenSpacePos) && Active.Value;
protected readonly Container ControlContainer;
protected readonly FillFlowContainer ItemsFlow;
private readonly TextFlowContainer headerText;
private readonly Box headerBackground;
private readonly Container contentContainer;
private readonly Box contentBackground;
private const float header_height = 42;
protected ModSelectColumn()
{
Width = 320;
RelativeSizeAxes = Axes.Y;
Shear = new Vector2(ShearedOverlayContainer.SHEAR, 0);
InternalChildren = new Drawable[]
{
TopLevelContent = new Container
{
RelativeSizeAxes = Axes.Both,
CornerRadius = ModSelectPanel.CORNER_RADIUS,
Masking = true,
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
Height = header_height + ModSelectPanel.CORNER_RADIUS,
Children = new Drawable[]
{
headerBackground = new Box
{
RelativeSizeAxes = Axes.X,
Height = header_height + ModSelectPanel.CORNER_RADIUS
},
headerText = new OsuTextFlowContainer(t =>
{
t.Font = OsuFont.TorusAlternate.With(size: 17);
t.Shadow = false;
t.Colour = Colour4.Black;
})
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0),
Padding = new MarginPadding
{
Horizontal = 17,
Bottom = ModSelectPanel.CORNER_RADIUS
}
}
}
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = header_height },
Child = contentContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = ModSelectPanel.CORNER_RADIUS,
BorderThickness = 3,
Children = new Drawable[]
{
contentBackground = new Box
{
RelativeSizeAxes = Axes.Both
},
new GridContainer
{
RelativeSizeAxes = Axes.Both,
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension()
},
Content = new[]
{
new Drawable[]
{
ControlContainer = new Container
{
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding { Horizontal = 14 }
}
},
new Drawable[]
{
new OsuScrollContainer(Direction.Vertical)
{
RelativeSizeAxes = Axes.Both,
ClampExtension = 100,
ScrollbarOverlapsContent = false,
Child = ItemsFlow = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0, 7),
Padding = new MarginPadding(7)
}
}
}
}
}
}
}
}
}
}
};
}
private void createHeaderText(LocalisableString text)
{
headerText.Clear();
int wordIndex = 0;
headerText.AddText(text, t =>
{
if (wordIndex == 0)
t.Font = t.Font.With(weight: FontWeight.SemiBold);
wordIndex += 1;
});
}
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
contentContainer.BorderColour = ColourInfo.GradientVertical(colourProvider.Background4, colourProvider.Background3);
contentBackground.Colour = colourProvider.Background4;
}
}
}

View File

@ -70,6 +70,7 @@ namespace osu.Game.Screens.Play
{
ScoreInfo =
{
BeatmapInfo = beatmap.BeatmapInfo,
Ruleset = ruleset.RulesetInfo
}
};