mirror of
https://github.com/ppy/osu.git
synced 2026-05-23 09:40:16 +08:00
Rewrite input settings and use new form controls
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -112,7 +112,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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
||||
{
|
||||
this.handler = handler;
|
||||
|
||||
Padding = new MarginPadding { Horizontal = SettingsPanel.CONTENT_MARGINS };
|
||||
Padding = SettingsPanel.ContentPaddingV2;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
||||
@@ -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.ContentPaddingV2,
|
||||
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.ContentPaddingV2,
|
||||
},
|
||||
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,179 @@
|
||||
// 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;
|
||||
|
||||
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()
|
||||
{
|
||||
if (toggleable && IsHovered)
|
||||
headerText.FadeColour(colourProvider.Light1, 300, Easing.OutQuint);
|
||||
else
|
||||
headerText.FadeColour(Current.Value ? colourProvider.Content1 : colourProvider.Foreground1, 300, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 };
|
||||
@@ -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.ContentPaddingV2,
|
||||
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
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user