Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement "form" check box control #29712

Merged
merged 4 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions osu.Game.Tests/Visual/UserInterface/TestSceneFormControls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using osu.Framework.Graphics.Cursor;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
using osuTK;

namespace osu.Game.Tests.Visual.UserInterface
Expand All @@ -25,7 +26,10 @@ public TestSceneFormControls()
RelativeSizeAxes = Axes.Both,
Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
RelativeSizeAxes = Axes.Y,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Width = 400,
Direction = FillDirection.Vertical,
Spacing = new Vector2(5),
Padding = new MarginPadding(10),
Expand Down Expand Up @@ -53,9 +57,20 @@ public TestSceneFormControls()
PlaceholderText = "Mine is 42!",
TabbableContentContainer = this,
},
new FormCheckBox
{
Caption = EditorSetupStrings.LetterboxDuringBreaks,
HintText = EditorSetupStrings.LetterboxDuringBreaksDescription,
},
new FormCheckBox
{
Caption = EditorSetupStrings.LetterboxDuringBreaks,
HintText = EditorSetupStrings.LetterboxDuringBreaksDescription,
Current = { Disabled = true },
},
},
},
},
}
};
}
}
154 changes: 154 additions & 0 deletions osu.Game/Graphics/UserInterfaceV2/FormCheckBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
using osu.Game.Overlays;

namespace osu.Game.Graphics.UserInterfaceV2
{
public partial class FormCheckBox : CompositeDrawable, IHasCurrentValue<bool>
{
public Bindable<bool> Current
{
get => current.Current;
set => current.Current = value;
}

private readonly BindableWithCurrent<bool> current = new BindableWithCurrent<bool>();

public LocalisableString Caption { get; init; }
public LocalisableString HintText { get; init; }

private Box background = null!;
private FormFieldCaption caption = null!;
private OsuSpriteText text = null!;
private Nub checkbox = null!;

private Sample? sampleChecked;
private Sample? sampleUnchecked;

[Resolved]
private OverlayColourProvider colourProvider { get; set; } = null!;

[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
RelativeSizeAxes = Axes.X;
Height = 50;

Masking = true;
CornerRadius = 5;
CornerExponent = 2.5f;

InternalChildren = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background5,
},
new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(9),
Children = new Drawable[]
{
caption = new FormFieldCaption
{
Caption = Caption,
TooltipText = HintText,
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft,
},
text = new OsuSpriteText
{
RelativeSizeAxes = Axes.X,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
},
checkbox = new Nub
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Current = Current,
},
},
},
};

sampleChecked = audio.Samples.Get(@"UI/check-on");
sampleUnchecked = audio.Samples.Get(@"UI/check-off");
}

protected override void LoadComplete()
{
base.LoadComplete();

current.BindValueChanged(_ =>
{
updateState();
playSamples();
background.FlashColour(ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Dark2), 800, Easing.OutQuint);
});
current.BindDisabledChanged(_ => updateState(), true);
}

private void playSamples()
{
if (Current.Value)
sampleChecked?.Play();
else
sampleUnchecked?.Play();
}

protected override bool OnHover(HoverEvent e)
{
updateState();
return true;
}

protected override void OnHoverLost(HoverLostEvent e)
{
base.OnHoverLost(e);
updateState();
}

protected override bool OnClick(ClickEvent e)
{
if (!Current.Disabled)
Current.Value = !Current.Value;
return true;
}

private void updateState()
{
background.Colour = Current.Disabled ? colourProvider.Background4 : colourProvider.Background5;
caption.Colour = Current.Disabled ? colourProvider.Foreground1 : colourProvider.Content2;
checkbox.Colour = Current.Disabled ? colourProvider.Foreground1 : colourProvider.Content1;
text.Colour = Current.Disabled ? colourProvider.Foreground1 : colourProvider.Content1;

text.Text = Current.Value ? CommonStrings.Enabled : CommonStrings.Disabled;

if (!Current.Disabled)
{
BorderThickness = IsHovered ? 2 : 0;

if (IsHovered)
BorderColour = colourProvider.Light4;
}
}
}
}
Loading