1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-25 06:20:02 +08:00

Merge pull request #36193 from frenzibyte/new-settings/overlay

Update settings to use new "form" style controls
This commit is contained in:
Dean Herbert
2026-01-22 20:27:16 +09:00
committed by GitHub
Unverified
69 changed files with 1293 additions and 926 deletions
@@ -7,7 +7,7 @@ using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Mania.Configuration;
@@ -31,47 +31,45 @@ namespace osu.Game.Rulesets.Mania
Children = new Drawable[]
{
new SettingsEnumDropdown<ManiaScrollingDirection>
new SettingsItemV2(new FormEnumDropdown<ManiaScrollingDirection>
{
LabelText = RulesetSettingsStrings.ScrollingDirection,
Caption = RulesetSettingsStrings.ScrollingDirection,
Current = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection)
},
new SettingsSlider<double, ManiaScrollSlider>
}),
new SettingsItemV2(new FormSliderBar<double>
{
LabelText = RulesetSettingsStrings.ScrollSpeed,
Caption = RulesetSettingsStrings.ScrollSpeed,
Current = config.GetBindable<double>(ManiaRulesetSetting.ScrollSpeed),
KeyboardStep = 1
},
new SettingsCheckbox
KeyboardStep = 1,
LabelFormat = v => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(v), v),
}),
new SettingsItemV2(new FormCheckBox
{
Caption = RulesetSettingsStrings.TimingBasedColouring,
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
})
{
Keywords = new[] { "color" },
LabelText = RulesetSettingsStrings.TimingBasedColouring,
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
},
};
Add(new SettingsCheckbox
Add(new SettingsItemV2(new FormCheckBox
{
LabelText = RulesetSettingsStrings.TouchOverlay,
Caption = RulesetSettingsStrings.TouchOverlay,
Current = config.GetBindable<bool>(ManiaRulesetSetting.TouchOverlay)
});
}));
if (RuntimeInfo.IsMobile)
{
Add(new SettingsEnumDropdown<ManiaMobileLayout>
Add(new SettingsItemV2(new FormEnumDropdown<ManiaMobileLayout>
{
LabelText = RulesetSettingsStrings.MobileLayout,
Caption = RulesetSettingsStrings.MobileLayout,
Current = config.GetBindable<ManiaMobileLayout>(ManiaRulesetSetting.MobileLayout),
#pragma warning disable CS0618 // Type or member is obsolete
Items = Enum.GetValues<ManiaMobileLayout>().Where(l => l != ManiaMobileLayout.LandscapeWithOverlay),
#pragma warning restore CS0618 // Type or member is obsolete
});
}));
}
}
private partial class ManiaScrollSlider : RoundedSliderBar<double>
{
public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(Current.Value), Current.Value);
}
}
}
@@ -3,7 +3,9 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Osu.Configuration;
@@ -27,32 +29,34 @@ namespace osu.Game.Rulesets.Osu.UI
Children = new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = RulesetSettingsStrings.SnakingInSliders,
Caption = RulesetSettingsStrings.SnakingInSliders,
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingInSliders)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
ClassicDefault = false,
LabelText = RulesetSettingsStrings.SnakingOutSliders,
Caption = RulesetSettingsStrings.SnakingOutSliders,
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
},
new SettingsCheckbox
})
{
LabelText = RulesetSettingsStrings.CursorTrail,
ApplyClassicDefault = c => ((IHasCurrentValue<bool>)c).Current.Value = false,
},
new SettingsItemV2(new FormCheckBox
{
Caption = RulesetSettingsStrings.CursorTrail,
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorTrail)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = RulesetSettingsStrings.CursorRipples,
Caption = RulesetSettingsStrings.CursorRipples,
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorRipples)
},
new SettingsEnumDropdown<PlayfieldBorderStyle>
}),
new SettingsItemV2(new FormEnumDropdown<PlayfieldBorderStyle>
{
LabelText = RulesetSettingsStrings.PlayfieldBorderStyle,
Caption = RulesetSettingsStrings.PlayfieldBorderStyle,
Current = config.GetBindable<PlayfieldBorderStyle>(OsuRulesetSetting.PlayfieldBorderStyle),
},
}),
};
}
}
@@ -4,6 +4,7 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Taiko.Configuration;
@@ -26,11 +27,11 @@ namespace osu.Game.Rulesets.Taiko
Children = new Drawable[]
{
new SettingsEnumDropdown<TaikoTouchControlScheme>
new SettingsItemV2(new FormEnumDropdown<TaikoTouchControlScheme>
{
LabelText = RulesetSettingsStrings.TouchControlScheme,
Caption = RulesetSettingsStrings.TouchControlScheme,
Current = config.GetBindable<TaikoTouchControlScheme>(TaikoRulesetSetting.TouchControlScheme)
}
})
};
}
}
@@ -11,6 +11,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Overlays;
using osu.Game.Overlays.Settings.Sections.Audio;
using osu.Game.Scoring;
using osu.Game.Tests.Visual.Ranking;
@@ -25,6 +26,9 @@ namespace osu.Game.Tests.Visual.Settings
[Cached]
private SessionAverageHitErrorTracker tracker = new SessionAverageHitErrorTracker();
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
private Container content = null!;
protected override Container Content => content;
@@ -13,6 +13,7 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays;
using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections.Input;
using osu.Game.Rulesets.Taiko;
using osuTK.Input;
@@ -202,16 +203,16 @@ namespace osu.Game.Tests.Visual.Settings
InputManager.ReleaseKey(Key.P);
});
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha > 0);
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<SettingsRevertToDefaultButton>().First().Alpha > 0);
AddStep("click reset button for bindings", () =>
{
var resetButton = settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First();
var resetButton = settingsKeyBindingRow.ChildrenOfType<SettingsRevertToDefaultButton>().First();
resetButton.TriggerClick();
});
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha == 0);
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<SettingsRevertToDefaultButton>().First().Alpha == 0);
AddAssert("binding cleared",
() => settingsKeyBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(0).KeyBinding.Value.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0)));
@@ -232,7 +233,7 @@ namespace osu.Game.Tests.Visual.Settings
InputManager.ReleaseKey(Key.P);
});
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha > 0);
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<SettingsRevertToDefaultButton>().First().Alpha > 0);
AddStep("click reset button for bindings", () =>
{
@@ -241,7 +242,7 @@ namespace osu.Game.Tests.Visual.Settings
resetButton.TriggerClick();
});
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha == 0);
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<SettingsRevertToDefaultButton>().First().Alpha == 0);
AddAssert("binding cleared",
() => settingsKeyBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(0).KeyBinding.Value.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0)));
@@ -394,7 +395,7 @@ namespace osu.Game.Tests.Visual.Settings
AddStep("reset Left (centre) to default", () =>
{
var row = panel.ChildrenOfType<KeyBindingRow>().First(r => r.ChildrenOfType<OsuSpriteText>().Any(s => s.Text.ToString() == "Left (centre)"));
row.ChildrenOfType<RevertToDefaultButton<bool>>().Single().TriggerClick();
row.ChildrenOfType<SettingsRevertToDefaultButton>().Single().TriggerClick();
});
KeyBindingConflictPopover popover = null;
@@ -450,7 +451,7 @@ namespace osu.Game.Tests.Visual.Settings
AddStep("revert row to default", () =>
{
var row = panel.ChildrenOfType<KeyBindingRow>().First(r => r.ChildrenOfType<OsuSpriteText>().Any(s => s.Text.ToString() == "Left (centre)"));
InputManager.MoveMouseTo(row.ChildrenOfType<RevertToDefaultButton<bool>>().Single());
InputManager.MoveMouseTo(row.ChildrenOfType<SettingsRevertToDefaultButton>().Single());
InputManager.Click(MouseButton.Left);
});
AddWaitStep("wait a bit", 3);
@@ -10,6 +10,7 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Testing;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections.Input;
namespace osu.Game.Tests.Visual.Settings
@@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual.Settings
row.KeyBindings.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.Escape)));
row.KeyBindings.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.ExtraMouseButton1)));
});
AddUntilStep("revert to default button not shown", () => row.ChildrenOfType<RevertToDefaultButton<bool>>().Single().Alpha, () => Is.Zero);
AddUntilStep("revert to default button not shown", () => row.ChildrenOfType<SettingsRevertToDefaultButton>().Single().Alpha, () => Is.Zero);
AddStep("change key bindings", () =>
{
@@ -54,7 +55,7 @@ namespace osu.Game.Tests.Visual.Settings
row.KeyBindings.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.Z)));
row.KeyBindings.Add(new RealmKeyBinding(GlobalAction.Back, new KeyCombination(InputKey.I)));
});
AddUntilStep("revert to default button not shown", () => row.ChildrenOfType<RevertToDefaultButton<bool>>().Single().Alpha, () => Is.Not.Zero);
AddUntilStep("revert to default button not shown", () => row.ChildrenOfType<SettingsRevertToDefaultButton>().Single().Alpha, () => Is.Not.Zero);
}
}
}
@@ -10,6 +10,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
@@ -31,7 +32,6 @@ namespace osu.Game.Tests.Visual.Settings
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
private FormSliderBar<float> sliderBar = null!;
private FormSliderBar<float> classicSliderBar = null!;
private SearchContainer searchContainer = null!;
@@ -173,7 +173,7 @@ namespace osu.Game.Tests.Visual.Settings
{
ShowRevertToDefaultButton = false
},
new SettingsItemV2(classicSliderBar = new FormSliderBar<float>
new SettingsItemV2(new FormSliderBar<float>
{
Caption = "Slider with classic default",
Current = new BindableFloat
@@ -185,7 +185,7 @@ namespace osu.Game.Tests.Visual.Settings
},
})
{
ApplyClassicDefault = () => classicSliderBar.Current.Value = 2,
ApplyClassicDefault = c => ((IHasCurrentValue<float>)c).Current.Value = 2,
},
},
},
@@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Handlers;
using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Testing;
using osu.Framework.Utils;
@@ -69,7 +70,7 @@ namespace osu.Game.Tests.Visual.Settings
{
AddStep("Test with wide tablet", () => tabletHandler.SetTabletSize(new Vector2(160, 100)));
AddStep("Reset to full area", () => settings.ChildrenOfType<DangerousSettingsButton>().First().TriggerClick());
AddStep("Reset to full area", () => settings.ChildrenOfType<DangerousSettingsButtonV2>().First().TriggerClick());
ensureValid();
AddStep("rotate 10", () => tabletHandler.Rotation.Value = 10);
@@ -129,7 +130,7 @@ namespace osu.Game.Tests.Visual.Settings
private void ensureInvalid() => AddAssert("area invalid", () => !settings.AreaSelection.IsWithinBounds);
public class TestTabletHandler : ITabletHandler
public class TestTabletHandler : InputHandler, ITabletHandler
{
public Bindable<Vector2> AreaOffset { get; } = new Bindable<Vector2>();
public Bindable<Vector2> AreaSize { get; } = new Bindable<Vector2>();
@@ -149,7 +150,7 @@ namespace osu.Game.Tests.Visual.Settings
private readonly Bindable<TabletInfo> tablet = new Bindable<TabletInfo>();
public BindableBool Enabled { get; } = new BindableBool(true);
public override bool IsActive => true;
public void SetTabletSize(Vector2 size)
{
@@ -389,6 +389,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
SortBy(SortMode.Artist);
checkMatchedBeatmaps(6);
AddUntilStep("wait for spread indicator", () => this.ChildrenOfType<PanelBeatmapStandalone.SpreadDisplay>().Any(d => d.Enabled.Value));
AddStep("click spread indicator", () => this.ChildrenOfType<PanelBeatmapSet.SpreadDisplay>().Single(d => d.Enabled.Value).TriggerClick());
WaitForFiltering();
checkMatchedBeatmaps(3);
@@ -412,6 +413,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
WaitForFiltering();
checkMatchedBeatmaps(3);
AddUntilStep("wait for spread indicator", () => this.ChildrenOfType<PanelBeatmapStandalone.SpreadDisplay>().Any(d => d.Enabled.Value));
AddStep("click spread indicator", () => this.ChildrenOfType<PanelBeatmapSet.SpreadDisplay>().Single(d => d.Enabled.Value).TriggerClick());
WaitForFiltering();
checkMatchedBeatmaps(3);
@@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
AddStep("Move cursor to button", () => InputManager.MoveMouseTo(settingsButton));
AddAssert("Button is hovered", () => settingsButton.IsHovered);
AddStep("Move cursor to padded area", () => InputManager.MoveMouseTo(settingsButton.ScreenSpaceDrawQuad.TopLeft + new Vector2(SettingsPanel.CONTENT_MARGINS / 2f, 10)));
AddStep("Move cursor to padded area", () => InputManager.MoveMouseTo(settingsButton.ScreenSpaceDrawQuad.TopLeft + new Vector2(SettingsPanel.CONTENT_PADDING.Left / 2f, 10)));
AddAssert("Cursor within a button", () => settingsButton.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position));
AddAssert("Button is not hovered", () => !settingsButton.IsHovered);
}
@@ -30,7 +30,11 @@ namespace osu.Game.Graphics.UserInterfaceV2
/// <summary>
/// Hint text containing an extended description of this slider bar, displayed in a tooltip when hovering the caption.
/// </summary>
public LocalisableString HintText { get; init; }
public LocalisableString HintText
{
get => header.HintText;
set => header.HintText = value;
}
/// <summary>
/// The maximum height of the dropdown's menu.
@@ -108,7 +108,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
/// <summary>
/// Whether sound effects should play when adjusting this slider.
/// </summary>
public bool PlaySamplesOnAdjust { get; init; }
public bool PlaySamplesOnAdjust { get; init; } = true;
/// <summary>
/// The string formatting function to use for the value label.
@@ -418,7 +418,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
private LocalisableString defaultLabelFormat(T value) => currentNumberInstantaneous.Value.ToStandardFormattedString(OsuSliderBar<T>.MAX_DECIMAL_DIGITS, DisplayAsPercentage);
private partial class InnerSlider : OsuSliderBar<T>
public partial class InnerSlider : OsuSliderBar<T>
{
public BindableBool Focused { get; } = new BindableBool();
@@ -51,7 +51,6 @@ namespace osu.Game.Graphics.UserInterfaceV2
{
RelativeSizeAxes = Axes.Both,
AlwaysPresent = true,
Alpha = 0
},
new Container
{
@@ -92,7 +91,6 @@ namespace osu.Game.Graphics.UserInterfaceV2
private void updateState()
{
nub.MoveToX(Current.Value ? nubContainer.DrawWidth - nub.DrawWidth : 0, 200, Easing.OutQuint);
fill.FadeTo(Current.Value ? 1 : 0, 250, Easing.OutQuint);
updateColours();
}
@@ -112,7 +110,11 @@ namespace osu.Game.Graphics.UserInterfaceV2
protected override void OnUserChange(bool value)
{
base.OnUserChange(value);
PlaySample(value);
}
public void PlaySample(bool value)
{
if (value)
sampleChecked?.Play();
else
@@ -135,7 +137,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
bool hover = IsHovered && !Current.Disabled;
borderColour = hover ? colourProvider.Highlight1.Opacity(0.5f) : colourProvider.Highlight1.Opacity(0.3f);
switchColour = hover ? colourProvider.Highlight1 : colourProvider.Light4;
switchColour = hover || Current.Value ? colourProvider.Highlight1 : colourProvider.Light4;
if (!Current.Value)
{
@@ -143,7 +145,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
switchColour = switchColour.MultiplyAlpha(0.8f);
}
fill.Colour = colourProvider.Background6;
fill.Colour = Current.Value ? colourProvider.Colour4.Darken(0.2f) : colourProvider.Background6;
}
nubContainer.FadeColour(switchColour, 250, Easing.OutQuint);
@@ -120,9 +120,9 @@ namespace osu.Game.Localisation
public static LocalisableString ModsHeader => new TranslatableString(getKey(@"mods_header"), @"Mods");
/// <summary>
/// "Increase visibility of first object when visual impairment mods are enabled"
/// "Increase first object visibility on visual impairment mods"
/// </summary>
public static LocalisableString IncreaseFirstObjectVisibility => new TranslatableString(getKey(@"increase_first_object_visibility"), @"Increase visibility of first object when visual impairment mods are enabled");
public static LocalisableString IncreaseFirstObjectVisibility => new TranslatableString(getKey(@"increase_first_object_visibility"), @"Increase first object visibility on visual impairment mods");
/// <summary>
/// "Hide during gameplay"
+1 -1
View File
@@ -625,7 +625,7 @@ namespace osu.Game
return new TouchSettings(th);
case MidiHandler:
return new InputSection.HandlerSection(handler);
return new InputSubsection(handler);
// return null for handlers that shouldn't have settings.
default:
@@ -0,0 +1,20 @@
// 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.Game.Graphics;
namespace osu.Game.Overlays.Settings
{
/// <summary>
/// A <see cref="SettingsButtonV2"/> with pink colours to mark dangerous/destructive actions.
/// </summary>
public partial class DangerousSettingsButtonV2 : SettingsButtonV2
{
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.DangerousButtonColour;
}
}
}
@@ -7,9 +7,10 @@ using osu.Framework.Graphics;
using System.Collections.Generic;
using System.Linq;
using osu.Framework;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Audio
@@ -21,30 +22,37 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
[Resolved]
private AudioManager audio { get; set; } = null!;
private SettingsDropdown<string> dropdown = null!;
private AudioDeviceDropdown dropdown = null!;
private SettingsCheckbox? wasapiExperimental;
private FormCheckBox? wasapiExperimental;
private readonly Bindable<SettingsNote.Data?> wasapiExperimentalNote = new Bindable<SettingsNote.Data?>();
[BackgroundDependencyLoader]
private void load()
{
Children = new Drawable[]
{
dropdown = new AudioDeviceSettingsDropdown
new SettingsItemV2(dropdown = new AudioDeviceDropdown
{
Caption = AudioSettingsStrings.OutputDevice,
})
{
LabelText = AudioSettingsStrings.OutputDevice,
Keywords = new[] { "speaker", "headphone", "output" }
},
};
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
{
Add(wasapiExperimental = new SettingsCheckbox
Add(new SettingsItemV2(wasapiExperimental = new FormCheckBox
{
LabelText = AudioSettingsStrings.WasapiLabel,
TooltipText = AudioSettingsStrings.WasapiTooltip,
Caption = AudioSettingsStrings.WasapiLabel,
HintText = AudioSettingsStrings.WasapiTooltip,
Current = audio.UseExperimentalWasapi,
Keywords = new[] { "wasapi", "latency", "exclusive" }
})
{
Keywords = new[] { "wasapi", "latency", "exclusive" },
Note = { BindTarget = wasapiExperimentalNote },
});
wasapiExperimental.Current.ValueChanged += _ => onDeviceChanged(string.Empty);
@@ -64,9 +72,9 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
if (wasapiExperimental != null)
{
if (wasapiExperimental.Current.Value)
wasapiExperimental.SetNoticeText(AudioSettingsStrings.WasapiNotice, true);
wasapiExperimentalNote.Value = new SettingsNote.Data(AudioSettingsStrings.WasapiNotice, SettingsNote.Type.Warning);
else
wasapiExperimental.ClearNoticeText();
wasapiExperimentalNote.Value = null;
}
}
@@ -103,15 +111,10 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
}
}
private partial class AudioDeviceSettingsDropdown : SettingsDropdown<string>
private partial class AudioDeviceDropdown : FormDropdown<string>
{
protected override OsuDropdown<string> CreateDropdown() => new AudioDeviceDropdownControl();
private partial class AudioDeviceDropdownControl : DropdownControl
{
protected override LocalisableString GenerateItemText(string item)
=> string.IsNullOrEmpty(item) ? CommonStrings.Default : base.GenerateItemText(item);
}
protected override LocalisableString GenerateItemText(string item)
=> string.IsNullOrEmpty(item) ? CommonStrings.Default : base.GenerateItemText(item);
}
}
}
@@ -11,171 +11,173 @@ using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Screens.Play.PlayerSettings;
using osuTK;
namespace osu.Game.Overlays.Settings.Sections.Audio
{
public partial class AudioOffsetAdjustControl : SettingsItem<double>
public partial class AudioOffsetAdjustControl : CompositeDrawable
{
public IBindable<double?> SuggestedOffset => ((AudioOffsetPreview)Control).SuggestedOffset;
[BackgroundDependencyLoader]
private void load()
public Bindable<double> Current
{
LabelText = AudioSettingsStrings.AudioOffset;
get => current.Current;
set => current.Current = value;
}
protected override Drawable CreateControl() => new AudioOffsetPreview();
private readonly BindableNumberWithCurrent<double> current = new BindableNumberWithCurrent<double>();
private partial class AudioOffsetPreview : CompositeDrawable, IHasCurrentValue<double>
private readonly IBindableList<SessionAverageHitErrorTracker.DataPoint> averageHitErrorHistory = new BindableList<SessionAverageHitErrorTracker.DataPoint>();
public readonly Bindable<double?> SuggestedOffset = new Bindable<double?>();
private Container<Circle> notchContainer = null!;
private SettingsNote hintNote = null!;
private RoundedButton applySuggestion = null!;
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
[BackgroundDependencyLoader]
private void load(SessionAverageHitErrorTracker hitErrorTracker)
{
public Bindable<double> Current
averageHitErrorHistory.BindTo(hitErrorTracker.AverageHitErrorHistory);
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
InternalChild = new FillFlowContainer
{
get => current.Current;
set => current.Current = value;
}
private readonly BindableNumberWithCurrent<double> current = new BindableNumberWithCurrent<double>();
private readonly IBindableList<SessionAverageHitErrorTracker.DataPoint> averageHitErrorHistory = new BindableList<SessionAverageHitErrorTracker.DataPoint>();
public readonly Bindable<double?> SuggestedOffset = new Bindable<double?>();
private Container<Box> notchContainer = null!;
private TextFlowContainer hintText = null!;
private RoundedButton applySuggestion = null!;
[BackgroundDependencyLoader]
private void load(SessionAverageHitErrorTracker hitErrorTracker)
{
averageHitErrorHistory.BindTo(hitErrorTracker.AverageHitErrorHistory);
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
InternalChild = new FillFlowContainer
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(10),
Direction = FillDirection.Vertical,
Children = new Drawable[]
new SettingsItemV2(new FormSliderBar<double>
{
new OffsetSliderBar
Caption = AudioSettingsStrings.AudioOffset,
RelativeSizeAxes = Axes.X,
Current = { BindTarget = Current },
KeyboardStep = 1,
LabelFormat = v => $"{v:N0} ms",
TooltipFormat = BeatmapOffsetControl.GetOffsetExplanatoryText,
}),
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding
{
RelativeSizeAxes = Axes.X,
Current = { BindTarget = Current },
KeyboardStep = 1,
Left = SettingsPanel.CONTENT_PADDING.Left + 9,
Right = SettingsPanel.CONTENT_PADDING.Right + 5
},
notchContainer = new Container<Box>
Child = notchContainer = new Container<Circle>
{
RelativeSizeAxes = Axes.X,
Width = 0.5f,
Height = 10,
Padding = new MarginPadding { Horizontal = Nub.DEFAULT_EXPANDED_SIZE / 2 },
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
},
hintText = new OsuTextFlowContainer(t => t.Font = OsuFont.Default.With(size: 16))
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
},
applySuggestion = new RoundedButton
{
RelativeSizeAxes = Axes.X,
Text = AudioSettingsStrings.ApplySuggestedOffset,
Action = () =>
Margin = new MarginPadding { Top = 2 },
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Padding = new MarginPadding
{
if (SuggestedOffset.Value.HasValue)
current.Value = SuggestedOffset.Value.Value;
hitErrorTracker.ClearHistory();
}
Horizontal = FormSliderBar<double>.InnerSlider.NUB_WIDTH / 2
},
},
},
hintNote = new SettingsNote
{
RelativeSizeAxes = Axes.X,
Padding = SettingsPanel.CONTENT_PADDING,
TextAnchor = Anchor.TopCentre,
},
applySuggestion = new RoundedButton
{
RelativeSizeAxes = Axes.X,
Text = AudioSettingsStrings.ApplySuggestedOffset,
Padding = SettingsPanel.CONTENT_PADDING,
Action = () =>
{
if (SuggestedOffset.Value.HasValue)
current.Value = SuggestedOffset.Value.Value;
hitErrorTracker.ClearHistory();
}
}
};
}
}
};
}
protected override void LoadComplete()
protected override void LoadComplete()
{
base.LoadComplete();
averageHitErrorHistory.BindCollectionChanged(updateDisplay, true);
current.BindValueChanged(_ => updateHintText());
SuggestedOffset.BindValueChanged(_ => updateHintText(), true);
}
private void updateDisplay(object? _, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
base.LoadComplete();
averageHitErrorHistory.BindCollectionChanged(updateDisplay, true);
current.BindValueChanged(_ => updateHintText());
SuggestedOffset.BindValueChanged(_ => updateHintText(), true);
}
private void updateDisplay(object? _, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (SessionAverageHitErrorTracker.DataPoint dataPoint in e.NewItems!)
case NotifyCollectionChangedAction.Add:
foreach (SessionAverageHitErrorTracker.DataPoint dataPoint in e.NewItems!)
{
notchContainer.ForEach(n => n.Alpha *= 0.95f);
notchContainer.Add(new Circle
{
notchContainer.ForEach(n => n.Alpha *= 0.95f);
notchContainer.Add(new Box
{
RelativeSizeAxes = Axes.Y,
Width = 2,
RelativePositionAxes = Axes.X,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
X = getXPositionForOffset(dataPoint.SuggestedGlobalAudioOffset)
});
}
RelativeSizeAxes = Axes.Y,
Width = 2,
RelativePositionAxes = Axes.X,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = colourProvider.Light1,
X = getXPositionForOffset(dataPoint.SuggestedGlobalAudioOffset)
});
}
break;
break;
case NotifyCollectionChangedAction.Remove:
foreach (SessionAverageHitErrorTracker.DataPoint dataPoint in e.OldItems!)
{
var notch = notchContainer.FirstOrDefault(n => n.X == getXPositionForOffset(dataPoint.SuggestedGlobalAudioOffset));
Debug.Assert(notch != null);
notchContainer.Remove(notch, true);
}
case NotifyCollectionChangedAction.Remove:
foreach (SessionAverageHitErrorTracker.DataPoint dataPoint in e.OldItems!)
{
var notch = notchContainer.FirstOrDefault(n => n.X == getXPositionForOffset(dataPoint.SuggestedGlobalAudioOffset));
Debug.Assert(notch != null);
notchContainer.Remove(notch, true);
}
break;
break;
case NotifyCollectionChangedAction.Reset:
notchContainer.Clear();
break;
}
SuggestedOffset.Value = averageHitErrorHistory.Any() ? Math.Round(averageHitErrorHistory.Average(dataPoint => dataPoint.SuggestedGlobalAudioOffset)) : null;
case NotifyCollectionChangedAction.Reset:
notchContainer.Clear();
break;
}
private float getXPositionForOffset(double offset) => (float)(Math.Clamp(offset, current.MinValue, current.MaxValue) / (2 * current.MaxValue));
SuggestedOffset.Value = averageHitErrorHistory.Any() ? Math.Round(averageHitErrorHistory.Average(dataPoint => dataPoint.SuggestedGlobalAudioOffset)) : null;
}
private void updateHintText()
private float getXPositionForOffset(double offset) => (float)(Math.Clamp(offset, current.MinValue, current.MaxValue) / (2 * current.MaxValue));
private void updateHintText()
{
if (SuggestedOffset.Value == null)
{
if (SuggestedOffset.Value == null)
{
applySuggestion.Enabled.Value = false;
hintText.Text = AudioSettingsStrings.SuggestedOffsetNote;
}
else if (Math.Abs(SuggestedOffset.Value.Value - current.Value) < 1)
{
applySuggestion.Enabled.Value = false;
hintText.Text = AudioSettingsStrings.SuggestedOffsetCorrect(averageHitErrorHistory.Count);
}
else
{
applySuggestion.Enabled.Value = true;
hintText.Text = AudioSettingsStrings.SuggestedOffsetValueReceived(averageHitErrorHistory.Count, SuggestedOffset.Value.Value.ToStandardFormattedString(0));
}
applySuggestion.Enabled.Value = false;
notchContainer.Hide();
hintNote.Current.Value = new SettingsNote.Data(AudioSettingsStrings.SuggestedOffsetNote, SettingsNote.Type.Informational);
}
private partial class OffsetSliderBar : RoundedSliderBar<double>
else if (Math.Abs(SuggestedOffset.Value.Value - current.Value) < 1)
{
public override LocalisableString TooltipText => BeatmapOffsetControl.GetOffsetExplanatoryText(Current.Value);
applySuggestion.Enabled.Value = false;
notchContainer.Show();
hintNote.Current.Value = new SettingsNote.Data(AudioSettingsStrings.SuggestedOffsetCorrect(averageHitErrorHistory.Count), SettingsNote.Type.Informational);
}
else
{
applySuggestion.Enabled.Value = true;
notchContainer.Show();
hintNote.Current.Value = new SettingsNote.Data(AudioSettingsStrings.SuggestedOffsetValueReceived(averageHitErrorHistory.Count, SuggestedOffset.Value.Value.ToStandardFormattedString(0)), SettingsNote.Type.Informational);
}
}
}
@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Audio
@@ -25,13 +26,14 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
new AudioOffsetAdjustControl
{
Current = config.GetBindable<double>(OsuSetting.AudioOffset),
Margin = new MarginPadding { Bottom = 5 },
},
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = AudioSettingsStrings.AdjustBeatmapOffsetAutomatically,
TooltipText = AudioSettingsStrings.AdjustBeatmapOffsetAutomaticallyTooltip,
Caption = AudioSettingsStrings.AdjustBeatmapOffsetAutomatically,
HintText = AudioSettingsStrings.AdjustBeatmapOffsetAutomaticallyTooltip,
Current = config.GetBindable<bool>(OsuSetting.AutomaticallyAdjustBeatmapOffset),
}
})
};
}
}
@@ -6,7 +6,7 @@ using osu.Framework.Audio;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Audio
@@ -20,46 +20,38 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
{
Children = new Drawable[]
{
new VolumeAdjustSlider
new SettingsItemV2(new FormSliderBar<double>
{
LabelText = AudioSettingsStrings.MasterVolume,
Caption = AudioSettingsStrings.MasterVolume,
Current = audio.Volume,
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsSlider<double>
DisplayAsPercentage = true,
PlaySamplesOnAdjust = false,
}),
new SettingsItemV2(new FormSliderBar<double>
{
LabelText = AudioSettingsStrings.MasterVolumeInactive,
Caption = AudioSettingsStrings.MasterVolumeInactive,
Current = config.GetBindable<double>(OsuSetting.VolumeInactive),
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new VolumeAdjustSlider
}),
new SettingsItemV2(new FormSliderBar<double>
{
LabelText = AudioSettingsStrings.EffectVolume,
Caption = AudioSettingsStrings.EffectVolume,
Current = audio.VolumeSample,
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new VolumeAdjustSlider
DisplayAsPercentage = true,
PlaySamplesOnAdjust = false,
}),
new SettingsItemV2(new FormSliderBar<double>
{
LabelText = AudioSettingsStrings.MusicVolume,
Caption = AudioSettingsStrings.MusicVolume,
Current = audio.VolumeTrack,
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
DisplayAsPercentage = true,
PlaySamplesOnAdjust = false,
}),
};
}
private partial class VolumeAdjustSlider : SettingsSlider<double>
{
protected override Drawable CreateControl()
{
var sliderBar = (RoundedSliderBar<double>)base.CreateControl();
sliderBar.PlaySamplesOnAdjust = false;
return sliderBar;
}
}
}
}
@@ -11,10 +11,10 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
{
protected override LocalisableString Header => @"Batch Import";
private SettingsButton importBeatmapsButton = null!;
private SettingsButton importCollectionsButton = null!;
private SettingsButton importScoresButton = null!;
private SettingsButton importSkinsButton = null!;
private SettingsButtonV2 importBeatmapsButton = null!;
private SettingsButtonV2 importCollectionsButton = null!;
private SettingsButtonV2 importScoresButton = null!;
private SettingsButtonV2 importSkinsButton = null!;
[BackgroundDependencyLoader]
private void load(LegacyImportManager? legacyImportManager)
@@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
AddRange(new[]
{
importBeatmapsButton = new SettingsButton
importBeatmapsButton = new SettingsButtonV2
{
Text = @"Import beatmaps from stable",
Action = () =>
@@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
legacyImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(_ => Schedule(() => importBeatmapsButton.Enabled.Value = true));
}
},
importSkinsButton = new SettingsButton
importSkinsButton = new SettingsButtonV2
{
Text = @"Import skins from stable",
Action = () =>
@@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
legacyImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(_ => Schedule(() => importSkinsButton.Enabled.Value = true));
}
},
importCollectionsButton = new SettingsButton
importCollectionsButton = new SettingsButtonV2
{
Text = @"Import collections from stable",
Action = () =>
@@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
legacyImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(_ => Schedule(() => importCollectionsButton.Enabled.Value = true));
}
},
importScoresButton = new SettingsButton
importScoresButton = new SettingsButtonV2
{
Text = @"Import scores from stable",
Action = () =>
@@ -4,6 +4,7 @@
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Overlays.Settings.Sections.DebugSettings
{
@@ -14,17 +15,17 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
[BackgroundDependencyLoader]
private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig)
{
Add(new SettingsCheckbox
Add(new SettingsItemV2(new FormCheckBox
{
LabelText = @"Show log overlay",
Caption = @"Show log overlay",
Current = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowLogOverlay)
});
}));
Add(new SettingsCheckbox
Add(new SettingsItemV2(new FormCheckBox
{
LabelText = @"Bypass front-to-back render pass",
Caption = @"Bypass front-to-back render pass",
Current = config.GetBindable<bool>(DebugSetting.BypassFrontToBackPass)
});
}));
}
}
}
@@ -13,6 +13,7 @@ using osu.Framework.Localisation;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.Database;
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Overlays.Settings.Sections.DebugSettings
{
@@ -23,10 +24,10 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
[BackgroundDependencyLoader]
private void load(GameHost host, RealmAccess realm)
{
SettingsButton blockAction;
SettingsButton unblockAction;
SettingsButtonV2 blockAction;
SettingsButtonV2 unblockAction;
Add(new SettingsButton
Add(new SettingsButtonV2
{
Text = @"Clear all caches",
Action = () =>
@@ -38,11 +39,11 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
}
});
SettingsEnumDropdown<GCLatencyMode> latencyModeDropdown;
Add(latencyModeDropdown = new SettingsEnumDropdown<GCLatencyMode>
FormEnumDropdown<GCLatencyMode> latencyModeDropdown;
Add(new SettingsItemV2(latencyModeDropdown = new FormEnumDropdown<GCLatencyMode>
{
LabelText = "GC mode",
});
Caption = "GC mode",
}));
latencyModeDropdown.Current.BindValueChanged(mode =>
{
@@ -65,7 +66,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
{
AddRange(new Drawable[]
{
new SettingsButton
new SettingsButtonV2
{
Text = @"Compact realm",
Action = () =>
@@ -76,11 +77,11 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
}
}
},
blockAction = new SettingsButton
blockAction = new SettingsButtonV2
{
Text = @"Block realm",
},
unblockAction = new SettingsButton
unblockAction = new SettingsButtonV2
{
Text = @"Unblock realm",
}
@@ -3,8 +3,10 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Gameplay
@@ -18,19 +20,23 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
Children = new Drawable[]
{
new SettingsSlider<float>
new SettingsItemV2(new FormSliderBar<float>
{
LabelText = AudioSettingsStrings.PositionalLevel,
Keywords = new[] { @"positional", @"balance" },
Caption = AudioSettingsStrings.PositionalLevel,
Current = osuConfig.GetBindable<float>(OsuSetting.PositionalHitsoundsLevel),
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsCheckbox
})
{
ClassicDefault = false,
LabelText = GameplaySettingsStrings.AlwaysPlayFirstComboBreak,
Keywords = new[] { @"positional", @"balance" },
},
new SettingsItemV2(new FormCheckBox
{
Caption = GameplaySettingsStrings.AlwaysPlayFirstComboBreak,
Current = config.GetBindable<bool>(OsuSetting.AlwaysPlayFirstComboBreak)
})
{
ApplyClassicDefault = c => ((IHasCurrentValue<bool>)c).Current.Value = false,
}
};
}
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Gameplay
@@ -18,31 +19,33 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
Children = new Drawable[]
{
new SettingsSlider<double>
new SettingsItemV2(new FormSliderBar<double>
{
LabelText = GameplaySettingsStrings.BackgroundDim,
Caption = GameplaySettingsStrings.BackgroundDim,
Current = config.GetBindable<double>(OsuSetting.DimLevel),
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsSlider<double>
}),
new SettingsItemV2(new FormSliderBar<double>
{
LabelText = GameplaySettingsStrings.BackgroundBlur,
Caption = GameplaySettingsStrings.BackgroundBlur,
Current = config.GetBindable<double>(OsuSetting.BlurLevel),
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.LightenDuringBreaks,
Caption = GameplaySettingsStrings.LightenDuringBreaks,
Current = config.GetBindable<bool>(OsuSetting.LightenDuringBreaks),
})
{
Keywords = new[] { "dim", "level" }
},
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.FadePlayfieldWhenHealthLow,
Caption = GameplaySettingsStrings.FadePlayfieldWhenHealthLow,
Current = config.GetBindable<bool>(OsuSetting.FadePlayfieldWhenHealthLow),
},
}),
};
}
}
@@ -6,6 +6,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Gameplay
@@ -23,35 +24,41 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
Children = new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = SkinSettingsStrings.BeatmapSkins,
Caption = SkinSettingsStrings.BeatmapSkins,
Current = config.GetBindable<bool>(OsuSetting.BeatmapSkins)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
Caption = SkinSettingsStrings.BeatmapColours,
Current = config.GetBindable<bool>(OsuSetting.BeatmapColours)
})
{
Keywords = new[] { "combo", "override", "color" },
LabelText = SkinSettingsStrings.BeatmapColours,
Current = config.GetBindable<bool>(OsuSetting.BeatmapColours)
},
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
Caption = SkinSettingsStrings.BeatmapHitsounds,
Current = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds)
})
{
Keywords = new[] { "samples", "override" },
LabelText = SkinSettingsStrings.BeatmapHitsounds,
Current = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds)
},
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = GraphicsSettingsStrings.StoryboardVideo,
Caption = GraphicsSettingsStrings.StoryboardVideo,
Current = config.GetBindable<bool>(OsuSetting.ShowStoryboard)
},
new SettingsSlider<float>
}),
new SettingsItemV2(new FormSliderBar<float>
{
Keywords = new[] { "color" },
LabelText = GraphicsSettingsStrings.ComboColourNormalisation,
Caption = GraphicsSettingsStrings.ComboColourNormalisation,
Current = comboColourNormalisation,
DisplayAsPercentage = true,
}
})
{
Keywords = new[] { "color" },
},
};
}
}
@@ -3,8 +3,10 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Rulesets.Scoring;
@@ -19,23 +21,25 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
Children = new Drawable[]
{
new SettingsEnumDropdown<ScoringMode>
new SettingsItemV2(new FormEnumDropdown<ScoringMode>
{
ClassicDefault = ScoringMode.Classic,
LabelText = GameplaySettingsStrings.ScoreDisplayMode,
Caption = GameplaySettingsStrings.ScoreDisplayMode,
Current = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode),
Keywords = new[] { "scoring" }
},
new SettingsCheckbox
})
{
LabelText = GraphicsSettingsStrings.HitLighting,
Keywords = new[] { "scoring" },
ApplyClassicDefault = c => ((IHasCurrentValue<ScoringMode>)c).Current.Value = ScoringMode.Classic,
},
new SettingsItemV2(new FormCheckBox
{
Caption = GraphicsSettingsStrings.HitLighting,
Current = config.GetBindable<bool>(OsuSetting.HitLighting)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.StarFountains,
Caption = GameplaySettingsStrings.StarFountains,
Current = config.GetBindable<bool>(OsuSetting.StarFountains)
},
}),
};
}
}
@@ -3,8 +3,10 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Gameplay
@@ -18,44 +20,50 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
Children = new Drawable[]
{
new SettingsEnumDropdown<HUDVisibilityMode>
new SettingsItemV2(new FormEnumDropdown<HUDVisibilityMode>
{
LabelText = GameplaySettingsStrings.HUDVisibilityMode,
Caption = GameplaySettingsStrings.HUDVisibilityMode,
Current = config.GetBindable<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.ShowReplaySettingsOverlay,
Caption = GameplaySettingsStrings.ShowReplaySettingsOverlay,
Current = config.GetBindable<bool>(OsuSetting.ReplaySettingsOverlay),
})
{
Keywords = new[] { "hide" },
},
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.AlwaysShowKeyOverlay,
Caption = GameplaySettingsStrings.AlwaysShowKeyOverlay,
Current = config.GetBindable<bool>(OsuSetting.KeyOverlay),
})
{
Keywords = new[] { "counter" },
},
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.AlwaysShowGameplayLeaderboard,
Caption = GameplaySettingsStrings.AlwaysShowGameplayLeaderboard,
Current = config.GetBindable<bool>(OsuSetting.GameplayLeaderboard),
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.AlwaysRequireHoldForMenu,
Caption = GameplaySettingsStrings.AlwaysRequireHoldForMenu,
Current = config.GetBindable<bool>(OsuSetting.AlwaysRequireHoldingForPause),
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.AlwaysShowHoldForMenuButton,
Caption = GameplaySettingsStrings.AlwaysShowHoldForMenuButton,
Current = config.GetBindable<bool>(OsuSetting.AlwaysShowHoldForMenuButton),
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
ClassicDefault = false,
LabelText = GameplaySettingsStrings.ShowHealthDisplayWhenCantFail,
Caption = GameplaySettingsStrings.ShowHealthDisplayWhenCantFail,
Current = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
Keywords = new[] { "hp", "bar" }
})
{
Keywords = new[] { "hp", "bar" },
ApplyClassicDefault = c => ((IHasCurrentValue<bool>)c).Current.Value = false,
},
};
}
@@ -6,6 +6,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Gameplay
@@ -19,32 +20,35 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
Children = new Drawable[]
{
new SettingsSlider<float, SizeSlider<float>>
new SettingsItemV2(new FormSliderBar<float>
{
LabelText = SkinSettingsStrings.GameplayCursorSize,
Caption = SkinSettingsStrings.GameplayCursorSize,
Current = config.GetBindable<float>(OsuSetting.GameplayCursorSize),
KeyboardStep = 0.01f
},
new SettingsCheckbox
KeyboardStep = 0.01f,
LabelFormat = v => $"{v:0.##}x"
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = SkinSettingsStrings.AutoCursorSize,
Caption = SkinSettingsStrings.AutoCursorSize,
Current = config.GetBindable<bool>(OsuSetting.AutoCursorSize)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = SkinSettingsStrings.GameplayCursorDuringTouch,
Keywords = new[] { @"touchscreen" },
Caption = SkinSettingsStrings.GameplayCursorDuringTouch,
Current = config.GetBindable<bool>(OsuSetting.GameplayCursorDuringTouch)
})
{
Keywords = new[] { @"touchscreen" },
},
};
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
{
Add(new SettingsCheckbox
Add(new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.DisableWinKey,
Caption = GameplaySettingsStrings.DisableWinKey,
Current = config.GetBindable<bool>(OsuSetting.GameplayDisableWinKey)
});
}));
}
}
}
@@ -6,6 +6,7 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Gameplay
@@ -21,10 +22,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
Children = new[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = GameplaySettingsStrings.IncreaseFirstObjectVisibility,
Caption = GameplaySettingsStrings.IncreaseFirstObjectVisibility,
Current = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility),
})
{
Keywords = new[] { @"approach", @"circle", @"hidden" },
},
};
@@ -20,14 +20,14 @@ namespace osu.Game.Overlays.Settings.Sections.General
[BackgroundDependencyLoader]
private void load(Storage storage)
{
Add(new SettingsButton
Add(new SettingsButtonV2
{
Text = GeneralSettingsStrings.OpenOsuFolder,
Keywords = new[] { @"logs", @"files", @"access", "directory" },
Action = () => storage.PresentExternally(),
});
Add(new DangerousSettingsButton
Add(new DangerousSettingsButtonV2
{
Text = GeneralSettingsStrings.ChangeFolderLocation,
Action = () => game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen()))
@@ -6,6 +6,7 @@ using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.General
@@ -19,22 +20,22 @@ namespace osu.Game.Overlays.Settings.Sections.General
{
Children = new Drawable[]
{
new SettingsEnumDropdown<Language>
new SettingsItemV2(new FormEnumDropdown<Language>
{
LabelText = GeneralSettingsStrings.LanguageDropdown,
Caption = GeneralSettingsStrings.LanguageDropdown,
Current = game.CurrentLanguage,
AlwaysShowSearchBar = true,
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GeneralSettingsStrings.PreferOriginalMetadataLanguage,
Caption = GeneralSettingsStrings.PreferOriginalMetadataLanguage,
Current = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowUnicode)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GeneralSettingsStrings.Prefer24HourTimeDisplay,
Caption = GeneralSettingsStrings.Prefer24HourTimeDisplay,
Current = config.GetBindable<bool>(OsuSetting.Prefer24HourTime)
},
}),
};
}
}
@@ -35,21 +35,21 @@ namespace osu.Game.Overlays.Settings.Sections.General
{
AddRange(new Drawable[]
{
new SettingsButton
new SettingsButtonV2
{
Text = GeneralSettingsStrings.RunSetupWizard,
Keywords = new[] { @"first run", @"initial", @"getting started", @"import", @"tutorial", @"recommended beatmaps" },
TooltipText = FirstRunSetupOverlayStrings.FirstRunSetupDescription,
Action = () => firstRunSetupOverlay?.Show(),
},
new SettingsButton
new SettingsButtonV2
{
Text = GeneralSettingsStrings.LearnMoreAboutLazer,
TooltipText = GeneralSettingsStrings.LearnMoreAboutLazerTooltip,
BackgroundColour = colours.YellowDark,
Action = () => game?.ShowWiki(@"Help_centre/Upgrading_to_lazer")
},
new SettingsButton
new SettingsButtonV2
{
Text = GeneralSettingsStrings.ReportIssue,
TooltipText = GeneralSettingsStrings.ReportIssueTooltip,
@@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
if (supportsExport)
{
Add(new SettingsButton
Add(new SettingsButtonV2
{
Text = GeneralSettingsStrings.ExportLogs,
BackgroundColour = colours.YellowDarker.Darken(0.5f),
@@ -8,6 +8,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Online.Multiplayer;
using osu.Game.Overlays.Dialog;
@@ -20,8 +21,10 @@ namespace osu.Game.Overlays.Settings.Sections.General
{
protected override LocalisableString Header => GeneralSettingsStrings.UpdateHeader;
private SettingsButton checkForUpdatesButton = null!;
private SettingsEnumDropdown<ReleaseStream> releaseStreamDropdown = null!;
private SettingsButtonV2 checkForUpdatesButton = null!;
private FormEnumDropdown<ReleaseStream> releaseStreamDropdown = null!;
private readonly Bindable<SettingsNote.Data?> releaseStreamDropdownNote = new Bindable<SettingsNote.Data?>();
private readonly Bindable<ReleaseStream> configReleaseStream = new Bindable<ReleaseStream>();
@@ -47,26 +50,28 @@ namespace osu.Game.Overlays.Settings.Sections.General
// For simplicity, hide the concept of release streams from mobile users.
if (isDesktop)
{
Add(releaseStreamDropdown = new SettingsEnumDropdown<ReleaseStream>
Add(new SettingsItemV2(releaseStreamDropdown = new FormEnumDropdown<ReleaseStream>
{
LabelText = GeneralSettingsStrings.ReleaseStream,
Caption = GeneralSettingsStrings.ReleaseStream,
Current = { Value = configReleaseStream.Value },
})
{
Keywords = new[] { @"version" },
ShowRevertToDefaultButton = updateManager!.FixedReleaseStream == null
});
if (updateManager!.FixedReleaseStream != null)
{
configReleaseStream.Value = updateManager.FixedReleaseStream.Value;
releaseStreamDropdown.ShowsDefaultIndicator = false;
releaseStreamDropdown.Items = [updateManager.FixedReleaseStream.Value];
releaseStreamDropdown.SetNoticeText(GeneralSettingsStrings.ChangeReleaseStreamPackageManagerWarning);
releaseStreamDropdownNote.Value = new SettingsNote.Data(GeneralSettingsStrings.ChangeReleaseStreamPackageManagerWarning, SettingsNote.Type.Warning);
}
releaseStreamDropdown.Current.BindValueChanged(releaseStreamChanged);
}
Add(checkForUpdatesButton = new SettingsButton
Add(checkForUpdatesButton = new SettingsButtonV2
{
Text = GeneralSettingsStrings.CheckUpdate,
Action = () => checkForUpdates().FireAndForget()
@@ -9,7 +9,6 @@ using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Configuration;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@@ -18,7 +17,7 @@ using osu.Framework.Platform;
using osu.Framework.Platform.Windows;
using osu.Game.Configuration;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osuTK;
using osuTK.Graphics;
@@ -29,8 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
{
protected override LocalisableString Header => GraphicsSettingsStrings.LayoutHeader;
private FillFlowContainer<SettingsSlider<float>> scalingSettings = null!;
private SettingsSlider<float> dimSlider = null!;
private FillFlowContainer<SettingsItemV2> scalingSettings = null!;
private readonly Bindable<Display> currentDisplay = new Bindable<Display>();
@@ -51,12 +49,19 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
private IWindow? window;
private SettingsDropdown<Size> resolutionFullscreenDropdown = null!;
private SettingsDropdown<Size> resolutionWindowedDropdown = null!;
private SettingsDropdown<Display> displayDropdown = null!;
private SettingsDropdown<WindowMode> windowModeDropdown = null!;
private SettingsCheckbox minimiseOnFocusLossCheckbox = null!;
private SettingsCheckbox safeAreaConsiderationsCheckbox = null!;
private readonly BindableBool resolutionFullscreenCanBeShown = new BindableBool(true);
private readonly BindableBool resolutionWindowedCanBeShown = new BindableBool(true);
private readonly BindableBool displayDropdownCanBeShown = new BindableBool(true);
private readonly BindableBool minimiseOnFocusLossCanBeShown = new BindableBool(true);
private readonly BindableBool safeAreaConsiderationsCanBeShown = new BindableBool(true);
private FormDropdown<Size> resolutionWindowedDropdown = null!;
private FormDropdown<Display> displayDropdown = null!;
private FormDropdown<WindowMode> windowModeDropdown = null!;
private FormSliderBar<float> dimSlider = null!;
private readonly Bindable<SettingsNote.Data?> windowModeDropdownNote = new Bindable<SettingsNote.Data?>();
private Bindable<double> windowedPositionX = null!;
private Bindable<double> windowedPositionY = null!;
@@ -98,105 +103,137 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
Children = new Drawable[]
{
windowModeDropdown = new SettingsDropdown<WindowMode>
new SettingsItemV2(windowModeDropdown = new FormDropdown<WindowMode>
{
LabelText = GraphicsSettingsStrings.ScreenMode,
Caption = GraphicsSettingsStrings.ScreenMode,
Items = window?.SupportedWindowModes,
CanBeShown = { Value = window?.SupportedWindowModes.Count() > 1 },
Current = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode),
},
displayDropdown = new DisplaySettingsDropdown
})
{
LabelText = GraphicsSettingsStrings.Display,
CanBeShown = { Value = window?.SupportedWindowModes.Count() > 1 },
Note = { BindTarget = windowModeDropdownNote },
},
new SettingsItemV2(displayDropdown = new DisplayDropdown
{
Caption = GraphicsSettingsStrings.Display,
Items = window?.Displays,
Current = currentDisplay,
},
resolutionFullscreenDropdown = new ResolutionSettingsDropdown
})
{
LabelText = GraphicsSettingsStrings.Resolution,
ShowsDefaultIndicator = false,
CanBeShown = { BindTarget = displayDropdownCanBeShown }
},
new SettingsItemV2(new ResolutionDropdown
{
Caption = GraphicsSettingsStrings.Resolution,
ItemSource = resolutionsFullscreen,
Current = sizeFullscreen
},
resolutionWindowedDropdown = new ResolutionSettingsDropdown
})
{
LabelText = GraphicsSettingsStrings.Resolution,
ShowsDefaultIndicator = false,
CanBeShown = { BindTarget = resolutionFullscreenCanBeShown },
ShowRevertToDefaultButton = false,
},
new SettingsItemV2(resolutionWindowedDropdown = new ResolutionDropdown
{
Caption = GraphicsSettingsStrings.Resolution,
ItemSource = resolutionsWindowed,
Current = windowedResolution
},
minimiseOnFocusLossCheckbox = new SettingsCheckbox
})
{
LabelText = GraphicsSettingsStrings.MinimiseOnFocusLoss,
CanBeShown = { BindTarget = resolutionWindowedCanBeShown },
ShowRevertToDefaultButton = false,
},
new SettingsItemV2(new FormCheckBox
{
Caption = GraphicsSettingsStrings.MinimiseOnFocusLoss,
Current = config.GetBindable<bool>(FrameworkSetting.MinimiseOnFocusLossInFullscreen),
})
{
CanBeShown = { BindTarget = minimiseOnFocusLossCanBeShown },
Keywords = new[] { "alt-tab", "minimize", "focus", "hide" },
},
safeAreaConsiderationsCheckbox = new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = GraphicsSettingsStrings.ShrinkGameToSafeArea,
Caption = GraphicsSettingsStrings.ShrinkGameToSafeArea,
Current = osuConfig.GetBindable<bool>(OsuSetting.SafeAreaConsiderations),
},
new SettingsSlider<float, UIScaleSlider>
})
{
LabelText = GraphicsSettingsStrings.UIScaling,
CanBeShown = { BindTarget = safeAreaConsiderationsCanBeShown },
},
new SettingsItemV2(new FormSliderBar<float>
{
Caption = GraphicsSettingsStrings.UIScaling,
TransferValueOnCommit = true,
Current = osuConfig.GetBindable<float>(OsuSetting.UIScale),
KeyboardStep = 0.01f,
Keywords = new[] { "scale", "letterbox" },
},
new SettingsEnumDropdown<ScalingMode>
LabelFormat = v => $@"{v:0.##}x",
})
{
LabelText = GraphicsSettingsStrings.ScreenScaling,
Current = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
Keywords = new[] { "scale", "letterbox" },
},
scalingSettings = new FillFlowContainer<SettingsSlider<float>>
new SettingsItemV2(new FormEnumDropdown<ScalingMode>
{
Caption = GraphicsSettingsStrings.ScreenScaling,
Current = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
})
{
Keywords = new[] { "scale", "letterbox" },
},
scalingSettings = new FillFlowContainer<SettingsItemV2>
{
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Masking = true,
Spacing = new Vector2(0, SettingsSection.ITEM_SPACING_V2),
Children = new[]
{
new SettingsSlider<float>
new SettingsItemV2(new FormSliderBar<float>
{
LabelText = GraphicsSettingsStrings.HorizontalPosition,
Keywords = new[] { "screen", "scaling" },
Caption = GraphicsSettingsStrings.HorizontalPosition,
Current = scalingPositionX,
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsSlider<float>
DisplayAsPercentage = true,
}.With(bindPreviewEvent))
{
LabelText = GraphicsSettingsStrings.VerticalPosition,
Keywords = new[] { "screen", "scaling" },
},
new SettingsItemV2(new FormSliderBar<float>
{
Caption = GraphicsSettingsStrings.VerticalPosition,
Current = scalingPositionY,
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsSlider<float>
DisplayAsPercentage = true,
}.With(bindPreviewEvent))
{
LabelText = GraphicsSettingsStrings.HorizontalScale,
Keywords = new[] { "screen", "scaling" },
},
new SettingsItemV2(new FormSliderBar<float>
{
Caption = GraphicsSettingsStrings.HorizontalScale,
Current = scalingSizeX,
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
new SettingsSlider<float>
DisplayAsPercentage = true,
}.With(bindPreviewEvent))
{
LabelText = GraphicsSettingsStrings.VerticalScale,
Keywords = new[] { "screen", "scaling" },
},
new SettingsItemV2(new FormSliderBar<float>
{
Caption = GraphicsSettingsStrings.VerticalScale,
Current = scalingSizeY,
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
dimSlider = new SettingsSlider<float>
DisplayAsPercentage = true,
}.With(bindPreviewEvent))
{
LabelText = GameplaySettingsStrings.BackgroundDim,
Keywords = new[] { "screen", "scaling" },
},
new SettingsItemV2(dimSlider = new FormSliderBar<float>
{
Caption = GameplaySettingsStrings.BackgroundDim,
Current = scalingBackgroundDim,
KeyboardStep = 0.01f,
DisplayAsPercentage = true,
},
}.With(bindPreviewEvent)),
}
},
};
@@ -208,8 +245,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
{
base.LoadComplete();
scalingSettings.ForEach(s => bindPreviewEvent(s.Current));
windowModeDropdown.Current.BindValueChanged(_ =>
{
updateDisplaySettingsVisibility();
@@ -298,18 +333,19 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
scalingSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
scalingSettings.AutoSizeAxes = scalingMode.Value != ScalingMode.Off ? Axes.Y : Axes.None;
scalingSettings.ForEach(s =>
foreach (SettingsItemV2 item in scalingSettings)
{
if (s == dimSlider)
{
s.CanBeShown.Value = scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays;
}
FormSliderBar<float> slider = (FormSliderBar<float>)item.Control;
if (slider == dimSlider)
item.CanBeShown.Value = scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays;
else
{
s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything;
s.CanBeShown.Value = scalingMode.Value != ScalingMode.Off;
slider.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything;
item.CanBeShown.Value = scalingMode.Value != ScalingMode.Off;
}
});
}
}
}
@@ -325,12 +361,12 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
private void updateDisplaySettingsVisibility()
{
resolutionFullscreenDropdown.CanBeShown.Value = windowModeDropdown.Current.Value == WindowMode.Fullscreen && resolutionsFullscreen.Count > 1;
resolutionWindowedDropdown.CanBeShown.Value = windowModeDropdown.Current.Value == WindowMode.Windowed && resolutionsWindowed.Count > 1;
resolutionFullscreenCanBeShown.Value = windowModeDropdown.Current.Value == WindowMode.Fullscreen && resolutionsFullscreen.Count > 1;
resolutionWindowedCanBeShown.Value = windowModeDropdown.Current.Value == WindowMode.Windowed && resolutionsWindowed.Count > 1;
displayDropdown.CanBeShown.Value = displayDropdown.Items.Count() > 1;
minimiseOnFocusLossCheckbox.CanBeShown.Value = RuntimeInfo.IsDesktop && windowModeDropdown.Current.Value == WindowMode.Fullscreen;
safeAreaConsiderationsCheckbox.CanBeShown.Value = host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero;
displayDropdownCanBeShown.Value = displayDropdown.Items.Count() > 1;
minimiseOnFocusLossCanBeShown.Value = RuntimeInfo.IsDesktop && windowModeDropdown.Current.Value == WindowMode.Fullscreen;
safeAreaConsiderationsCanBeShown.Value = host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero;
}
private void updateScreenModeWarning()
@@ -339,16 +375,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
if (RuntimeInfo.OS == RuntimeInfo.Platform.macOS && !FrameworkEnvironment.UseSDL3)
{
if (windowModeDropdown.Current.Value == WindowMode.Fullscreen)
windowModeDropdown.SetNoticeText(LayoutSettingsStrings.FullscreenMacOSNote, true);
windowModeDropdownNote.Value = new SettingsNote.Data(LayoutSettingsStrings.FullscreenMacOSNote, SettingsNote.Type.Critical);
else
windowModeDropdown.ClearNoticeText();
windowModeDropdownNote.Value = null;
return;
}
if (windowModeDropdown.Current.Value != WindowMode.Fullscreen)
{
windowModeDropdown.SetNoticeText(GraphicsSettingsStrings.NotFullscreenNote, true);
windowModeDropdownNote.Value = new SettingsNote.Data(GraphicsSettingsStrings.NotFullscreenNote, SettingsNote.Type.Warning);
return;
}
@@ -357,28 +393,28 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
switch (fullscreenCapability.Value)
{
case FullscreenCapability.Unknown:
windowModeDropdown.SetNoticeText(LayoutSettingsStrings.CheckingForFullscreenCapabilities, true);
windowModeDropdownNote.Value = new SettingsNote.Data(LayoutSettingsStrings.CheckingForFullscreenCapabilities, SettingsNote.Type.Informational);
break;
case FullscreenCapability.Capable:
windowModeDropdown.SetNoticeText(LayoutSettingsStrings.OsuIsRunningExclusiveFullscreen);
windowModeDropdownNote.Value = new SettingsNote.Data(LayoutSettingsStrings.OsuIsRunningExclusiveFullscreen, SettingsNote.Type.Informational);
break;
case FullscreenCapability.Incapable:
windowModeDropdown.SetNoticeText(LayoutSettingsStrings.UnableToRunExclusiveFullscreen, true);
windowModeDropdownNote.Value = new SettingsNote.Data(LayoutSettingsStrings.UnableToRunExclusiveFullscreen, SettingsNote.Type.Warning);
break;
}
}
else
{
// We can only detect exclusive fullscreen status on windows currently.
windowModeDropdown.ClearNoticeText();
windowModeDropdownNote.Value = null;
}
}
private void bindPreviewEvent(Bindable<float> bindable)
private void bindPreviewEvent(FormSliderBar<float> slider)
{
bindable.ValueChanged += _ =>
slider.Current.ValueChanged += _ =>
{
switch (scalingMode.Value)
{
@@ -421,37 +457,22 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
}
}
private partial class UIScaleSlider : RoundedSliderBar<float>
private partial class DisplayDropdown : FormDropdown<Display>
{
public override LocalisableString TooltipText => base.TooltipText + "x";
}
private partial class DisplaySettingsDropdown : SettingsDropdown<Display>
{
protected override OsuDropdown<Display> CreateDropdown() => new DisplaySettingsDropdownControl();
private partial class DisplaySettingsDropdownControl : DropdownControl
protected override LocalisableString GenerateItemText(Display item)
{
protected override LocalisableString GenerateItemText(Display item)
{
return $"{item.Index}: {item.Name} ({item.Bounds.Width}x{item.Bounds.Height})";
}
return $"{item.Index}: {item.Name} ({item.Bounds.Width}x{item.Bounds.Height})";
}
}
private partial class ResolutionSettingsDropdown : SettingsDropdown<Size>
private partial class ResolutionDropdown : FormDropdown<Size>
{
protected override OsuDropdown<Size> CreateDropdown() => new ResolutionDropdownControl();
private partial class ResolutionDropdownControl : DropdownControl
protected override LocalisableString GenerateItemText(Size item)
{
protected override LocalisableString GenerateItemText(Size item)
{
if (item == new Size(9999, 9999))
return CommonStrings.Default;
if (item == new Size(9999, 9999))
return CommonStrings.Default;
return $"{item.Width}x{item.Height}";
}
return $"{item.Width}x{item.Height}";
}
}
@@ -9,7 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays.Dialog;
@@ -29,32 +29,38 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
Children = new Drawable[]
{
new RendererSettingsDropdown
new SettingsItemV2(new RendererDropdown
{
LabelText = GraphicsSettingsStrings.Renderer,
Caption = GraphicsSettingsStrings.Renderer,
Current = renderer,
Items = host.GetPreferredRenderersForCurrentPlatform().Order()
#pragma warning disable CS0612 // Type or member is obsolete
.Where(t => t != RendererType.Vulkan && t != RendererType.OpenGLLegacy),
#pragma warning restore CS0612 // Type or member is obsolete
})
{
Keywords = new[] { @"compatibility", @"directx" },
},
// TODO: this needs to be a custom dropdown at some point
new SettingsEnumDropdown<FrameSync>
new SettingsItemV2(new FormEnumDropdown<FrameSync>
{
LabelText = GraphicsSettingsStrings.FrameLimiter,
Caption = GraphicsSettingsStrings.FrameLimiter,
Current = config.GetBindable<FrameSync>(FrameworkSetting.FrameSync),
})
{
Keywords = new[] { @"fps", @"framerate" },
},
new SettingsEnumDropdown<ExecutionMode>
new SettingsItemV2(new FormEnumDropdown<ExecutionMode>
{
LabelText = GraphicsSettingsStrings.ThreadingMode,
Caption = GraphicsSettingsStrings.ThreadingMode,
Current = config.GetBindable<ExecutionMode>(FrameworkSetting.ExecutionMode)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GraphicsSettingsStrings.ShowFPS,
Caption = GraphicsSettingsStrings.ShowFPS,
Current = osuConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay),
})
{
Keywords = new[] { @"framerate", @"counter" },
},
};
@@ -82,30 +88,25 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
});
}
private partial class RendererSettingsDropdown : SettingsEnumDropdown<RendererType>
private partial class RendererDropdown : FormEnumDropdown<RendererType>
{
protected override OsuDropdown<RendererType> CreateDropdown() => new RendererDropdown();
private RendererType hostResolvedRenderer;
private bool automaticRendererInUse;
protected partial class RendererDropdown : DropdownControl
[BackgroundDependencyLoader]
private void load(FrameworkConfigManager config, GameHost host)
{
private RendererType hostResolvedRenderer;
private bool automaticRendererInUse;
var renderer = config.GetBindable<RendererType>(FrameworkSetting.Renderer);
automaticRendererInUse = renderer.Value == RendererType.Automatic;
hostResolvedRenderer = host.ResolvedRenderer;
}
[BackgroundDependencyLoader]
private void load(FrameworkConfigManager config, GameHost host)
{
var renderer = config.GetBindable<RendererType>(FrameworkSetting.Renderer);
automaticRendererInUse = renderer.Value == RendererType.Automatic;
hostResolvedRenderer = host.ResolvedRenderer;
}
protected override LocalisableString GenerateItemText(RendererType item)
{
if (item == RendererType.Automatic && automaticRendererInUse)
return LocalisableString.Interpolate($"{base.GenerateItemText(item)} ({hostResolvedRenderer.GetDescription()})");
protected override LocalisableString GenerateItemText(RendererType item)
{
if (item == RendererType.Automatic && automaticRendererInUse)
return LocalisableString.Interpolate($"{base.GenerateItemText(item)} ({hostResolvedRenderer.GetDescription()})");
return base.GenerateItemText(item);
}
return base.GenerateItemText(item);
}
}
}
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Graphics
@@ -18,16 +19,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
{
Children = new Drawable[]
{
new SettingsEnumDropdown<ScreenshotFormat>
new SettingsItemV2(new FormEnumDropdown<ScreenshotFormat>
{
LabelText = GraphicsSettingsStrings.ScreenshotFormat,
Caption = GraphicsSettingsStrings.ScreenshotFormat,
Current = config.GetBindable<ScreenshotFormat>(OsuSetting.ScreenshotFormat)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = GraphicsSettingsStrings.ShowCursorInScreenshots,
Caption = GraphicsSettingsStrings.ShowCursorInScreenshots,
Current = config.GetBindable<bool>(OsuSetting.ScreenshotCaptureMenuCursor)
}
})
};
}
}
@@ -9,6 +9,7 @@ using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Video;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Graphics
@@ -18,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
protected override LocalisableString Header => GraphicsSettingsStrings.VideoHeader;
private Bindable<HardwareVideoDecoder> hardwareVideoDecoder;
private SettingsCheckbox hwAccelCheckbox;
private FormCheckBox hwAccelCheckbox;
[BackgroundDependencyLoader]
private void load(FrameworkConfigManager config)
@@ -27,10 +28,10 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
Children = new Drawable[]
{
hwAccelCheckbox = new SettingsCheckbox
new SettingsItemV2(hwAccelCheckbox = new FormCheckBox
{
LabelText = GraphicsSettingsStrings.UseHardwareAcceleration,
},
Caption = GraphicsSettingsStrings.UseHardwareAcceleration,
}),
};
hwAccelCheckbox.Current.Default = hardwareVideoDecoder.Default != HardwareVideoDecoder.None;
@@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
{
Children = new Drawable[]
{
new SettingsButton
new SettingsButtonV2
{
Text = BindingSettingsStrings.Configure,
TooltipText = BindingSettingsStrings.ChangeBindingsButton,
@@ -8,25 +8,23 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Handlers.Joystick;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Input
{
public partial class JoystickSettings : SettingsSubsection
public partial class JoystickSettings : InputSubsection
{
protected override LocalisableString Header => JoystickSettingsStrings.JoystickGamepad;
private readonly JoystickHandler joystickHandler;
private readonly Bindable<bool> enabled = new BindableBool(true);
private SettingsSlider<float> deadzoneSlider;
private Bindable<float> handlerDeadzone;
private Bindable<float> localDeadzone;
public JoystickSettings(JoystickHandler joystickHandler)
: base(joystickHandler)
{
this.joystickHandler = joystickHandler;
}
@@ -38,30 +36,22 @@ namespace osu.Game.Overlays.Settings.Sections.Input
handlerDeadzone = joystickHandler.DeadzoneThreshold.GetBoundCopy();
localDeadzone = handlerDeadzone.GetUnboundCopy();
Children = new Drawable[]
AddRange(new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormSliderBar<float>
{
LabelText = CommonStrings.Enabled,
Current = enabled
},
deadzoneSlider = new SettingsSlider<float>
{
LabelText = JoystickSettingsStrings.DeadzoneThreshold,
Caption = JoystickSettingsStrings.DeadzoneThreshold,
KeyboardStep = 0.01f,
DisplayAsPercentage = true,
Current = localDeadzone,
},
};
})
});
}
protected override void LoadComplete()
{
base.LoadComplete();
enabled.BindTo(joystickHandler.Enabled);
enabled.BindValueChanged(e => deadzoneSlider.Current.Disabled = !e.NewValue, true);
handlerDeadzone.BindValueChanged(val =>
{
bool disabled = localDeadzone.Disabled;
@@ -94,6 +94,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
private Container content = null!;
private OsuSpriteText text = null!;
private SettingsRevertToDefaultButton revertButton = null!;
private FillFlowContainer cancelAndClearButtons = null!;
private FillFlowContainer<KeyButton> buttons = null!;
@@ -127,27 +128,24 @@ namespace osu.Game.Overlays.Settings.Sections.Input
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Padding = new MarginPadding { Right = SettingsPanel.CONTENT_MARGINS };
Padding = new MarginPadding { Right = SettingsPanel.CONTENT_PADDING.Right };
InternalChildren = new Drawable[]
{
new Container
revertButton = new SettingsRevertToDefaultButton
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
Height = 1,
RelativeSizeAxes = Axes.Y,
Width = SettingsPanel.CONTENT_MARGINS,
Child = new RevertToDefaultButton<bool>
{
Current = isDefault,
Action = RestoreDefaults,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}
IconSize = 12,
Action = RestoreDefaults,
},
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS },
Padding = new MarginPadding { Left = SettingsPanel.CONTENT_PADDING.Left },
Children = new Drawable[]
{
content = new Container
@@ -179,7 +177,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight
Origin = Anchor.TopRight,
Spacing = new Vector2(-6, 0),
},
cancelAndClearButtons = new FillFlowContainer
{
@@ -223,6 +222,19 @@ namespace osu.Game.Overlays.Settings.Sections.Input
keypressSamples[i] = audioManager.Samples.Get($@"Keyboard/key-press-{1 + i}");
}
protected override void LoadComplete()
{
base.LoadComplete();
isDefault.BindValueChanged(d =>
{
if (d.NewValue)
revertButton.Hide();
else
revertButton.Show();
}, true);
}
public void RestoreDefaults()
{
int i = 0;
@@ -483,7 +495,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
protected override void OnFocus(FocusEvent e)
{
content.AutoSizeDuration = 500;
content.AutoSizeDuration = 250;
content.AutoSizeEasing = Easing.OutQuint;
cancelAndClearButtons.FadeIn(300, Easing.OutQuint);
@@ -111,7 +111,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
}
}
public partial class ResetButton : DangerousSettingsButton
public partial class ResetButton : DangerousSettingsButtonV2
{
[BackgroundDependencyLoader]
private void load()
@@ -1,8 +1,6 @@
// 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.
#nullable disable
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -11,30 +9,33 @@ using osu.Framework.Graphics;
using osu.Framework.Input.Handlers.Mouse;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Input
{
public partial class MouseSettings : SettingsSubsection
public partial class MouseSettings : InputSubsection
{
private readonly MouseHandler mouseHandler;
protected override LocalisableString Header => MouseSettingsStrings.Mouse;
private Bindable<double> handlerSensitivity;
private Bindable<double> handlerSensitivity = null!;
private Bindable<double> localSensitivity = null!;
private Bindable<WindowMode> windowMode = null!;
private Bindable<bool> minimiseOnFocusLoss = null!;
private FormEnumDropdown<OsuConfineMouseMode> confineMouseModeSetting = null!;
private Bindable<bool> relativeMode = null!;
private Bindable<double> localSensitivity;
private FormCheckBox highPrecisionMouse = null!;
private Bindable<WindowMode> windowMode;
private Bindable<bool> minimiseOnFocusLoss;
private SettingsEnumDropdown<OsuConfineMouseMode> confineMouseModeSetting;
private Bindable<bool> relativeMode;
private readonly Bindable<SettingsNote.Data?> highPrecisionMouseNote = new Bindable<SettingsNote.Data?>();
private SettingsCheckbox highPrecisionMouse;
protected override bool IsToggleable => false;
public MouseSettings(MouseHandler mouseHandler)
: base(mouseHandler)
{
this.mouseHandler = mouseHandler;
}
@@ -50,38 +51,47 @@ namespace osu.Game.Overlays.Settings.Sections.Input
windowMode = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode);
minimiseOnFocusLoss = config.GetBindable<bool>(FrameworkSetting.MinimiseOnFocusLossInFullscreen);
Children = new Drawable[]
AddRange(new Drawable[]
{
highPrecisionMouse = new SettingsCheckbox
new SettingsItemV2(highPrecisionMouse = new FormCheckBox
{
LabelText = MouseSettingsStrings.HighPrecisionMouse,
TooltipText = MouseSettingsStrings.HighPrecisionMouseTooltip,
Caption = MouseSettingsStrings.HighPrecisionMouse,
HintText = MouseSettingsStrings.HighPrecisionMouseTooltip,
Current = relativeMode,
})
{
Keywords = new[] { @"raw", @"input", @"relative", @"cursor", "sensitivity", "speed", "velocity" },
Note = { BindTarget = highPrecisionMouseNote },
},
new SensitivitySetting
new SettingsItemV2(new FormSliderBar<double>
{
Caption = MouseSettingsStrings.CursorSensitivity,
Current = localSensitivity,
KeyboardStep = 0.01f,
TransferValueOnCommit = true,
LabelFormat = v => $@"{v:0.##}x",
TooltipFormat = v => localSensitivity.Disabled ? MouseSettingsStrings.EnableHighPrecisionForSensitivityAdjust : $@"{v:0.##}x",
})
{
Keywords = new[] { "speed", "velocity" },
LabelText = MouseSettingsStrings.CursorSensitivity,
Current = localSensitivity
},
confineMouseModeSetting = new SettingsEnumDropdown<OsuConfineMouseMode>
new SettingsItemV2(confineMouseModeSetting = new FormEnumDropdown<OsuConfineMouseMode>
{
LabelText = MouseSettingsStrings.ConfineMouseMode,
Caption = MouseSettingsStrings.ConfineMouseMode,
Current = osuConfig.GetBindable<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = MouseSettingsStrings.DisableMouseWheelVolumeAdjust,
TooltipText = MouseSettingsStrings.DisableMouseWheelVolumeAdjustTooltip,
Caption = MouseSettingsStrings.DisableMouseWheelVolumeAdjust,
HintText = MouseSettingsStrings.DisableMouseWheelVolumeAdjustTooltip,
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableWheel)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = MouseSettingsStrings.DisableClicksDuringGameplay,
Caption = MouseSettingsStrings.DisableClicksDuringGameplay,
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
},
};
}),
});
}
protected override void LoadComplete()
@@ -112,9 +122,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input
case RuntimeInfo.Platform.macOS:
case RuntimeInfo.Platform.iOS:
if (highPrecision.NewValue)
highPrecisionMouse.SetNoticeText(MouseSettingsStrings.HighPrecisionPlatformWarning, true);
highPrecisionMouseNote.Value = new SettingsNote.Data(MouseSettingsStrings.HighPrecisionPlatformWarning, SettingsNote.Type.Warning);
else
highPrecisionMouse.ClearNoticeText();
highPrecisionMouseNote.Value = null;
break;
}
@@ -131,27 +141,13 @@ namespace osu.Game.Overlays.Settings.Sections.Input
if (confineModeOverriden)
{
confineMouseModeSetting.Current.Disabled = true;
confineMouseModeSetting.TooltipText = MouseSettingsStrings.NotApplicableFullscreen;
confineMouseModeSetting.HintText = MouseSettingsStrings.NotApplicableFullscreen;
}
else
{
confineMouseModeSetting.Current.Disabled = false;
confineMouseModeSetting.TooltipText = string.Empty;
confineMouseModeSetting.HintText = default;
}
}
public partial class SensitivitySetting : SettingsSlider<double, SensitivitySlider>
{
public SensitivitySetting()
{
KeyboardStep = 0.01f;
TransferValueOnCommit = true;
}
}
public partial class SensitivitySlider : RoundedSliderBar<double>
{
public override LocalisableString TooltipText => Current.Disabled ? MouseSettingsStrings.EnableHighPrecisionForSensitivityAdjust : $"{base.TooltipText}x";
}
}
}
@@ -41,71 +41,92 @@ namespace osu.Game.Overlays.Settings.Sections.Input
private Box usableFill;
private OsuSpriteText usableAreaText;
[Resolved]
private OsuColour colour { get; set; }
public TabletAreaSelection(ITabletHandler handler)
{
this.handler = handler;
Padding = new MarginPadding { Horizontal = SettingsPanel.CONTENT_MARGINS };
Padding = SettingsPanel.CONTENT_PADDING;
}
[BackgroundDependencyLoader]
private void load()
private void load(OverlayColourProvider colourProvider)
{
InternalChild = tabletContainer = new Container
InternalChildren = new Drawable[]
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Masking = true,
CornerRadius = 5,
BorderThickness = 2,
BorderColour = colour.Gray3,
Children = new Drawable[]
new Container
{
new Box
RelativeSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 5,
CornerExponent = 2.5f,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Colour = colour.Gray1,
},
usableAreaContainer = new UsableAreaContainer(handler)
{
Origin = Anchor.Centre,
Children = new Drawable[]
new Box
{
usableFill = new Box
Colour = colourProvider.Background5,
RelativeSizeAxes = Axes.Both,
},
tabletContainer = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Masking = true,
CornerRadius = 5,
BorderThickness = 2,
BorderColour = colourProvider.Background3,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.6f,
},
new Box
{
Colour = Color4.White,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Height = 5,
},
new Box
{
Colour = Color4.White,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Width = 5,
},
usableAreaText = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.White,
Font = OsuFont.Default.With(size: 12),
Y = 10
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4,
},
usableAreaContainer = new UsableAreaContainer(handler)
{
Origin = Anchor.Centre,
Children = new Drawable[]
{
usableFill = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.6f,
},
new Box
{
Colour = Color4.White,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Height = 5,
},
new Box
{
Colour = Color4.White,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Width = 5,
},
usableAreaText = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Colour = Color4.White,
Font = OsuFont.Default.With(size: 12),
Y = 10
}
}
},
tabletName = new OsuSpriteText
{
Padding = new MarginPadding(3),
Font = OsuFont.Default.With(size: 8)
},
}
}
},
tabletName = new OsuSpriteText
{
Padding = new MarginPadding(3),
Font = OsuFont.Default.With(size: 8)
},
}
}
},
};
}
@@ -169,9 +190,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
return a;
}
[Resolved]
private OsuColour colour { get; set; }
private void checkBounds()
{
if (tablet.Value == null)
@@ -9,6 +9,8 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Handlers;
using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Localisation;
using osu.Framework.Platform;
@@ -17,13 +19,14 @@ using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterfaceV2;
using osuTK;
using osu.Game.Localisation;
using osu.Game.Online.Chat;
namespace osu.Game.Overlays.Settings.Sections.Input
{
public partial class TabletSettings : SettingsSubsection
public partial class TabletSettings : InputSubsection
{
public override IEnumerable<LocalisableString> FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { "area" });
@@ -74,70 +77,92 @@ namespace osu.Game.Overlays.Settings.Sections.Input
private FillFlowContainer mainSettings;
private FillFlowContainer noTabletMessage;
private Container noTabletMessage;
protected override LocalisableString Header => TabletSettingsStrings.Tablet;
public TabletSettings(ITabletHandler tabletHandler)
: base((InputHandler)tabletHandler)
{
this.tabletHandler = tabletHandler;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, LocalisationManager localisation, OsuConfigManager osuConfig)
private void load(OsuColour colours, LocalisationManager localisation, OsuConfigManager osuConfig, OverlayColourProvider colourProvider)
{
scalingMode = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling);
scalingSizeX = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeX);
scalingSizeY = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeY);
Children = new Drawable[]
AddRange(new Drawable[]
{
new SettingsCheckbox
{
LabelText = CommonStrings.Enabled,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Current = enabled,
},
noTabletMessage = new FillFlowContainer
noTabletMessage = new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Padding = new MarginPadding { Horizontal = SettingsPanel.CONTENT_MARGINS },
Spacing = new Vector2(5f),
Children = new Drawable[]
Padding = SettingsPanel.CONTENT_PADDING,
Child = new Container
{
new OsuSpriteText
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Masking = true,
CornerRadius = 5,
CornerExponent = 2.5f,
Children = new Drawable[]
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = TabletSettingsStrings.NoTabletDetected,
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Dark2,
},
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
Spacing = new Vector2(5f),
Padding = new MarginPadding { Horizontal = 8, Vertical = 10 },
Children = new Drawable[]
{
new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = TabletSettingsStrings.NoTabletDetected,
Font = OsuFont.Style.Caption1.With(weight: FontWeight.SemiBold),
Colour = colourProvider.Content2,
},
new LinkFlowContainer(cp =>
{
cp.Colour = colours.Orange1;
cp.Font = OsuFont.Style.Caption1.With(weight: FontWeight.SemiBold);
})
{
TextAnchor = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
}.With(t =>
{
t.NewLine();
const string url = @"https://opentabletdriver.net/Wiki/FAQ/General";
var formattedSource = MessageFormatter.FormatText(localisation.GetLocalisedString(TabletSettingsStrings.NoTabletDetectedDescription(url)));
t.AddLinks(formattedSource.Text, formattedSource.Links);
}),
}
},
},
new LinkFlowContainer(cp => cp.Colour = colours.Yellow)
{
TextAnchor = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
}.With(t =>
{
t.NewLine();
const string url = @"https://opentabletdriver.net/Wiki/FAQ/General";
var formattedSource = MessageFormatter.FormatText(localisation.GetLocalisedString(TabletSettingsStrings.NoTabletDetectedDescription(url)));
t.AddLinks(formattedSource.Text, formattedSource.Links);
}),
}
},
},
mainSettings = new FillFlowContainer
{
Alpha = 0,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0, SettingsSection.ITEM_SPACING),
Spacing = new Vector2(0, SettingsSection.ITEM_SPACING_V2),
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
@@ -146,7 +171,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
RelativeSizeAxes = Axes.X,
Height = 300,
},
new DangerousSettingsButton
new DangerousSettingsButtonV2
{
Text = TabletSettingsStrings.ResetToFullArea,
Action = () =>
@@ -156,9 +181,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
areaOffset.SetDefault();
areaSize.SetDefault();
},
CanBeShown = { BindTarget = enabled }
},
new SettingsButton
new SettingsButtonV2
{
Text = TabletSettingsStrings.ConformToCurrentGameAspectRatio,
Action = () =>
@@ -174,73 +198,62 @@ namespace osu.Game.Overlays.Settings.Sections.Input
forceAspectRatio(gameplayWidth / gameplayHeight);
},
CanBeShown = { BindTarget = enabled }
},
new SettingsSlider<float>
new SettingsItemV2(new FormSliderBar<float>
{
TransferValueOnCommit = true,
LabelText = TabletSettingsStrings.XOffset,
Caption = TabletSettingsStrings.XOffset,
Current = offsetX,
CanBeShown = { BindTarget = enabled }
},
new SettingsSlider<float>
}),
new SettingsItemV2(new FormSliderBar<float>
{
TransferValueOnCommit = true,
LabelText = TabletSettingsStrings.YOffset,
Caption = TabletSettingsStrings.YOffset,
Current = offsetY,
CanBeShown = { BindTarget = enabled }
},
new SettingsSlider<float>
}),
new SettingsItemV2(new FormSliderBar<float>
{
TransferValueOnCommit = true,
LabelText = TabletSettingsStrings.Rotation,
Caption = TabletSettingsStrings.Rotation,
Current = rotation,
CanBeShown = { BindTarget = enabled }
},
}),
new RotationPresetButtons(tabletHandler)
{
Padding = new MarginPadding
{
Horizontal = SettingsPanel.CONTENT_MARGINS
}
Padding = SettingsPanel.CONTENT_PADDING,
},
new SettingsSlider<float>
new SettingsItemV2(new FormSliderBar<float>
{
TransferValueOnCommit = true,
LabelText = TabletSettingsStrings.AspectRatio,
Caption = TabletSettingsStrings.AspectRatio,
Current = aspectRatio,
CanBeShown = { BindTarget = enabled }
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = TabletSettingsStrings.LockAspectRatio,
Caption = TabletSettingsStrings.LockAspectRatio,
Current = aspectLock,
CanBeShown = { BindTarget = enabled }
},
new SettingsSlider<float>
}),
new SettingsItemV2(new FormSliderBar<float>
{
TransferValueOnCommit = true,
LabelText = CommonStrings.Width,
Caption = CommonStrings.Width,
Current = sizeX,
CanBeShown = { BindTarget = enabled }
},
new SettingsSlider<float>
}),
new SettingsItemV2(new FormSliderBar<float>
{
TransferValueOnCommit = true,
LabelText = CommonStrings.Height,
Caption = CommonStrings.Height,
Current = sizeY,
CanBeShown = { BindTarget = enabled }
},
new SettingsPercentageSlider<float>
}),
new SettingsItemV2(new FormSliderBar<float>
{
TransferValueOnCommit = true,
LabelText = TabletSettingsStrings.TipPressureForClick,
Caption = TabletSettingsStrings.TipPressureForClick,
Current = pressureThreshold,
CanBeShown = { BindTarget = enabled }
},
DisplayAsPercentage = true,
}),
}
},
};
});
}
protected override void LoadComplete()
@@ -8,6 +8,7 @@ using osu.Framework.Allocation;
using osu.Framework.Input.Handlers;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Input
@@ -15,34 +16,25 @@ namespace osu.Game.Overlays.Settings.Sections.Input
/// <summary>
/// Touch input settings subsection common to all touch handlers (even on different platforms).
/// </summary>
public partial class TouchSettings : SettingsSubsection
public partial class TouchSettings : InputSubsection
{
private readonly InputHandler handler;
protected override LocalisableString Header => TouchSettingsStrings.Touch;
protected override bool IsToggleable => !RuntimeInfo.IsMobile;
public TouchSettings(InputHandler handler)
: base(handler)
{
this.handler = handler;
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager osuConfig)
{
if (!RuntimeInfo.IsMobile) // don't allow disabling the only input method (touch) on mobile.
Add(new SettingsItemV2(new FormCheckBox
{
Add(new SettingsCheckbox
{
LabelText = CommonStrings.Enabled,
Current = handler.Enabled
});
}
Add(new SettingsCheckbox
{
LabelText = TouchSettingsStrings.DisableTapsDuringGameplay,
Caption = TouchSettingsStrings.DisableTapsDuringGameplay,
Current = osuConfig.GetBindable<bool>(OsuSetting.TouchDisableGameplayTaps)
});
}));
}
public override IEnumerable<LocalisableString> FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { @"touchscreen" });
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Handlers;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Game.Graphics;
@@ -45,30 +44,5 @@ namespace osu.Game.Overlays.Settings.Sections
Add(handlerSection);
}
}
public partial class HandlerSection : SettingsSubsection
{
private readonly InputHandler handler;
public HandlerSection(InputHandler handler)
{
this.handler = handler;
}
[BackgroundDependencyLoader]
private void load()
{
Children = new Drawable[]
{
new SettingsCheckbox
{
LabelText = CommonStrings.Enabled,
Current = handler.Enabled
},
};
}
protected override LocalisableString Header => handler.Description;
}
}
}
@@ -0,0 +1,183 @@
// 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.Containers;
using osu.Framework.Input.Events;
using osu.Framework.Input.Handlers;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.Settings.Sections
{
public partial class InputSubsection : SettingsSubsection
{
private readonly InputHandler handler;
protected override LocalisableString Header => handler.Description;
/// <summary>
/// Whether the input handler can be toggled on/off by the user.
/// </summary>
protected virtual bool IsToggleable => true;
private readonly BindableBool handlerEnabled = new BindableBool();
public InputSubsection(InputHandler handler)
{
this.handler = handler;
FlowContent.AlwaysPresent = true;
}
[BackgroundDependencyLoader]
private void load()
{
HeaderContainer.Child = new ToggleableHeader(Header, IsToggleable)
{
Current = { BindTarget = handlerEnabled },
};
}
protected override void LoadComplete()
{
base.LoadComplete();
handlerEnabled.BindTo(handler.Enabled);
handlerEnabled.BindValueChanged(v => updateEnabledState(), true);
}
private void updateEnabledState()
{
// set negative bottom margin to not have too much vertical gap between disabled input subsections.
bool negativeBottomMargin = !handlerEnabled.Value || FlowContent.Count == 0;
HeaderContainer.TransformTo(nameof(Margin), new MarginPadding { Bottom = negativeBottomMargin ? -15 : 0 }, 300, Easing.OutQuint);
FlowContent.ClearTransforms();
if (!handlerEnabled.Value)
{
FlowContent.AutoSizeAxes = Axes.None;
FlowContent.ResizeHeightTo(0, 300, Easing.OutQuint);
FlowContent.FadeOut(200, Easing.OutQuint);
}
else
{
// enable auto size transform momentarily for smooth pop in animation, and disable it right after the transform is added.
// we don't want this specification to apply when a dropdown in the input settings is being open, it causes too slow animation.
// (try removing the schedule below then watch a settings dropdown menu opening animation).
FlowContent.AutoSizeDuration = 300;
FlowContent.AutoSizeEasing = Easing.OutQuint;
FlowContent.AutoSizeAxes = Axes.Y;
ScheduleAfterChildren(() => FlowContent.AutoSizeDuration = 0);
FlowContent.FadeIn(300, Easing.OutQuint);
}
}
private partial class ToggleableHeader : CompositeDrawable
{
private readonly LocalisableString header;
private readonly bool toggleable;
public readonly BindableBool Current = new BindableBool(true);
public ToggleableHeader(LocalisableString header, bool toggleable)
{
this.header = header;
this.toggleable = toggleable;
}
private SwitchButton switchButton = null!;
private OsuSpriteText headerText = null!;
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
[BackgroundDependencyLoader]
private void load()
{
AutoSizeAxes = Axes.Both;
InternalChildren = new Drawable[]
{
switchButton = new SwitchButton
{
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
Scale = new Vector2(0.6f),
Position = new Vector2(12, 8),
Rotation = 90,
},
headerText = new OsuSpriteText
{
Text = header,
Font = OsuFont.GetFont(size: 20),
Margin = new MarginPadding { Vertical = 12 },
X = 20,
},
new HoverSounds(),
};
}
protected override void LoadComplete()
{
base.LoadComplete();
switchButton.Current.ValueChanged += v => Current.Value = v.NewValue;
Current.BindValueChanged(v =>
{
switchButton.Current.Disabled = false;
switchButton.Current.Value = v.NewValue;
switchButton.Current.Disabled = !toggleable;
updateDisplay();
}, true);
}
protected override bool OnHover(HoverEvent e)
{
updateDisplay();
return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
{
updateDisplay();
base.OnHoverLost(e);
}
protected override bool OnClick(ClickEvent e)
{
if (toggleable)
{
Current.Toggle();
switchButton.PlaySample(Current.Value);
}
updateDisplay();
return true;
}
private void updateDisplay()
{
// default, toggled on (or not toggleable)
Color4 col = colourProvider.Content1;
if (toggleable && !Current.Value)
col = IsHovered ? colourProvider.Light1 : colourProvider.Foreground1;
headerText.FadeColour(col, 300, Easing.OutQuint);
}
}
}
}
@@ -14,16 +14,16 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
protected override LocalisableString Header => CommonStrings.Beatmaps;
private SettingsButton deleteBeatmapsButton = null!;
private SettingsButton deleteBeatmapVideosButton = null!;
private SettingsButton resetOffsetsButton = null!;
private SettingsButton restoreButton = null!;
private SettingsButton undeleteButton = null!;
private SettingsButtonV2 deleteBeatmapsButton = null!;
private SettingsButtonV2 deleteBeatmapVideosButton = null!;
private SettingsButtonV2 resetOffsetsButton = null!;
private SettingsButtonV2 restoreButton = null!;
private SettingsButtonV2 undeleteButton = null!;
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps, IDialogOverlay? dialogOverlay)
{
Add(deleteBeatmapsButton = new DangerousSettingsButton
Add(deleteBeatmapsButton = new DangerousSettingsButtonV2
{
Text = MaintenanceSettingsStrings.DeleteAllBeatmaps,
Action = () =>
@@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
}
});
Add(deleteBeatmapVideosButton = new DangerousSettingsButton
Add(deleteBeatmapVideosButton = new DangerousSettingsButtonV2
{
Text = MaintenanceSettingsStrings.DeleteAllBeatmapVideos,
Action = () =>
@@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
}
});
Add(resetOffsetsButton = new DangerousSettingsButton
Add(resetOffsetsButton = new DangerousSettingsButtonV2
{
Text = MaintenanceSettingsStrings.ResetAllOffsets,
Action = () =>
@@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
AddRange(new Drawable[]
{
restoreButton = new SettingsButton
restoreButton = new SettingsButtonV2
{
Text = MaintenanceSettingsStrings.RestoreAllHiddenDifficulties,
Action = () =>
@@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Task.Run(beatmaps.RestoreAll).ContinueWith(_ => Schedule(() => restoreButton.Enabled.Value = true));
}
},
undeleteButton = new SettingsButton
undeleteButton = new SettingsButtonV2
{
Text = MaintenanceSettingsStrings.RestoreAllRecentlyDeletedBeatmaps,
Action = () =>
@@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
[BackgroundDependencyLoader]
private void load(IDialogOverlay? dialogOverlay)
{
Add(new DangerousSettingsButton
Add(new DangerousSettingsButtonV2
{
Text = MaintenanceSettingsStrings.DeleteAllCollections,
Action = () =>
@@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
AddRange(new Drawable[]
{
new SettingsButton
new SettingsButtonV2
{
Text = DebugSettingsStrings.ImportFiles,
Action = () =>
@@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
performer?.PerformFromScreen(menu => menu.Push(new FileImportScreen()));
},
},
new SettingsButton
new SettingsButtonV2
{
Text = DebugSettingsStrings.RunLatencyCertifier,
Action = () => performer?.PerformFromScreen(menu => menu.Push(new LatencyCertifierScreen()))
@@ -25,15 +25,15 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
[Resolved]
private INotificationOverlay? notificationOverlay { get; set; }
private SettingsButton undeleteButton = null!;
private SettingsButton deleteAllButton = null!;
private SettingsButtonV2 undeleteButton = null!;
private SettingsButtonV2 deleteAllButton = null!;
[BackgroundDependencyLoader]
private void load(IDialogOverlay? dialogOverlay)
{
AddRange(new Drawable[]
{
deleteAllButton = new DangerousSettingsButton
deleteAllButton = new DangerousSettingsButtonV2
{
Text = MaintenanceSettingsStrings.DeleteAllModPresets,
Action = () =>
@@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
}, DeleteConfirmationContentStrings.ModPresets));
}
},
undeleteButton = new SettingsButton
undeleteButton = new SettingsButtonV2
{
Text = MaintenanceSettingsStrings.RestoreAllRecentlyDeletedModPresets,
Action = () => Task.Run(undeleteModPresets).ContinueWith(t => Schedule(onModPresetsUndeleted, t))
@@ -13,12 +13,12 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
protected override LocalisableString Header => CommonStrings.Scores;
private SettingsButton deleteScoresButton = null!;
private SettingsButtonV2 deleteScoresButton = null!;
[BackgroundDependencyLoader]
private void load(ScoreManager scores, IDialogOverlay? dialogOverlay)
{
Add(deleteScoresButton = new DangerousSettingsButton
Add(deleteScoresButton = new DangerousSettingsButtonV2
{
Text = MaintenanceSettingsStrings.DeleteAllScores,
Action = () =>
@@ -13,12 +13,12 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
protected override LocalisableString Header => CommonStrings.Skins;
private SettingsButton deleteSkinsButton = null!;
private SettingsButtonV2 deleteSkinsButton = null!;
[BackgroundDependencyLoader]
private void load(SkinManager skins, IDialogOverlay? dialogOverlay)
{
Add(deleteSkinsButton = new DangerousSettingsButton
Add(deleteSkinsButton = new DangerousSettingsButtonV2
{
Text = MaintenanceSettingsStrings.DeleteAllSkins,
Action = () =>
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Online
@@ -18,27 +19,27 @@ namespace osu.Game.Overlays.Settings.Sections.Online
{
Children = new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = OnlineSettingsStrings.NotifyOnMentioned,
Caption = OnlineSettingsStrings.NotifyOnMentioned,
Current = config.GetBindable<bool>(OsuSetting.NotifyOnUsernameMentioned)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = OnlineSettingsStrings.NotifyOnPrivateMessage,
Caption = OnlineSettingsStrings.NotifyOnPrivateMessage,
Current = config.GetBindable<bool>(OsuSetting.NotifyOnPrivateMessage)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = OnlineSettingsStrings.NotifyOnFriendPresenceChange,
TooltipText = OnlineSettingsStrings.NotifyOnFriendPresenceChangeTooltip,
Caption = OnlineSettingsStrings.NotifyOnFriendPresenceChange,
HintText = OnlineSettingsStrings.NotifyOnFriendPresenceChangeTooltip,
Current = config.GetBindable<bool>(OsuSetting.NotifyOnFriendPresenceChange),
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = OnlineSettingsStrings.HideCountryFlags,
Caption = OnlineSettingsStrings.HideCountryFlags,
Current = config.GetBindable<bool>(OsuSetting.HideCountryFlags)
},
}),
};
}
}
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Online
@@ -18,11 +19,11 @@ namespace osu.Game.Overlays.Settings.Sections.Online
{
Children = new Drawable[]
{
new SettingsEnumDropdown<DiscordRichPresenceMode>
new SettingsItemV2(new FormEnumDropdown<DiscordRichPresenceMode>
{
LabelText = OnlineSettingsStrings.DiscordRichPresence,
Caption = OnlineSettingsStrings.DiscordRichPresence,
Current = config.GetBindable<DiscordRichPresenceMode>(OsuSetting.DiscordRichPresence)
}
}),
};
}
}
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.Online
@@ -18,28 +19,34 @@ namespace osu.Game.Overlays.Settings.Sections.Online
{
Children = new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = OnlineSettingsStrings.ExternalLinkWarning,
Caption = OnlineSettingsStrings.ExternalLinkWarning,
Current = config.GetBindable<bool>(OsuSetting.ExternalLinkWarning)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = OnlineSettingsStrings.PreferNoVideo,
Keywords = new[] { "no-video" },
Caption = OnlineSettingsStrings.PreferNoVideo,
Current = config.GetBindable<bool>(OsuSetting.PreferNoVideo)
},
new SettingsCheckbox
})
{
LabelText = OnlineSettingsStrings.AutomaticallyDownloadMissingBeatmaps,
Keywords = new[] { "spectator", "replay" },
Keywords = new[] { "no-video" },
},
new SettingsItemV2(new FormCheckBox
{
Caption = OnlineSettingsStrings.AutomaticallyDownloadMissingBeatmaps,
Current = config.GetBindable<bool>(OsuSetting.AutomaticallyDownloadMissingBeatmaps),
},
new SettingsCheckbox
})
{
LabelText = OnlineSettingsStrings.ShowExplicitContent,
Keywords = new[] { "nsfw", "18+", "offensive" },
Keywords = new[] { "spectator", "replay" },
},
new SettingsItemV2(new FormCheckBox
{
Caption = OnlineSettingsStrings.ShowExplicitContent,
Current = config.GetBindable<bool>(OsuSetting.ShowOnlineExplicitContent),
})
{
Keywords = new[] { "nsfw", "18+", "offensive" },
}
};
}
@@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Settings.Sections
{
public partial class SkinSection : SettingsSection
{
private SkinSettingsDropdown skinDropdown;
private SkinDropdown skinDropdown;
public override LocalisableString Header => SkinSettingsStrings.SkinSectionHeader;
@@ -65,29 +65,28 @@ namespace osu.Game.Overlays.Settings.Sections
{
Children = new Drawable[]
{
skinDropdown = new SkinSettingsDropdown
new SettingsItemV2(skinDropdown = new SkinDropdown
{
AlwaysShowSearchBar = true,
AllowNonContiguousMatching = true,
LabelText = SkinSettingsStrings.CurrentSkin,
Caption = SkinSettingsStrings.CurrentSkin,
Current = skins.CurrentSkinInfo,
},
}),
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5, 0),
Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS },
Padding = SettingsPanel.CONTENT_PADDING,
Children = new Drawable[]
{
// This is all super-temporary until we move skin settings to their own panel / overlay.
new RenameSkinButton { Padding = new MarginPadding(), RelativeSizeAxes = Axes.None, Width = 120 },
new ExportSkinButton { Padding = new MarginPadding(), RelativeSizeAxes = Axes.None, Width = 120 },
new DeleteSkinButton { Padding = new MarginPadding(), RelativeSizeAxes = Axes.None, Width = 110 },
new RenameSkinButton { Padding = new MarginPadding { Right = 2.5f }, RelativeSizeAxes = Axes.X, Width = 1 / 3f },
new ExportSkinButton { Padding = new MarginPadding { Horizontal = 2.5f }, RelativeSizeAxes = Axes.X, Width = 1 / 3f },
new DeleteSkinButton { Padding = new MarginPadding { Left = 2.5f }, RelativeSizeAxes = Axes.X, Width = 1 / 3f },
}
},
new SettingsButton
new SettingsButtonV2
{
Text = SkinSettingsStrings.SkinLayoutEditor,
Action = () => skinEditor?.ToggleVisibility(),
@@ -148,17 +147,12 @@ namespace osu.Game.Overlays.Settings.Sections
realmSubscription?.Dispose();
}
private partial class SkinSettingsDropdown : SettingsDropdown<Live<SkinInfo>>
private partial class SkinDropdown : FormDropdown<Live<SkinInfo>>
{
protected override OsuDropdown<Live<SkinInfo>> CreateDropdown() => new SkinDropdownControl();
private partial class SkinDropdownControl : DropdownControl
{
protected override LocalisableString GenerateItemText(Live<SkinInfo> item) => item.ToString();
}
protected override LocalisableString GenerateItemText(Live<SkinInfo> item) => item.ToString();
}
public partial class RenameSkinButton : SettingsButton, IHasPopover
public partial class RenameSkinButton : SettingsButtonV2, IHasPopover
{
[Resolved]
private SkinManager skins { get; set; }
@@ -189,7 +183,7 @@ namespace osu.Game.Overlays.Settings.Sections
}
}
public partial class ExportSkinButton : SettingsButton
public partial class ExportSkinButton : SettingsButtonV2
{
[Resolved]
private SkinManager skins { get; set; }
@@ -227,7 +221,7 @@ namespace osu.Game.Overlays.Settings.Sections
}
}
public partial class DeleteSkinButton : DangerousSettingsButton
public partial class DeleteSkinButton : DangerousSettingsButtonV2
{
[Resolved]
private SkinManager skins { get; set; }
@@ -3,9 +3,10 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.UserInterface
@@ -19,29 +20,33 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
{
Children = new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = UserInterfaceStrings.CursorRotation,
Caption = UserInterfaceStrings.CursorRotation,
Current = config.GetBindable<bool>(OsuSetting.CursorRotation)
},
new SettingsSlider<float, SizeSlider<float>>
}),
new SettingsItemV2(new FormSliderBar<float>
{
LabelText = UserInterfaceStrings.MenuCursorSize,
Caption = UserInterfaceStrings.MenuCursorSize,
Current = config.GetBindable<float>(OsuSetting.MenuCursorSize),
KeyboardStep = 0.01f
},
new SettingsCheckbox
KeyboardStep = 0.01f,
LabelFormat = v => $"{v:0.##}x"
}),
new SettingsItemV2(new FormCheckBox
{
LabelText = UserInterfaceStrings.Parallax,
Caption = UserInterfaceStrings.Parallax,
Current = config.GetBindable<bool>(OsuSetting.MenuParallax)
},
new SettingsSlider<double, TimeSlider>
}),
new SettingsItemV2(new FormSliderBar<double>
{
ClassicDefault = 0,
LabelText = UserInterfaceStrings.HoldToConfirmActivationTime,
Caption = UserInterfaceStrings.HoldToConfirmActivationTime,
Current = config.GetBindable<double>(OsuSetting.UIHoldActivationDelay),
KeyboardStep = 50,
LabelFormat = v => $"{v:N0} ms",
})
{
Keywords = new[] { @"delay" },
KeyboardStep = 50
ApplyClassicDefault = c => ((IHasCurrentValue<double>)c).Current.Value = 0,
},
};
}
@@ -1,13 +1,12 @@
// 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.
#nullable disable
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
@@ -18,9 +17,9 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
{
protected override LocalisableString Header => UserInterfaceStrings.MainMenuHeader;
private IBindable<APIUser> user;
private IBindable<APIUser> user = null!;
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown;
private readonly Bindable<SettingsNote.Data?> backgroundSourceNote = new Bindable<SettingsNote.Data?>();
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, IAPIProvider api)
@@ -29,38 +28,45 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
Children = new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = UserInterfaceStrings.ShowMenuTips,
Caption = UserInterfaceStrings.ShowMenuTips,
Current = config.GetBindable<bool>(OsuSetting.MenuTips)
},
new SettingsCheckbox
}),
new SettingsItemV2(new FormCheckBox
{
Keywords = new[] { "intro", "welcome" },
LabelText = UserInterfaceStrings.InterfaceVoices,
Caption = UserInterfaceStrings.InterfaceVoices,
Current = config.GetBindable<bool>(OsuSetting.MenuVoice)
},
new SettingsCheckbox
})
{
Keywords = new[] { "intro", "welcome" },
LabelText = UserInterfaceStrings.OsuMusicTheme,
},
new SettingsItemV2(new FormCheckBox
{
Caption = UserInterfaceStrings.OsuMusicTheme,
Current = config.GetBindable<bool>(OsuSetting.MenuMusic)
},
new SettingsEnumDropdown<IntroSequence>
})
{
LabelText = UserInterfaceStrings.IntroSequence,
Keywords = new[] { "intro", "welcome" },
},
new SettingsItemV2(new FormEnumDropdown<IntroSequence>
{
Caption = UserInterfaceStrings.IntroSequence,
Current = config.GetBindable<IntroSequence>(OsuSetting.IntroSequence),
},
backgroundSourceDropdown = new SettingsEnumDropdown<BackgroundSource>
}),
new SettingsItemV2(new FormEnumDropdown<BackgroundSource>
{
LabelText = UserInterfaceStrings.BackgroundSource,
Caption = UserInterfaceStrings.BackgroundSource,
Current = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource),
},
new SettingsEnumDropdown<SeasonalBackgroundMode>
})
{
LabelText = UserInterfaceStrings.SeasonalBackgrounds,
Note = { BindTarget = backgroundSourceNote },
},
new SettingsItemV2(new FormEnumDropdown<SeasonalBackgroundMode>
{
Caption = UserInterfaceStrings.SeasonalBackgrounds,
Current = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode),
}
})
};
}
@@ -71,9 +77,9 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
user.BindValueChanged(u =>
{
if (u.NewValue?.IsSupporter != true)
backgroundSourceDropdown.SetNoticeText(UserInterfaceStrings.NotSupporterNote, true);
backgroundSourceNote.Value = new SettingsNote.Data(UserInterfaceStrings.NotSupporterNote, SettingsNote.Type.Informational);
else
backgroundSourceDropdown.ClearNoticeText();
backgroundSourceNote.Value = null;
}, true);
}
}
@@ -3,8 +3,10 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osu.Game.Overlays.Mods.Input;
@@ -19,35 +21,40 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
{
Children = new Drawable[]
{
new SettingsCheckbox
new SettingsItemV2(new FormCheckBox
{
LabelText = UserInterfaceStrings.ShowConvertedBeatmaps,
Caption = UserInterfaceStrings.ShowConvertedBeatmaps,
Current = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps),
})
{
Keywords = new[] { "converts", "converted" }
},
new SettingsEnumDropdown<RandomSelectAlgorithm>
new SettingsItemV2(new FormEnumDropdown<RandomSelectAlgorithm>
{
LabelText = UserInterfaceStrings.RandomSelectionAlgorithm,
Caption = UserInterfaceStrings.RandomSelectionAlgorithm,
Current = config.GetBindable<RandomSelectAlgorithm>(OsuSetting.RandomSelectAlgorithm),
},
new SettingsEnumDropdown<ModSelectHotkeyStyle>
}),
new SettingsItemV2(new FormEnumDropdown<ModSelectHotkeyStyle>
{
LabelText = UserInterfaceStrings.ModSelectHotkeyStyle,
Caption = UserInterfaceStrings.ModSelectHotkeyStyle,
Current = config.GetBindable<ModSelectHotkeyStyle>(OsuSetting.ModSelectHotkeyStyle),
ClassicDefault = ModSelectHotkeyStyle.Classic
},
new SettingsCheckbox
})
{
LabelText = UserInterfaceStrings.ModSelectTextSearchStartsActive,
ApplyClassicDefault = c => ((IHasCurrentValue<ModSelectHotkeyStyle>)c).Current.Value = ModSelectHotkeyStyle.Classic,
},
new SettingsItemV2(new FormCheckBox
{
Caption = UserInterfaceStrings.ModSelectTextSearchStartsActive,
Current = config.GetBindable<bool>(OsuSetting.ModSelectTextSearchStartsActive),
ClassicDefault = false
},
new SettingsCheckbox
})
{
LabelText = GameplaySettingsStrings.BackgroundBlur,
ApplyClassicDefault = c => ((IHasCurrentValue<bool>)c).Current.Value = false,
},
new SettingsItemV2(new FormCheckBox
{
Caption = GameplaySettingsStrings.BackgroundBlur,
Current = config.GetBindable<bool>(OsuSetting.SongSelectBackgroundBlur),
ClassicDefault = false,
}
}),
};
}
}
@@ -0,0 +1,43 @@
// 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 osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Overlays.Settings
{
public partial class SettingsButtonV2 : RoundedButton, IConditionalFilterable
{
public SettingsButtonV2()
{
RelativeSizeAxes = Axes.X;
Margin = new MarginPadding { Vertical = -1.5f };
Padding = SettingsPanel.CONTENT_PADDING;
}
public IEnumerable<string> Keywords { get; set; } = Array.Empty<string>();
public BindableBool CanBeShown { get; } = new BindableBool(true);
IBindable<bool> IConditionalFilterable.CanBeShown => CanBeShown;
public override IEnumerable<LocalisableString> FilterTerms
{
get
{
if (TooltipText != default)
yield return TooltipText;
foreach (string s in Keywords)
yield return s;
foreach (LocalisableString s in base.FilterTerms)
yield return s;
}
}
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
Padding = new MarginPadding { Top = 20, Bottom = 30, Horizontal = SettingsPanel.CONTENT_MARGINS };
Padding = new MarginPadding { Top = 20, Bottom = 30, Left = SettingsPanel.CONTENT_PADDING.Left, Right = SettingsPanel.CONTENT_PADDING.Right };
FillFlowContainer modes;
+2 -1
View File
@@ -35,7 +35,8 @@ namespace osu.Game.Overlays.Settings
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding
{
Horizontal = SettingsPanel.CONTENT_MARGINS,
Left = SettingsPanel.CONTENT_PADDING.Left,
Right = SettingsPanel.CONTENT_PADDING.Right,
Top = Toolbar.Toolbar.TOOLTIP_HEIGHT,
Bottom = 30
}
+15 -14
View File
@@ -14,7 +14,8 @@ namespace osu.Game.Overlays.Settings
{
public sealed partial class SettingsItemV2 : CompositeDrawable, ISettingsItem, IConditionalFilterable
{
private readonly IFormControl control;
public readonly IFormControl Control;
private readonly SettingsRevertToDefaultButton revertButton;
private readonly BindableBool controlDefault = new BindableBool(true);
@@ -32,7 +33,7 @@ namespace osu.Game.Overlays.Settings
public SettingsItemV2(IFormControl control)
{
this.control = control;
Control = control;
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
@@ -41,7 +42,7 @@ namespace osu.Game.Overlays.Settings
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS_RIGHT },
Padding = SettingsPanel.CONTENT_PADDING,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
@@ -78,8 +79,8 @@ namespace osu.Game.Overlays.Settings
{
base.LoadComplete();
controlDefault.Value = control.IsDefault;
controlEnabled.Value = !control.IsDisabled;
controlDefault.Value = Control.IsDefault;
controlEnabled.Value = !Control.IsDisabled;
controlDefault.BindValueChanged(_ => updateDefaultState());
controlEnabled.BindValueChanged(_ => updateDefaultState(), true);
@@ -99,8 +100,8 @@ namespace osu.Game.Overlays.Settings
protected override void Update()
{
base.Update();
controlDefault.Value = control.IsDefault;
controlEnabled.Value = !control.IsDisabled;
controlDefault.Value = Control.IsDefault;
controlEnabled.Value = !Control.IsDisabled;
}
#region ISettingsItem
@@ -111,20 +112,20 @@ namespace osu.Game.Overlays.Settings
/// If set, this setting is considered as having a "classic" default value,
/// and this is the function for overwriting the control with that value.
/// </summary>
public Action? ApplyClassicDefault { get; set; }
public Action<IFormControl>? ApplyClassicDefault { get; set; }
void ISettingsItem.ApplyClassicDefault() => ApplyClassicDefault?.Invoke();
void ISettingsItem.ApplyClassicDefault() => ApplyClassicDefault?.Invoke(Control);
public void ApplyDefault()
{
if (!control.IsDisabled)
control.SetDefault();
if (!Control.IsDisabled)
Control.SetDefault();
}
public event Action SettingChanged
{
add => control.ValueChanged += value;
remove => control.ValueChanged -= value;
add => Control.ValueChanged += value;
remove => Control.ValueChanged -= value;
}
#endregion
@@ -140,7 +141,7 @@ namespace osu.Game.Overlays.Settings
get
{
var filterTerms = new List<LocalisableString>(Keywords.Select(k => (LocalisableString)k));
filterTerms.AddRange(control.FilterTerms);
filterTerms.AddRange(Control.FilterTerms);
if (HasClassicDefault)
filterTerms.Add(CLASSIC_DEFAULT_SEARCH_TERM);
@@ -26,6 +26,14 @@ namespace osu.Game.Overlays.Settings
[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;
public new MarginPadding Padding
{
get => base.Padding;
set => base.Padding = value;
}
public Anchor TextAnchor { get; init; } = Anchor.TopLeft;
[BackgroundDependencyLoader]
private void load()
{
@@ -53,6 +61,7 @@ namespace osu.Game.Overlays.Settings
},
text = new OsuTextFlowContainer(s => s.Font = OsuFont.Style.Caption1.With(weight: FontWeight.SemiBold))
{
TextAnchor = TextAnchor,
Padding = new MarginPadding(8),
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
@@ -35,6 +35,7 @@ namespace osu.Game.Overlays.Settings
public virtual IEnumerable<LocalisableString> FilterTerms => new[] { Header };
public const int ITEM_SPACING = 14;
public const int ITEM_SPACING_V2 = 7;
private const int header_size = 24;
private const int border_size = 4;
@@ -73,7 +74,7 @@ namespace osu.Game.Overlays.Settings
{
Top = 36
},
Spacing = new Vector2(0, ITEM_SPACING),
Spacing = new Vector2(0, ITEM_SPACING_V2),
Direction = FillDirection.Vertical,
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
@@ -114,10 +115,7 @@ namespace osu.Game.Overlays.Settings
{
Font = OsuFont.TorusAlternate.With(size: header_size),
Text = Header,
Margin = new MarginPadding
{
Horizontal = SettingsPanel.CONTENT_MARGINS
}
Margin = SettingsPanel.CONTENT_PADDING,
},
FlowContent
}
@@ -18,6 +18,8 @@ namespace osu.Game.Overlays.Settings
protected readonly FillFlowContainer FlowContent;
protected Container HeaderContainer { get; private set; } = null!;
protected abstract LocalisableString Header { get; }
public virtual IEnumerable<LocalisableString> FilterTerms => new[] { Header };
@@ -37,9 +39,9 @@ namespace osu.Game.Overlays.Settings
FlowContent = new FillFlowContainer
{
Margin = new MarginPadding { Top = SettingsSection.ITEM_SPACING },
Margin = new MarginPadding { Top = SettingsSection.ITEM_SPACING_V2 },
Direction = FillDirection.Vertical,
Spacing = new Vector2(0, SettingsSection.ITEM_SPACING),
Spacing = new Vector2(0, SettingsSection.ITEM_SPACING_V2),
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
};
@@ -53,11 +55,20 @@ namespace osu.Game.Overlays.Settings
{
AddRangeInternal(new Drawable[]
{
new OsuSpriteText
HeaderContainer = new Container
{
Text = Header,
Margin = new MarginPadding { Vertical = (header_height - header_font_size) * 0.5f, Horizontal = SettingsPanel.CONTENT_MARGINS },
Font = OsuFont.GetFont(size: header_font_size),
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = SettingsPanel.CONTENT_PADDING,
Children = new[]
{
new OsuSpriteText
{
Text = Header,
Font = OsuFont.GetFont(size: header_font_size),
Margin = new MarginPadding { Vertical = (header_height - header_font_size) * 0.5f },
},
},
},
FlowContent
});
+4 -3
View File
@@ -31,8 +31,8 @@ namespace osu.Game.Overlays
{
public const float CONTENT_MARGINS = 20;
// extra margin to give room to the revert-to-default button in settings controls.
public const float CONTENT_MARGINS_RIGHT = 30;
// extra right padding to give room to the revert-to-default button in settings controls.
public static readonly MarginPadding CONTENT_PADDING = new MarginPadding { Left = 20, Right = 30 };
public const float TRANSITION_LENGTH = 600;
@@ -134,7 +134,8 @@ namespace osu.Game.Overlays
Padding = new MarginPadding
{
Vertical = 20,
Horizontal = CONTENT_MARGINS
Left = CONTENT_PADDING.Left,
Right = CONTENT_PADDING.Right,
},
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,