mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 15:16:38 +09:00
Merge pull request #13771 from LumpBloom7/volume-meter-switch
Add ability to navigate between volume meters via Alt+Left/Right arrows
This commit is contained in:
@ -0,0 +1,87 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
namespace osu.Game.Graphics.Containers
|
||||
{
|
||||
/// <summary>
|
||||
/// A FillFlowContainer that provides functionality to cycle selection between children
|
||||
/// The selection wraps around when overflowing past the first or last child.
|
||||
/// </summary>
|
||||
public class SelectionCycleFillFlowContainer<T> : FillFlowContainer<T> where T : Drawable, IStateful<SelectionState>
|
||||
{
|
||||
public T Selected => (selectedIndex >= 0 && selectedIndex < Count) ? this[selectedIndex.Value] : null;
|
||||
|
||||
private int? selectedIndex;
|
||||
|
||||
public void SelectNext()
|
||||
{
|
||||
if (!selectedIndex.HasValue || selectedIndex == Count - 1)
|
||||
setSelected(0);
|
||||
else
|
||||
setSelected(selectedIndex.Value + 1);
|
||||
}
|
||||
|
||||
public void SelectPrevious()
|
||||
{
|
||||
if (!selectedIndex.HasValue || selectedIndex == 0)
|
||||
setSelected(Count - 1);
|
||||
else
|
||||
setSelected(selectedIndex.Value - 1);
|
||||
}
|
||||
|
||||
public void Deselect() => setSelected(null);
|
||||
|
||||
public void Select(T item)
|
||||
{
|
||||
var newIndex = IndexOf(item);
|
||||
|
||||
if (newIndex < 0)
|
||||
setSelected(null);
|
||||
else
|
||||
setSelected(IndexOf(item));
|
||||
}
|
||||
|
||||
public override void Add(T drawable)
|
||||
{
|
||||
base.Add(drawable);
|
||||
|
||||
Debug.Assert(drawable != null);
|
||||
|
||||
drawable.StateChanged += state => selectionChanged(drawable, state);
|
||||
}
|
||||
|
||||
public override bool Remove(T drawable)
|
||||
=> throw new NotSupportedException($"Cannot remove drawables from {nameof(SelectionCycleFillFlowContainer<T>)}");
|
||||
|
||||
private void setSelected(int? value)
|
||||
{
|
||||
if (selectedIndex == value)
|
||||
return;
|
||||
|
||||
// Deselect the previously-selected button
|
||||
if (selectedIndex.HasValue)
|
||||
this[selectedIndex.Value].State = SelectionState.NotSelected;
|
||||
|
||||
selectedIndex = value;
|
||||
|
||||
// Select the newly-selected button
|
||||
if (selectedIndex.HasValue)
|
||||
this[selectedIndex.Value].State = SelectionState.Selected;
|
||||
}
|
||||
|
||||
private void selectionChanged(T drawable, SelectionState state)
|
||||
{
|
||||
if (state == SelectionState.NotSelected)
|
||||
Deselect();
|
||||
else
|
||||
Select(drawable);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +1,26 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Bindables;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using System;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public class DialogButton : OsuClickableContainer
|
||||
public class DialogButton : OsuClickableContainer, IStateful<SelectionState>
|
||||
{
|
||||
private const float idle_width = 0.8f;
|
||||
private const float hover_width = 0.9f;
|
||||
@ -27,7 +28,22 @@ namespace osu.Game.Graphics.UserInterface
|
||||
private const float hover_duration = 500;
|
||||
private const float click_duration = 200;
|
||||
|
||||
public readonly BindableBool Selected = new BindableBool();
|
||||
public event Action<SelectionState> StateChanged;
|
||||
|
||||
private SelectionState state;
|
||||
|
||||
public SelectionState State
|
||||
{
|
||||
get => state;
|
||||
set
|
||||
{
|
||||
if (state == value)
|
||||
return;
|
||||
|
||||
state = value;
|
||||
StateChanged?.Invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Container backgroundContainer;
|
||||
private readonly Container colourContainer;
|
||||
@ -153,7 +169,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
updateGlow();
|
||||
|
||||
Selected.ValueChanged += selectionChanged;
|
||||
StateChanged += selectionChanged;
|
||||
}
|
||||
|
||||
private Color4 buttonColour;
|
||||
@ -221,7 +237,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
.OnComplete(_ =>
|
||||
{
|
||||
clickAnimating = false;
|
||||
Selected.TriggerChange();
|
||||
StateChanged?.Invoke(State);
|
||||
});
|
||||
|
||||
return base.OnClick(e);
|
||||
@ -235,7 +251,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
protected override void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
if (Selected.Value)
|
||||
if (State == SelectionState.Selected)
|
||||
colourContainer.ResizeWidthTo(hover_width, click_duration, Easing.In);
|
||||
base.OnMouseUp(e);
|
||||
}
|
||||
@ -243,7 +259,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
base.OnHover(e);
|
||||
Selected.Value = true;
|
||||
State = SelectionState.Selected;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -251,15 +267,15 @@ namespace osu.Game.Graphics.UserInterface
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
Selected.Value = false;
|
||||
State = SelectionState.NotSelected;
|
||||
}
|
||||
|
||||
private void selectionChanged(ValueChangedEvent<bool> args)
|
||||
private void selectionChanged(SelectionState newState)
|
||||
{
|
||||
if (clickAnimating)
|
||||
return;
|
||||
|
||||
if (args.NewValue)
|
||||
if (newState == SelectionState.Selected)
|
||||
{
|
||||
spriteText.TransformSpacingTo(hoverSpacing, hover_duration, Easing.OutElastic);
|
||||
colourContainer.ResizeWidthTo(hover_width, hover_duration, Easing.OutElastic);
|
||||
|
Reference in New Issue
Block a user