From d84d0310e09b00d120b263238c8c00349dc56d21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2024 12:56:03 +0900 Subject: [PATCH 1/3] Move mute button to master volume circle --- osu.Game/Overlays/Volume/MasterVolumeMeter.cs | 54 +++++++++++++++++++ osu.Game/Overlays/Volume/MuteButton.cs | 12 ++--- osu.Game/Overlays/Volume/VolumeMeter.cs | 16 +++--- osu.Game/Overlays/VolumeOverlay.cs | 53 ++++++++---------- 4 files changed, 93 insertions(+), 42 deletions(-) create mode 100644 osu.Game/Overlays/Volume/MasterVolumeMeter.cs diff --git a/osu.Game/Overlays/Volume/MasterVolumeMeter.cs b/osu.Game/Overlays/Volume/MasterVolumeMeter.cs new file mode 100644 index 0000000000..951a6d53b1 --- /dev/null +++ b/osu.Game/Overlays/Volume/MasterVolumeMeter.cs @@ -0,0 +1,54 @@ +// 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.Audio; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Volume +{ + public partial class MasterVolumeMeter : VolumeMeter + { + private MuteButton muteButton = null!; + + public Bindable IsMuted { get; } = new Bindable(); + + private readonly BindableDouble muteAdjustment = new BindableDouble(); + + [Resolved] + private VolumeOverlay volumeOverlay { get; set; } = null!; + + public MasterVolumeMeter(string name, float circleSize, Color4 meterColour) + : base(name, circleSize, meterColour) + { + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + IsMuted.BindValueChanged(muted => + { + if (muted.NewValue) + audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment); + else + audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment); + }); + + Add(muteButton = new MuteButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + X = CircleSize / 2, + Y = CircleSize * 0.23f, + Current = { BindTarget = IsMuted } + }); + + muteButton.Current.ValueChanged += _ => volumeOverlay.Show(); + } + + public void ToggleMute() => muteButton.Current.Value = !muteButton.Current.Value; + } +} diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 1dc8d754b7..a04d79bd20 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -35,16 +35,16 @@ namespace osu.Game.Overlays.Volume private Color4 hoveredColour, unhoveredColour; - private const float width = 100; - public const float HEIGHT = 35; - public MuteButton() { + const float width = 30; + const float height = 30; + Content.BorderThickness = 3; - Content.CornerRadius = HEIGHT / 2; + Content.CornerRadius = height / 2; Content.CornerExponent = 2; - Size = new Vector2(width, HEIGHT); + Size = new Vector2(width, height); Action = () => Current.Value = !Current.Value; } @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Volume [BackgroundDependencyLoader] private void load(OsuColour colours) { - hoveredColour = colours.YellowDark; + hoveredColour = colours.PinkLight; Content.BorderColour = unhoveredColour = colours.Gray1; BackgroundColour = colours.Gray1; diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index e96cd0fa46..9e0c599386 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -35,8 +35,12 @@ namespace osu.Game.Overlays.Volume private CircularProgress volumeCircle; private CircularProgress volumeCircleGlow; + protected static readonly Vector2 LABEL_SIZE = new Vector2(120, 20); + public BindableDouble Bindable { get; } = new BindableDouble { MinValue = 0, MaxValue = 1, Precision = 0.01 }; - private readonly float circleSize; + + protected readonly float CircleSize; + private readonly Color4 meterColour; private readonly string name; @@ -73,7 +77,7 @@ namespace osu.Game.Overlays.Volume public VolumeMeter(string name, float circleSize, Color4 meterColour) { - this.circleSize = circleSize; + CircleSize = circleSize; this.meterColour = meterColour; this.name = name; @@ -101,7 +105,7 @@ namespace osu.Game.Overlays.Volume { new Container { - Size = new Vector2(circleSize), + Size = new Vector2(CircleSize), Children = new Drawable[] { new BufferedContainer @@ -199,7 +203,7 @@ namespace osu.Game.Overlays.Volume { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.Numeric.With(size: 0.16f * circleSize) + Font = OsuFont.Numeric.With(size: 0.16f * CircleSize) }).WithEffect(new GlowEffect { Colour = Color4.Transparent, @@ -209,10 +213,10 @@ namespace osu.Game.Overlays.Volume }, new Container { - Size = new Vector2(120, 20), + Size = LABEL_SIZE, CornerRadius = 10, Masking = true, - Margin = new MarginPadding { Left = circleSize + 10 }, + Margin = new MarginPadding { Left = CircleSize + 10 }, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, Children = new Drawable[] diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index 6f9861c703..0d801ff118 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Bindables; @@ -20,21 +21,19 @@ using osuTK.Graphics; namespace osu.Game.Overlays { + [Cached] public partial class VolumeOverlay : VisibilityContainer { + public Bindable IsMuted { get; } = new Bindable(); + private const float offset = 10; private VolumeMeter volumeMeterMaster = null!; private VolumeMeter volumeMeterEffect = null!; private VolumeMeter volumeMeterMusic = null!; - private MuteButton muteButton = null!; private SelectionCycleFillFlowContainer volumeMeters = null!; - private readonly BindableDouble muteAdjustment = new BindableDouble(); - - public Bindable IsMuted { get; } = new Bindable(); - [BackgroundDependencyLoader] private void load(AudioManager audio, OsuColour colours) { @@ -49,14 +48,7 @@ namespace osu.Game.Overlays Width = 300, Colour = ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.75f), Color4.Black.Opacity(0)) }, - muteButton = new MuteButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding(10), - Current = { BindTarget = IsMuted } - }, - volumeMeters = new SelectionCycleFillFlowContainer + new FillFlowContainer { Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Both, @@ -64,26 +56,29 @@ namespace osu.Game.Overlays Origin = Anchor.CentreLeft, Spacing = new Vector2(0, offset), Margin = new MarginPadding { Left = offset }, - Children = new[] + Children = new Drawable[] { - volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker), - volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.PinkDarker), - volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.BlueDarker), - } - } + volumeMeters = new SelectionCycleFillFlowContainer + { + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Spacing = new Vector2(0, offset), + Children = new[] + { + volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker), + volumeMeterMaster = new MasterVolumeMeter("MASTER", 150, colours.PinkDarker) { IsMuted = { BindTarget = IsMuted }, }, + volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.BlueDarker), + } + }, + }, + }, }); volumeMeterMaster.Bindable.BindTo(audio.Volume); volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); - - IsMuted.BindValueChanged(muted => - { - if (muted.NewValue) - audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment); - else - audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment); - }); } protected override void LoadComplete() @@ -92,8 +87,6 @@ namespace osu.Game.Overlays foreach (var volumeMeter in volumeMeters) volumeMeter.Bindable.ValueChanged += _ => Show(); - - muteButton.Current.ValueChanged += _ => Show(); } public bool Adjust(GlobalAction action, float amount = 1, bool isPrecise = false) @@ -130,7 +123,7 @@ namespace osu.Game.Overlays case GlobalAction.ToggleMute: Show(); - muteButton.Current.Value = !muteButton.Current.Value; + volumeMeters.OfType().First().ToggleMute(); return true; } From fa9a835eb5366ea55def9aa280700c55b51ef28f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2024 19:29:23 +0900 Subject: [PATCH 2/3] Make icon smaller --- osu.Game/Overlays/Volume/MuteButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index a04d79bd20..bee5cce199 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -71,7 +71,7 @@ namespace osu.Game.Overlays.Volume Current.BindValueChanged(muted => { icon.Icon = muted.NewValue ? FontAwesome.Solid.VolumeMute : FontAwesome.Solid.VolumeUp; - icon.Size = new Vector2(muted.NewValue ? 18 : 20); + icon.Size = new Vector2(muted.NewValue ? 12 : 16); icon.Margin = new MarginPadding { Right = muted.NewValue ? 2 : 0 }; }, true); } From 179a3ad8dd31c8ecfb4684a2ad5529b91a87d1ae Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 9 Aug 2024 19:55:56 +0900 Subject: [PATCH 3/3] Hack around the border looking ugly This is an o!f issue because borders are applied into the individual sprites of the container via masking, rather than being isolated to the container itself. In this case, it'll be applied to the "flash" sprite, which is using additive blending, causing further issues. --- osu.Game/Overlays/Volume/MuteButton.cs | 32 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index bee5cce199..878842867d 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -7,13 +7,13 @@ 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.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Volume { @@ -33,29 +33,28 @@ namespace osu.Game.Overlays.Volume } } - private Color4 hoveredColour, unhoveredColour; + private ColourInfo hoveredBorderColour; + private ColourInfo unhoveredBorderColour; + private CompositeDrawable border = null!; public MuteButton() { const float width = 30; const float height = 30; - Content.BorderThickness = 3; + Size = new Vector2(width, height); Content.CornerRadius = height / 2; Content.CornerExponent = 2; - Size = new Vector2(width, height); - Action = () => Current.Value = !Current.Value; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - hoveredColour = colours.PinkLight; - - Content.BorderColour = unhoveredColour = colours.Gray1; BackgroundColour = colours.Gray1; + hoveredBorderColour = colours.PinkLight; + unhoveredBorderColour = colours.Gray1; SpriteIcon icon; @@ -65,6 +64,19 @@ namespace osu.Game.Overlays.Volume { Anchor = Anchor.Centre, Origin = Anchor.Centre, + }, + border = new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + BorderThickness = 3, + BorderColour = unhoveredBorderColour, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } } }); @@ -78,13 +90,13 @@ namespace osu.Game.Overlays.Volume protected override bool OnHover(HoverEvent e) { - Content.TransformTo, ColourInfo>("BorderColour", hoveredColour, 500, Easing.OutQuint); + border.TransformTo(nameof(BorderColour), hoveredBorderColour, 500, Easing.OutQuint); return false; } protected override void OnHoverLost(HoverLostEvent e) { - Content.TransformTo, ColourInfo>("BorderColour", unhoveredColour, 500, Easing.OutQuint); + border.TransformTo(nameof(BorderColour), unhoveredBorderColour, 500, Easing.OutQuint); } protected override bool OnMouseDown(MouseDownEvent e)