Merge pull request #24199 from peppy/revert-to-default-design-change

Update design of "revert to default" button
This commit is contained in:
Bartłomiej Dach 2023-07-13 23:44:24 +02:00 committed by GitHub
commit cdbb6f90be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 122 additions and 138 deletions

View File

@ -195,16 +195,16 @@ public void TestSingleBindingResetButton()
InputManager.ReleaseKey(Key.P);
});
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<RestoreDefaultValueButton<bool>>().First().Alpha > 0);
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha > 0);
AddStep("click reset button for bindings", () =>
{
var resetButton = settingsKeyBindingRow.ChildrenOfType<RestoreDefaultValueButton<bool>>().First();
var resetButton = settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First();
resetButton.TriggerClick();
});
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<RestoreDefaultValueButton<bool>>().First().Alpha == 0);
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha == 0);
AddAssert("binding cleared",
() => settingsKeyBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0)));
@ -225,7 +225,7 @@ public void TestResetAllBindingsButton()
InputManager.ReleaseKey(Key.P);
});
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<RestoreDefaultValueButton<bool>>().First().Alpha > 0);
AddUntilStep("restore button shown", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha > 0);
AddStep("click reset button for bindings", () =>
{
@ -234,7 +234,7 @@ public void TestResetAllBindingsButton()
resetButton.TriggerClick();
});
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<RestoreDefaultValueButton<bool>>().First().Alpha == 0);
AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType<RevertToDefaultButton<bool>>().First().Alpha == 0);
AddAssert("binding cleared",
() => settingsKeyBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0)));

View File

@ -1,65 +0,0 @@
// 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 NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Tests.Visual.Settings
{
public partial class TestSceneRestoreDefaultValueButton : OsuTestScene
{
[Resolved]
private OsuColour colours { get; set; }
private float scale = 1;
private readonly Bindable<float> current = new Bindable<float>
{
Default = default,
Value = 1,
};
[Test]
public void TestBasic()
{
RestoreDefaultValueButton<float> restoreDefaultValueButton = null;
AddStep("create button", () => Child = new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colours.GreySeaFoam
},
restoreDefaultValueButton = new RestoreDefaultValueButton<float>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(scale),
Current = current,
}
}
});
AddSliderStep("set scale", 1, 4, 1, scale =>
{
this.scale = scale;
if (restoreDefaultValueButton != null)
restoreDefaultValueButton.Scale = new Vector2(scale);
});
AddToggleStep("toggle default state", state => current.Value = state ? default : 1);
AddToggleStep("toggle disabled state", state => current.Disabled = state);
}
}
}

View File

@ -0,0 +1,53 @@
// 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 NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Overlays;
using osu.Game.Tests.Visual.UserInterface;
using osuTK;
namespace osu.Game.Tests.Visual.Settings
{
public partial class TestSceneRevertToDefaultButton : ThemeComparisonTestScene
{
private float scale = 1;
private readonly Bindable<float> current = new Bindable<float>
{
Default = default,
Value = 1,
};
protected override Drawable CreateContent() => new Container
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Child = new RevertToDefaultButton<float>
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(scale),
Current = current,
}
};
[Test]
public void TestStates()
{
AddStep("create content", () => CreateThemedContent(OverlayColourScheme.Purple));
AddSliderStep("set scale", 1, 4, 1, scale =>
{
this.scale = scale;
foreach (var revertToDefaultButton in this.ChildrenOfType<RevertToDefaultButton<float>>())
revertToDefaultButton.Parent!.Scale = new Vector2(scale);
});
AddToggleStep("toggle default state", state => current.Value = state ? default : 1);
AddToggleStep("toggle disabled state", state => current.Disabled = state);
}
}
}

View File

@ -23,7 +23,7 @@ public partial class TestSceneSettingsItem : OsuTestScene
public void TestRestoreDefaultValueButtonVisibility()
{
SettingsTextBox textBox = null;
RestoreDefaultValueButton<string> restoreDefaultValueButton = null;
RevertToDefaultButton<string> revertToDefaultButton = null;
AddStep("create settings item", () =>
{
@ -33,22 +33,22 @@ public void TestRestoreDefaultValueButtonVisibility()
};
});
AddUntilStep("wait for loaded", () => textBox.IsLoaded);
AddStep("retrieve restore default button", () => restoreDefaultValueButton = textBox.ChildrenOfType<RestoreDefaultValueButton<string>>().Single());
AddStep("retrieve restore default button", () => revertToDefaultButton = textBox.ChildrenOfType<RevertToDefaultButton<string>>().Single());
AddAssert("restore button hidden", () => restoreDefaultValueButton.Alpha == 0);
AddAssert("restore button hidden", () => revertToDefaultButton.Alpha == 0);
AddStep("change value from default", () => textBox.Current.Value = "non-default");
AddUntilStep("restore button shown", () => restoreDefaultValueButton.Alpha > 0);
AddUntilStep("restore button shown", () => revertToDefaultButton.Alpha > 0);
AddStep("restore default", () => textBox.Current.SetDefault());
AddUntilStep("restore button hidden", () => restoreDefaultValueButton.Alpha == 0);
AddUntilStep("restore button hidden", () => revertToDefaultButton.Alpha == 0);
}
[Test]
public void TestSetAndClearLabelText()
{
SettingsTextBox textBox = null;
RestoreDefaultValueButton<string> restoreDefaultValueButton = null;
RevertToDefaultButton<string> revertToDefaultButton = null;
OsuTextBox control = null;
AddStep("create settings item", () =>
@ -61,25 +61,25 @@ public void TestSetAndClearLabelText()
AddUntilStep("wait for loaded", () => textBox.IsLoaded);
AddStep("retrieve components", () =>
{
restoreDefaultValueButton = textBox.ChildrenOfType<RestoreDefaultValueButton<string>>().Single();
revertToDefaultButton = textBox.ChildrenOfType<RevertToDefaultButton<string>>().Single();
control = textBox.ChildrenOfType<OsuTextBox>().Single();
});
AddStep("set non-default value", () => restoreDefaultValueButton.Current.Value = "non-default");
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, control.DrawHeight, 1));
AddStep("set non-default value", () => revertToDefaultButton.Current.Value = "non-default");
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(revertToDefaultButton.Parent.DrawHeight, control.DrawHeight, 1));
AddStep("set label", () => textBox.LabelText = "label text");
AddAssert("default value button centre aligned to label size", () =>
{
var label = textBox.ChildrenOfType<OsuSpriteText>().Single(spriteText => spriteText.Text == "label text");
return Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, label.DrawHeight, 1);
return Precision.AlmostEquals(revertToDefaultButton.Parent.DrawHeight, label.DrawHeight, 1);
});
AddStep("clear label", () => textBox.LabelText = default);
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, control.DrawHeight, 1));
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(revertToDefaultButton.Parent.DrawHeight, control.DrawHeight, 1));
AddStep("set warning text", () => textBox.SetNoticeText("This is some very important warning text! Hopefully it doesn't break the alignment of the default value indicator...", true));
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(restoreDefaultValueButton.Parent.DrawHeight, control.DrawHeight, 1));
AddAssert("default value button centre aligned to control size", () => Precision.AlmostEquals(revertToDefaultButton.Parent.DrawHeight, control.DrawHeight, 1));
}
/// <summary>
@ -92,7 +92,7 @@ public void TestRestoreDefaultValueButtonPrecision(float initialValue)
{
BindableFloat current = null;
SettingsSlider<float> sliderBar = null;
RestoreDefaultValueButton<float> restoreDefaultValueButton = null;
RevertToDefaultButton<float> revertToDefaultButton = null;
AddStep("create settings item", () =>
{
@ -107,15 +107,15 @@ public void TestRestoreDefaultValueButtonPrecision(float initialValue)
};
});
AddUntilStep("wait for loaded", () => sliderBar.IsLoaded);
AddStep("retrieve restore default button", () => restoreDefaultValueButton = sliderBar.ChildrenOfType<RestoreDefaultValueButton<float>>().Single());
AddStep("retrieve restore default button", () => revertToDefaultButton = sliderBar.ChildrenOfType<RevertToDefaultButton<float>>().Single());
AddAssert("restore button hidden", () => restoreDefaultValueButton.Alpha == 0);
AddAssert("restore button hidden", () => revertToDefaultButton.Alpha == 0);
AddStep("change value to next closest", () => sliderBar.Current.Value += current.Precision * 0.6f);
AddUntilStep("restore button shown", () => restoreDefaultValueButton.Alpha > 0);
AddUntilStep("restore button shown", () => revertToDefaultButton.Alpha > 0);
AddStep("restore default", () => sliderBar.Current.SetDefault());
AddUntilStep("restore button hidden", () => restoreDefaultValueButton.Alpha == 0);
AddUntilStep("restore button hidden", () => revertToDefaultButton.Alpha == 0);
}
[Test]

View File

@ -793,7 +793,7 @@ public void TestModMultiplierUpdates()
AddStep("open customisation area", () => modSelectOverlay.CustomisationButton!.TriggerClick());
AddStep("reset half time speed to default", () => modSelectOverlay.ChildrenOfType<ModSettingsArea>().Single()
.ChildrenOfType<RestoreDefaultValueButton<double>>().Single().TriggerClick());
.ChildrenOfType<RevertToDefaultButton<double>>().Single().TriggerClick());
AddUntilStep("difficulty multiplier display shows correct value", () => modSelectOverlay.ChildrenOfType<DifficultyMultiplierDisplay>().Single().Current.Value, () => Is.EqualTo(0.7));
}

View File

@ -1,28 +1,25 @@
// 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.Extensions.Color4Extensions;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osuTK;
using osu.Game.Localisation;
using osuTK;
namespace osu.Game.Overlays
{
public partial class RestoreDefaultValueButton<T> : OsuClickableContainer, IHasCurrentValue<T>
public partial class RevertToDefaultButton<T> : OsuClickableContainer, IHasCurrentValue<T>
{
public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks;
@ -31,11 +28,20 @@ public partial class RestoreDefaultValueButton<T> : OsuClickableContainer, IHasC
// this is intentionally not using BindableWithCurrent, as it can use the wrong IsDefault implementation when passed a BindableNumber.
// using GetBoundCopy() ensures that the received bindable is of the exact same type as the source bindable and uses the proper IsDefault implementation.
private Bindable<T> current;
private Bindable<T>? current;
private SpriteIcon icon = null!;
private Circle circle = null!;
[Resolved]
private OsuColour colours { get; set; } = null!;
[Resolved]
private OverlayColourProvider? colourProvider { get; set; }
public Bindable<T> Current
{
get => current;
get => current.AsNonNull();
set
{
current?.UnbindAll();
@ -50,43 +56,36 @@ public Bindable<T> Current
}
}
[Resolved]
private OsuColour colours { get; set; }
private const float size = 4;
private CircularContainer circle = null!;
private Box background = null!;
public RestoreDefaultValueButton()
public RevertToDefaultButton()
: base(HoverSampleSet.Button)
{
}
[BackgroundDependencyLoader]
private void load(OsuColour colour)
private void load()
{
// size intentionally much larger than actual drawn content, so that the button is easier to click.
Size = new Vector2(3 * size);
Size = new Vector2(14);
Add(circle = new CircularContainer
AddRange(new Drawable[]
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(size),
Masking = true,
Child = background = new Box
circle = new Circle
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Colour = colour.Lime1
},
icon = new SpriteIcon
{
Icon = FontAwesome.Solid.Undo,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(8),
}
});
Alpha = 0f;
Action += () =>
{
if (!current.Disabled)
if (current?.Disabled == false)
current.SetDefault();
};
}
@ -120,28 +119,25 @@ private void updateState()
if (current == null)
return;
Enabled.Value = !Current.Disabled;
Enabled.Value = !current.Disabled;
if (!Current.Disabled)
this.FadeTo(current.Disabled ? 0.2f : (current.IsDefault ? 0 : 1), fade_duration, Easing.OutQuint);
if (IsHovered && Enabled.Value)
{
this.FadeTo(Current.IsDefault ? 0 : 1, fade_duration, Easing.OutQuint);
background.FadeColour(IsHovered ? colours.Lime0 : colours.Lime1, fade_duration, Easing.OutQuint);
circle.TweenEdgeEffectTo(new EdgeEffectParameters
{
Colour = (IsHovered ? colours.Lime1 : colours.Lime3).Opacity(0.4f),
Radius = IsHovered ? 8 : 4,
Type = EdgeEffectType.Glow
}, fade_duration, Easing.OutQuint);
icon.RotateTo(-40, 500, Easing.OutQuint);
icon.FadeColour(colourProvider?.Light1 ?? colours.YellowLight, 300, Easing.OutQuint);
circle.FadeColour(colourProvider?.Background2 ?? colours.Gray6, 300, Easing.OutQuint);
this.ScaleTo(1.2f, 300, Easing.OutQuint);
}
else
{
background.FadeColour(colours.Lime3, fade_duration, Easing.OutQuint);
circle.TweenEdgeEffectTo(new EdgeEffectParameters
{
Colour = colours.Lime3.Opacity(0.1f),
Radius = 2,
Type = EdgeEffectType.Glow
}, fade_duration, Easing.OutQuint);
icon.RotateTo(0, 100, Easing.OutQuint);
icon.FadeColour(colourProvider?.Colour0 ?? colours.Yellow, 100, Easing.OutQuint);
circle.FadeColour(colourProvider?.Background3 ?? colours.Gray3, 100, Easing.OutQuint);
this.ScaleTo(1f, 100, Easing.OutQuint);
}
}
}

View File

@ -103,7 +103,7 @@ private void load(OverlayColourProvider colourProvider)
{
RelativeSizeAxes = Axes.Y,
Width = SettingsPanel.CONTENT_MARGINS,
Child = new RestoreDefaultValueButton<bool>
Child = new RevertToDefaultButton<bool>
{
Current = isDefault,
Action = RestoreDefaults,

View File

@ -217,7 +217,7 @@ private void load()
// intentionally done before LoadComplete to avoid overhead.
if (ShowsDefaultIndicator)
{
defaultValueIndicatorContainer.Add(new RestoreDefaultValueButton<T>
defaultValueIndicatorContainer.Add(new RevertToDefaultButton<T>
{
Current = controlWithCurrent.Current,
Anchor = Anchor.Centre,