From 028c958431728deb42811a92a3993f2382ee49a6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 20 Sep 2019 19:19:43 +0900 Subject: [PATCH] Initial implementation of a switch button --- .../UserInterface/TestSceneSwitchButton.cs | 20 +++ .../Graphics/UserInterface/SwitchButton.cs | 117 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs create mode 100644 osu.Game/Graphics/UserInterface/SwitchButton.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs new file mode 100644 index 0000000000..8fe381f141 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneSwitchButton : OsuTestScene + { + public TestSceneSwitchButton() + { + Child = new SwitchButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + } + } +} diff --git a/osu.Game/Graphics/UserInterface/SwitchButton.cs b/osu.Game/Graphics/UserInterface/SwitchButton.cs new file mode 100644 index 0000000000..21712051ef --- /dev/null +++ b/osu.Game/Graphics/UserInterface/SwitchButton.cs @@ -0,0 +1,117 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Graphics.UserInterface +{ + public class SwitchButton : Checkbox + { + private const float border_thickness = 4.5f; + private const float padding = 1.25f; + + private readonly Box fill; + private readonly Container switchContainer; + private readonly Drawable switchCircle; + private readonly CircularBorderContainer circularContainer; + + private Color4 enabledColour; + private Color4 disabledColour; + + public SwitchButton() + { + Size = new Vector2(45, 20); + + InternalChild = circularContainer = new CircularBorderContainer + { + RelativeSizeAxes = Axes.Both, + BorderColour = Color4.White, + BorderThickness = border_thickness, + Masking = true, + Children = new Drawable[] + { + fill = new Box + { + RelativeSizeAxes = Axes.Both, + AlwaysPresent = true, + Alpha = 0 + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(border_thickness + padding), + Child = switchContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Child = switchCircle = new CircularContainer + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + Masking = true, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + enabledColour = colours.BlueDark; + disabledColour = colours.Gray3; + + switchContainer.Colour = enabledColour; + fill.Colour = disabledColour; + + updateBorder(); + } + + protected override void OnUserChange(bool value) + { + base.OnUserChange(value); + + if (value) + switchCircle.MoveToX(switchContainer.DrawWidth - switchCircle.DrawWidth, 200, Easing.OutQuint); + else + switchCircle.MoveToX(0, 200, Easing.OutQuint); + + fill.FadeTo(value ? 1 : 0, 250, Easing.OutQuint); + + updateBorder(); + } + + protected override bool OnHover(HoverEvent e) + { + updateBorder(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + updateBorder(); + base.OnHoverLost(e); + } + + private void updateBorder() + { + circularContainer.TransformBorderTo((Current.Value ? enabledColour : disabledColour).Lighten(IsHovered ? 0.3f : 0)); + } + + private class CircularBorderContainer : CircularContainer + { + public void TransformBorderTo(SRGBColour colour) + => this.TransformTo(nameof(BorderColour), colour, 250, Easing.OutQuint); + } + } +}