mirror of
https://github.com/osukey/osukey.git
synced 2025-05-18 20:17:23 +09:00
Implement ability to switch between volume meters
This commit is contained in:
parent
49090a0d1b
commit
d1553f0864
@ -103,6 +103,9 @@ namespace osu.Game.Input.Bindings
|
|||||||
new KeyBinding(new[] { InputKey.Alt, InputKey.Up }, GlobalAction.IncreaseVolume),
|
new KeyBinding(new[] { InputKey.Alt, InputKey.Up }, GlobalAction.IncreaseVolume),
|
||||||
new KeyBinding(new[] { InputKey.Alt, InputKey.Down }, GlobalAction.DecreaseVolume),
|
new KeyBinding(new[] { InputKey.Alt, InputKey.Down }, GlobalAction.DecreaseVolume),
|
||||||
|
|
||||||
|
new KeyBinding(new[] { InputKey.Alt, InputKey.Left }, GlobalAction.PreviousVolumeMeter),
|
||||||
|
new KeyBinding(new[] { InputKey.Alt, InputKey.Right }, GlobalAction.NextVolumeMeter),
|
||||||
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.F4 }, GlobalAction.ToggleMute),
|
new KeyBinding(new[] { InputKey.Control, InputKey.F4 }, GlobalAction.ToggleMute),
|
||||||
|
|
||||||
new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev),
|
new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev),
|
||||||
@ -263,5 +266,11 @@ namespace osu.Game.Input.Bindings
|
|||||||
|
|
||||||
[Description("Toggle skin editor")]
|
[Description("Toggle skin editor")]
|
||||||
ToggleSkinEditor,
|
ToggleSkinEditor,
|
||||||
|
|
||||||
|
[Description("Previous volume meter")]
|
||||||
|
PreviousVolumeMeter,
|
||||||
|
|
||||||
|
[Description("Next volume meter")]
|
||||||
|
NextVolumeMeter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@ namespace osu.Game.Overlays.Volume
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GlobalAction.ToggleMute:
|
case GlobalAction.ToggleMute:
|
||||||
|
case GlobalAction.NextVolumeMeter:
|
||||||
|
case GlobalAction.PreviousVolumeMeter:
|
||||||
ActionRequested?.Invoke(action);
|
ActionRequested?.Invoke(action);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Transforms;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
@ -27,6 +28,11 @@ namespace osu.Game.Overlays.Volume
|
|||||||
{
|
{
|
||||||
public class VolumeMeter : Container, IKeyBindingHandler<GlobalAction>
|
public class VolumeMeter : Container, IKeyBindingHandler<GlobalAction>
|
||||||
{
|
{
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private Bindable<VolumeMeter> focusedMeter { get; set; }
|
||||||
|
|
||||||
|
private bool isFocused => focusedMeter == null || focusedMeter.Value == this;
|
||||||
|
|
||||||
private CircularProgress volumeCircle;
|
private CircularProgress volumeCircle;
|
||||||
private CircularProgress volumeCircleGlow;
|
private CircularProgress volumeCircleGlow;
|
||||||
|
|
||||||
@ -41,6 +47,8 @@ namespace osu.Game.Overlays.Volume
|
|||||||
private Sample sample;
|
private Sample sample;
|
||||||
private double sampleLastPlaybackTime;
|
private double sampleLastPlaybackTime;
|
||||||
|
|
||||||
|
public Action<VolumeMeter> RequestFocus;
|
||||||
|
|
||||||
public VolumeMeter(string name, float circleSize, Color4 meterColour)
|
public VolumeMeter(string name, float circleSize, Color4 meterColour)
|
||||||
{
|
{
|
||||||
this.circleSize = circleSize;
|
this.circleSize = circleSize;
|
||||||
@ -310,20 +318,32 @@ namespace osu.Game.Overlays.Volume
|
|||||||
|
|
||||||
private const float transition_length = 500;
|
private const float transition_length = 500;
|
||||||
|
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
if (focusedMeter != null)
|
||||||
|
focusedMeter.Value = this;
|
||||||
|
|
||||||
|
this.ScaleTo(1.04f, transition_length, Easing.OutExpo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unfocus()
|
||||||
|
{
|
||||||
|
this.ScaleTo(1f, transition_length, Easing.OutExpo);
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
this.ScaleTo(1.04f, transition_length, Easing.OutExpo);
|
Focus();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnHoverLost(HoverLostEvent e)
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
{
|
{
|
||||||
this.ScaleTo(1f, transition_length, Easing.OutExpo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(GlobalAction action)
|
public bool OnPressed(GlobalAction action)
|
||||||
{
|
{
|
||||||
if (!IsHovered)
|
if (!IsHovered || !isFocused)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (action)
|
switch (action)
|
||||||
|
@ -19,6 +19,7 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
|
[Cached]
|
||||||
public class VolumeOverlay : VisibilityContainer
|
public class VolumeOverlay : VisibilityContainer
|
||||||
{
|
{
|
||||||
private const float offset = 10;
|
private const float offset = 10;
|
||||||
@ -32,6 +33,8 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
public Bindable<bool> IsMuted { get; } = new Bindable<bool>();
|
public Bindable<bool> IsMuted { get; } = new Bindable<bool>();
|
||||||
|
|
||||||
|
private FillFlowContainer<VolumeMeter> volumeMeters;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, OsuColour colours)
|
private void load(AudioManager audio, OsuColour colours)
|
||||||
{
|
{
|
||||||
@ -53,7 +56,7 @@ namespace osu.Game.Overlays
|
|||||||
Margin = new MarginPadding(10),
|
Margin = new MarginPadding(10),
|
||||||
Current = { BindTarget = IsMuted }
|
Current = { BindTarget = IsMuted }
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
volumeMeters = new FillFlowContainer<VolumeMeter>
|
||||||
{
|
{
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
@ -61,7 +64,7 @@ namespace osu.Game.Overlays
|
|||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Spacing = new Vector2(0, offset),
|
Spacing = new Vector2(0, offset),
|
||||||
Margin = new MarginPadding { Left = offset },
|
Margin = new MarginPadding { Left = offset },
|
||||||
Children = new Drawable[]
|
Children = new VolumeMeter[]
|
||||||
{
|
{
|
||||||
volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker),
|
volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker),
|
||||||
volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.PinkDarker),
|
volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.PinkDarker),
|
||||||
@ -81,8 +84,13 @@ namespace osu.Game.Overlays
|
|||||||
else
|
else
|
||||||
audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment);
|
audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
focusedMeter.BindValueChanged(meter => meter.OldValue?.Unfocus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private Bindable<VolumeMeter> focusedMeter = new Bindable<VolumeMeter>();
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -93,6 +101,23 @@ namespace osu.Game.Overlays
|
|||||||
muteButton.Current.ValueChanged += _ => Show();
|
muteButton.Current.ValueChanged += _ => Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HandleAction(GlobalAction action)
|
||||||
|
{
|
||||||
|
if (!IsLoaded) return false;
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case GlobalAction.DecreaseVolume:
|
||||||
|
case GlobalAction.IncreaseVolume:
|
||||||
|
return Adjust(action);
|
||||||
|
case GlobalAction.NextVolumeMeter:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Adjust(GlobalAction action, float amount = 1, bool isPrecise = false)
|
public bool Adjust(GlobalAction action, float amount = 1, bool isPrecise = false)
|
||||||
{
|
{
|
||||||
if (!IsLoaded) return false;
|
if (!IsLoaded) return false;
|
||||||
@ -102,25 +127,32 @@ namespace osu.Game.Overlays
|
|||||||
case GlobalAction.DecreaseVolume:
|
case GlobalAction.DecreaseVolume:
|
||||||
if (State.Value == Visibility.Hidden)
|
if (State.Value == Visibility.Hidden)
|
||||||
Show();
|
Show();
|
||||||
else if (volumeMeterMusic.IsHovered)
|
|
||||||
volumeMeterMusic.Decrease(amount, isPrecise);
|
|
||||||
else if (volumeMeterEffect.IsHovered)
|
|
||||||
volumeMeterEffect.Decrease(amount, isPrecise);
|
|
||||||
else
|
else
|
||||||
volumeMeterMaster.Decrease(amount, isPrecise);
|
focusedMeter.Value.Decrease(amount, isPrecise);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GlobalAction.IncreaseVolume:
|
case GlobalAction.IncreaseVolume:
|
||||||
if (State.Value == Visibility.Hidden)
|
if (State.Value == Visibility.Hidden)
|
||||||
Show();
|
Show();
|
||||||
else if (volumeMeterMusic.IsHovered)
|
|
||||||
volumeMeterMusic.Increase(amount, isPrecise);
|
|
||||||
else if (volumeMeterEffect.IsHovered)
|
|
||||||
volumeMeterEffect.Increase(amount, isPrecise);
|
|
||||||
else
|
else
|
||||||
volumeMeterMaster.Increase(amount, isPrecise);
|
focusedMeter.Value.Increase(amount, isPrecise);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case GlobalAction.NextVolumeMeter:
|
||||||
|
if (State.Value == Visibility.Hidden)
|
||||||
|
Show();
|
||||||
|
else
|
||||||
|
focusShift(1);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case GlobalAction.PreviousVolumeMeter:
|
||||||
|
if (State.Value == Visibility.Hidden)
|
||||||
|
Show();
|
||||||
|
else
|
||||||
|
focusShift(-1);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
case GlobalAction.ToggleMute:
|
case GlobalAction.ToggleMute:
|
||||||
Show();
|
Show();
|
||||||
muteButton.Current.Value = !muteButton.Current.Value;
|
muteButton.Current.Value = !muteButton.Current.Value;
|
||||||
@ -130,10 +162,23 @@ namespace osu.Game.Overlays
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void focusShift(int direction = 1)
|
||||||
|
{
|
||||||
|
Show();
|
||||||
|
var newIndex = volumeMeters.IndexOf(focusedMeter.Value) + direction;
|
||||||
|
if (newIndex < 0)
|
||||||
|
newIndex += volumeMeters.Count;
|
||||||
|
|
||||||
|
volumeMeters.Children[newIndex % volumeMeters.Count].Focus();
|
||||||
|
}
|
||||||
|
|
||||||
private ScheduledDelegate popOutDelegate;
|
private ScheduledDelegate popOutDelegate;
|
||||||
|
|
||||||
public override void Show()
|
public override void Show()
|
||||||
{
|
{
|
||||||
|
if (State.Value == Visibility.Hidden)
|
||||||
|
volumeMeterMaster.Focus();
|
||||||
|
|
||||||
if (State.Value == Visibility.Visible)
|
if (State.Value == Visibility.Visible)
|
||||||
schedulePopOut();
|
schedulePopOut();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user