From 46dfb761c57e1804576760ce217ddf4a44544cba Mon Sep 17 00:00:00 2001 From: jorolf Date: Wed, 28 Feb 2018 16:14:52 +0100 Subject: [PATCH] basic volume meter and testcase --- .../Visual/TestCaseVolumeControl.cs | 29 +++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + osu.Game/Overlays/Volume/MuteButton.cs | 58 ++++++ osu.Game/Overlays/Volume/VolumeMeter.cs | 193 ++++++++++++++++++ osu.Game/osu.Game.csproj | 2 + 5 files changed, 283 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseVolumeControl.cs create mode 100644 osu.Game/Overlays/Volume/MuteButton.cs create mode 100644 osu.Game/Overlays/Volume/VolumeMeter.cs diff --git a/osu.Game.Tests/Visual/TestCaseVolumeControl.cs b/osu.Game.Tests/Visual/TestCaseVolumeControl.cs new file mode 100644 index 0000000000..04390d6d19 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseVolumeControl.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Graphics; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Overlays.Volume; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseVolumeControl : TestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + VolumeMeter meter; + Add(meter = new VolumeMeter("MASTER", 125, colours.PinkDarker)); + Add(new MuteButton + { + Margin = new MarginPadding { Top = 200 } + }); + + meter.Bindable.BindTo(audio.Volume); + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8301f1f734..63adbc8b43 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -162,6 +162,7 @@ + diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs new file mode 100644 index 0000000000..b45034c166 --- /dev/null +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -0,0 +1,58 @@ +using osu.Framework.Allocation; +using osu.Framework.Configuration; +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; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Overlays.Volume +{ + public class MuteButton : Container, IHasCurrentValue + { + public Bindable Current { get; } = new Bindable(); + + private Color4 hoveredColour, unhoveredColour; + + public MuteButton() + { + Masking = true; + BorderThickness = 3; + CornerRadius = 20; + Size = new Vector2(100, 40); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoveredColour = colours.YellowDark; + BorderColour = unhoveredColour = colours.Gray1.Opacity(0.9f); + + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.9f, + }, + }); + } + + protected override bool OnHover(InputState state) + { + this.TransformTo("BorderColour", hoveredColour, 500, Easing.OutQuint); + return true; + } + + protected override void OnHoverLost(InputState state) + { + this.TransformTo("BorderColour", unhoveredColour, 500, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs new file mode 100644 index 0000000000..3351dbed9a --- /dev/null +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -0,0 +1,193 @@ +using System; +using System.Globalization; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Bindings; +using osu.Framework.MathUtils; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Input.Bindings; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Overlays.Volume +{ + public class VolumeMeter : Container, IKeyBindingHandler + { + private CircularProgress volumeCircle; + public BindableDouble Bindable { get; } = new BindableDouble(); + private readonly float circleSize; + private readonly Color4 meterColour; + private readonly string name; + + public VolumeMeter(string name, float circleSize, Color4 meterColour) + { + this.circleSize = circleSize; + this.meterColour = meterColour; + this.name = name; + + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Add(new Container + { + Size = new Vector2(120, 20), + CornerRadius = 10, + Masking = true, + Margin = new MarginPadding { Left = circleSize + 10 }, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.9f, + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Exo2.0-Bold", + Text = name + } + } + }); + + + OsuSpriteText text, maxText; + CircularProgress bgProgress; + BufferedContainer maxGlow; + + Add(new CircularContainer + { + Masking = true, + Size = new Vector2(circleSize), + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.9f, + }, + bgProgress = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = 0.05f, + Rotation = 180, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = colours.Gray2, + Size = new Vector2(0.8f) + }, + (volumeCircle = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = 0.05f, + Rotation = 180, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0.8f) + }).WithEffect(new GlowEffect + { + Colour = meterColour, + Strength = 2 + }), + maxGlow = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Venera", + Text = "MAX", + TextSize = 0.16f * circleSize + }.WithEffect(new GlowEffect + { + Colour = meterColour, + PadExtent = true, + Strength = 2, + }), + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Venera", + TextSize = 0.16f * circleSize + } + } + }); + + Bindable.ValueChanged += newVolume => this.TransformTo("circleBindable", newVolume * 0.75, 250, Easing.OutQuint); + volumeCircle.Current.ValueChanged += newVolume => + { + if (newVolume > 0.745) + { + text.Alpha = 0; + maxGlow.Alpha = 1; //show "MAX" + } + else + { + text.Text = Math.Round(newVolume / 0.0075).ToString(CultureInfo.CurrentCulture); + text.Alpha = 1; + maxGlow.Alpha = 0; + } + }; + + bgProgress.Current.Value = 0.75f; + } + + /// + /// This is needed because doesn't support + /// + private double circleBindable + { + get => volumeCircle.Current; + set => volumeCircle.Current.Value = value; + } + + public double Volume + { + get => Bindable; + private set => Bindable.Value = value; + } + + public void Increase() + { + Volume += 0.05f; + } + + public void Decrease() + { + Volume -= 0.05f; + } + + public bool OnPressed(GlobalAction action) + { + if (!IsHovered) return false; + + switch (action) + { + case GlobalAction.DecreaseVolume: + Decrease(); + return true; + case GlobalAction.IncreaseVolume: + Increase(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4944613828..b94da5badb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -330,6 +330,8 @@ + +