mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 03:25:11 +08:00
Share item cycling logic with GameplayMenuOverlay
This commit is contained in:
parent
3fe875efb2
commit
d495196b66
@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
showOverlay();
|
||||
|
||||
AddStep("Up arrow", () => InputManager.Key(Key.Up));
|
||||
AddAssert("Last button selected", () => pauseOverlay.Buttons.Last().Selected.Value);
|
||||
AddAssert("Last button selected", () => pauseOverlay.Buttons.Last().Selected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
showOverlay();
|
||||
|
||||
AddStep("Down arrow", () => InputManager.Key(Key.Down));
|
||||
AddAssert("First button selected", () => getButton(0).Selected.Value);
|
||||
AddAssert("First button selected", () => getButton(0).Selected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -111,11 +111,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("Show overlay", () => failOverlay.Show());
|
||||
|
||||
AddStep("Up arrow", () => InputManager.Key(Key.Up));
|
||||
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value);
|
||||
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected);
|
||||
AddStep("Up arrow", () => InputManager.Key(Key.Up));
|
||||
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value);
|
||||
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected);
|
||||
AddStep("Up arrow", () => InputManager.Key(Key.Up));
|
||||
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value);
|
||||
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -127,11 +127,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("Show overlay", () => failOverlay.Show());
|
||||
|
||||
AddStep("Down arrow", () => InputManager.Key(Key.Down));
|
||||
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value);
|
||||
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected);
|
||||
AddStep("Down arrow", () => InputManager.Key(Key.Down));
|
||||
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value);
|
||||
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected);
|
||||
AddStep("Down arrow", () => InputManager.Key(Key.Down));
|
||||
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value);
|
||||
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -145,7 +145,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("Hover first button", () => InputManager.MoveMouseTo(failOverlay.Buttons.First()));
|
||||
AddStep("Hide overlay", () => failOverlay.Hide());
|
||||
|
||||
AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected.Value));
|
||||
AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -162,11 +162,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("Hide overlay", () => pauseOverlay.Hide());
|
||||
showOverlay();
|
||||
|
||||
AddAssert("First button not selected", () => !getButton(0).Selected.Value);
|
||||
AddAssert("First button not selected", () => !getButton(0).Selected);
|
||||
|
||||
AddStep("Move slightly", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(1)));
|
||||
|
||||
AddAssert("First button selected", () => getButton(0).Selected.Value);
|
||||
AddAssert("First button selected", () => getButton(0).Selected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -179,8 +179,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
AddStep("Down arrow", () => InputManager.Key(Key.Down));
|
||||
AddStep("Hover second button", () => InputManager.MoveMouseTo(getButton(1)));
|
||||
AddAssert("First button not selected", () => !getButton(0).Selected.Value);
|
||||
AddAssert("Second button selected", () => getButton(1).Selected.Value);
|
||||
AddAssert("First button not selected", () => !getButton(0).Selected);
|
||||
AddAssert("Second button selected", () => getButton(1).Selected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -196,8 +196,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
AddStep("Hover second button", () => InputManager.MoveMouseTo(getButton(1)));
|
||||
AddStep("Up arrow", () => InputManager.Key(Key.Up));
|
||||
AddAssert("Second button not selected", () => !getButton(1).Selected.Value);
|
||||
AddAssert("First button selected", () => getButton(0).Selected.Value);
|
||||
AddAssert("Second button not selected", () => !getButton(1).Selected);
|
||||
AddAssert("First button selected", () => getButton(0).Selected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -211,7 +211,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("Hover second button", () => InputManager.MoveMouseTo(getButton(1)));
|
||||
AddStep("Unhover second button", () => InputManager.MoveMouseTo(Vector2.Zero));
|
||||
AddStep("Down arrow", () => InputManager.Key(Key.Down));
|
||||
AddAssert("First button selected", () => getButton(0).Selected.Value); // Initial state condition
|
||||
AddAssert("First button selected", () => getButton(0).Selected); // Initial state condition
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -282,7 +282,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
showOverlay();
|
||||
|
||||
AddAssert("No button selected",
|
||||
() => pauseOverlay.Buttons.All(button => !button.Selected.Value));
|
||||
() => pauseOverlay.Buttons.All(button => !button.Selected));
|
||||
}
|
||||
|
||||
private void showOverlay() => AddStep("Show overlay", () => pauseOverlay.Show());
|
||||
|
@ -0,0 +1,55 @@
|
||||
// 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.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, ISelectable
|
||||
{
|
||||
private int selectedIndex = -1;
|
||||
|
||||
private void setSelected(int value)
|
||||
{
|
||||
if (selectedIndex == value)
|
||||
return;
|
||||
|
||||
// Deselect the previously-selected button
|
||||
if (selectedIndex != -1)
|
||||
this[selectedIndex].Selected = false;
|
||||
|
||||
selectedIndex = value;
|
||||
|
||||
// Select the newly-selected button
|
||||
if (selectedIndex != -1)
|
||||
this[selectedIndex].Selected = true;
|
||||
}
|
||||
|
||||
public void SelectNext()
|
||||
{
|
||||
if (selectedIndex == -1 || selectedIndex == Count - 1)
|
||||
setSelected(0);
|
||||
else
|
||||
setSelected(selectedIndex + 1);
|
||||
}
|
||||
|
||||
public void SelectPrevious()
|
||||
{
|
||||
if (selectedIndex == -1 || selectedIndex == 0)
|
||||
setSelected(Count - 1);
|
||||
else
|
||||
setSelected(selectedIndex - 1);
|
||||
}
|
||||
|
||||
public void Deselect() => setSelected(-1);
|
||||
public void Select(T item) => setSelected(IndexOf(item));
|
||||
|
||||
public T Selected => (selectedIndex >= 0 && selectedIndex < Count) ? this[selectedIndex] : null;
|
||||
}
|
||||
}
|
@ -2,24 +2,24 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Bindables;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
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, ISelectable
|
||||
{
|
||||
private const float idle_width = 0.8f;
|
||||
private const float hover_width = 0.9f;
|
||||
@ -27,7 +27,13 @@ namespace osu.Game.Graphics.UserInterface
|
||||
private const float hover_duration = 500;
|
||||
private const float click_duration = 200;
|
||||
|
||||
public readonly BindableBool Selected = new BindableBool();
|
||||
public readonly BindableBool SelectedBindable = new BindableBool();
|
||||
|
||||
public bool Selected
|
||||
{
|
||||
get => SelectedBindable.Value;
|
||||
set => SelectedBindable.Value = value;
|
||||
}
|
||||
|
||||
private readonly Container backgroundContainer;
|
||||
private readonly Container colourContainer;
|
||||
@ -153,7 +159,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
updateGlow();
|
||||
|
||||
Selected.ValueChanged += selectionChanged;
|
||||
SelectedBindable.ValueChanged += selectionChanged;
|
||||
}
|
||||
|
||||
private Color4 buttonColour;
|
||||
@ -221,7 +227,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
.OnComplete(_ =>
|
||||
{
|
||||
clickAnimating = false;
|
||||
Selected.TriggerChange();
|
||||
SelectedBindable.TriggerChange();
|
||||
});
|
||||
|
||||
return base.OnClick(e);
|
||||
@ -235,7 +241,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
|
||||
protected override void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
if (Selected.Value)
|
||||
if (Selected)
|
||||
colourContainer.ResizeWidthTo(hover_width, click_duration, Easing.In);
|
||||
base.OnMouseUp(e);
|
||||
}
|
||||
@ -243,7 +249,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
base.OnHover(e);
|
||||
Selected.Value = true;
|
||||
Selected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -251,7 +257,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
base.OnHoverLost(e);
|
||||
Selected.Value = false;
|
||||
Selected = false;
|
||||
}
|
||||
|
||||
private void selectionChanged(ValueChangedEvent<bool> args)
|
||||
|
10
osu.Game/Graphics/UserInterface/ISelectable.cs
Normal file
10
osu.Game/Graphics/UserInterface/ISelectable.cs
Normal file
@ -0,0 +1,10 @@
|
||||
// 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.
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
{
|
||||
public interface ISelectable
|
||||
{
|
||||
bool Selected { get; set; }
|
||||
}
|
||||
}
|
@ -19,13 +19,14 @@ using osu.Framework.Threading;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Volume
|
||||
{
|
||||
public class VolumeMeter : Container, IKeyBindingHandler<GlobalAction>
|
||||
public class VolumeMeter : Container, IKeyBindingHandler<GlobalAction>, ISelectable
|
||||
{
|
||||
private CircularProgress volumeCircle;
|
||||
private CircularProgress volumeCircleGlow;
|
||||
@ -43,7 +44,13 @@ namespace osu.Game.Overlays.Volume
|
||||
private Sample sample;
|
||||
private double sampleLastPlaybackTime;
|
||||
|
||||
public Action<VolumeMeter> RequestFocus;
|
||||
public BindableBool SelectedBindable = new BindableBool();
|
||||
|
||||
public bool Selected
|
||||
{
|
||||
get => SelectedBindable.Value;
|
||||
set => SelectedBindable.Value = value;
|
||||
}
|
||||
|
||||
public VolumeMeter(string name, float circleSize, Color4 meterColour)
|
||||
{
|
||||
@ -212,6 +219,8 @@ namespace osu.Game.Overlays.Volume
|
||||
Bindable.BindValueChanged(volume => { this.TransformTo(nameof(DisplayVolume), volume.NewValue, 400, Easing.OutQuint); }, true);
|
||||
|
||||
bgProgress.Current.Value = 0.75f;
|
||||
|
||||
SelectedBindable.ValueChanged += selectionChanged;
|
||||
}
|
||||
|
||||
private int? displayVolumeInt;
|
||||
@ -330,21 +339,9 @@ namespace osu.Game.Overlays.Volume
|
||||
|
||||
private const float transition_length = 500;
|
||||
|
||||
public void Focus()
|
||||
{
|
||||
this.ScaleTo(1.04f, transition_length, Easing.OutExpo);
|
||||
focusGlowContainer.FadeIn(transition_length, Easing.OutExpo);
|
||||
}
|
||||
|
||||
public void Unfocus()
|
||||
{
|
||||
this.ScaleTo(1f, transition_length, Easing.OutExpo);
|
||||
focusGlowContainer.FadeOut(transition_length, Easing.OutExpo);
|
||||
}
|
||||
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
RequestFocus?.Invoke(this);
|
||||
Selected = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -352,6 +349,20 @@ namespace osu.Game.Overlays.Volume
|
||||
{
|
||||
}
|
||||
|
||||
private void selectionChanged(ValueChangedEvent<bool> selected)
|
||||
{
|
||||
if (selected.NewValue)
|
||||
{
|
||||
this.ScaleTo(1.04f, transition_length, Easing.OutExpo);
|
||||
focusGlowContainer.FadeIn(transition_length, Easing.OutExpo);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ScaleTo(1f, transition_length, Easing.OutExpo);
|
||||
focusGlowContainer.FadeOut(transition_length, Easing.OutExpo);
|
||||
}
|
||||
}
|
||||
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
if (!IsHovered)
|
||||
@ -360,12 +371,12 @@ namespace osu.Game.Overlays.Volume
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.SelectPrevious:
|
||||
RequestFocus?.Invoke(this);
|
||||
Selected = true;
|
||||
adjust(1, false);
|
||||
return true;
|
||||
|
||||
case GlobalAction.SelectNext:
|
||||
RequestFocus?.Invoke(this);
|
||||
Selected = true;
|
||||
adjust(-1, false);
|
||||
return true;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Overlays.Volume;
|
||||
using osuTK;
|
||||
@ -32,7 +33,7 @@ namespace osu.Game.Overlays
|
||||
|
||||
public Bindable<bool> IsMuted { get; } = new Bindable<bool>();
|
||||
|
||||
private FillFlowContainer<VolumeMeter> volumeMeters;
|
||||
private SelectionCycleFillFlowContainer<VolumeMeter> volumeMeters;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio, OsuColour colours)
|
||||
@ -55,7 +56,7 @@ namespace osu.Game.Overlays
|
||||
Margin = new MarginPadding(10),
|
||||
Current = { BindTarget = IsMuted }
|
||||
},
|
||||
volumeMeters = new FillFlowContainer<VolumeMeter>
|
||||
volumeMeters = new SelectionCycleFillFlowContainer<VolumeMeter>
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
@ -65,18 +66,9 @@ namespace osu.Game.Overlays
|
||||
Margin = new MarginPadding { Left = offset },
|
||||
Children = new[]
|
||||
{
|
||||
volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker)
|
||||
{
|
||||
RequestFocus = v => focusedMeter.Value = v
|
||||
},
|
||||
volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.PinkDarker)
|
||||
{
|
||||
RequestFocus = v => focusedMeter.Value = v
|
||||
},
|
||||
volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.BlueDarker)
|
||||
{
|
||||
RequestFocus = v => focusedMeter.Value = v
|
||||
},
|
||||
volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker),
|
||||
volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.PinkDarker),
|
||||
volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.BlueDarker),
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -92,23 +84,18 @@ namespace osu.Game.Overlays
|
||||
else
|
||||
audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment);
|
||||
});
|
||||
|
||||
focusedMeter.BindValueChanged(meter =>
|
||||
{
|
||||
meter.OldValue?.Unfocus();
|
||||
meter.NewValue?.Focus();
|
||||
});
|
||||
}
|
||||
|
||||
private readonly Bindable<VolumeMeter> focusedMeter = new Bindable<VolumeMeter>();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
volumeMeterMaster.Bindable.ValueChanged += _ => Show();
|
||||
volumeMeterEffect.Bindable.ValueChanged += _ => Show();
|
||||
volumeMeterMusic.Bindable.ValueChanged += _ => Show();
|
||||
foreach (var volumeMeter in volumeMeters)
|
||||
{
|
||||
volumeMeter.Bindable.ValueChanged += _ => Show();
|
||||
volumeMeter.SelectedBindable.ValueChanged += selected => volumeMeterSelectionChanged(volumeMeter, selected.NewValue);
|
||||
}
|
||||
|
||||
muteButton.Current.ValueChanged += _ => Show();
|
||||
}
|
||||
|
||||
@ -122,28 +109,26 @@ namespace osu.Game.Overlays
|
||||
if (State.Value == Visibility.Hidden)
|
||||
Show();
|
||||
else
|
||||
focusedMeter.Value.Decrease(amount, isPrecise);
|
||||
volumeMeters.Selected?.Decrease(amount, isPrecise);
|
||||
return true;
|
||||
|
||||
case GlobalAction.IncreaseVolume:
|
||||
if (State.Value == Visibility.Hidden)
|
||||
Show();
|
||||
else
|
||||
focusedMeter.Value.Increase(amount, isPrecise);
|
||||
volumeMeters.Selected?.Increase(amount, isPrecise);
|
||||
return true;
|
||||
|
||||
case GlobalAction.NextVolumeMeter:
|
||||
if (State.Value == Visibility.Hidden)
|
||||
Show();
|
||||
else
|
||||
focusShift(1);
|
||||
if (State.Value == Visibility.Visible)
|
||||
volumeMeters.SelectNext();
|
||||
Show();
|
||||
return true;
|
||||
|
||||
case GlobalAction.PreviousVolumeMeter:
|
||||
if (State.Value == Visibility.Hidden)
|
||||
Show();
|
||||
else
|
||||
focusShift(-1);
|
||||
if (State.Value == Visibility.Visible)
|
||||
volumeMeters.SelectPrevious();
|
||||
Show();
|
||||
return true;
|
||||
|
||||
case GlobalAction.ToggleMute:
|
||||
@ -155,15 +140,12 @@ namespace osu.Game.Overlays
|
||||
return false;
|
||||
}
|
||||
|
||||
private void focusShift(int direction = 1)
|
||||
private void volumeMeterSelectionChanged(VolumeMeter meter, bool isSelected)
|
||||
{
|
||||
Show();
|
||||
|
||||
var newIndex = volumeMeters.IndexOf(focusedMeter.Value) + direction;
|
||||
if (newIndex < 0)
|
||||
newIndex += volumeMeters.Count;
|
||||
|
||||
focusedMeter.Value = volumeMeters.Children[newIndex % volumeMeters.Count];
|
||||
if (!isSelected)
|
||||
volumeMeters.Deselect();
|
||||
else
|
||||
volumeMeters.Select(meter);
|
||||
}
|
||||
|
||||
private ScheduledDelegate popOutDelegate;
|
||||
@ -172,7 +154,7 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
// Focus on the master meter as a default if previously hidden
|
||||
if (State.Value == Visibility.Hidden)
|
||||
focusedMeter.Value = volumeMeterMaster;
|
||||
volumeMeters.Select(volumeMeterMaster);
|
||||
|
||||
if (State.Value == Visibility.Visible)
|
||||
schedulePopOut();
|
||||
|
@ -2,23 +2,24 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Humanizer;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input.Bindings;
|
||||
using Humanizer;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
@ -41,18 +42,18 @@ namespace osu.Game.Screens.Play
|
||||
/// <summary>
|
||||
/// Action that is invoked when <see cref="GlobalAction.Back"/> is triggered.
|
||||
/// </summary>
|
||||
protected virtual Action BackAction => () => InternalButtons.Children.LastOrDefault()?.Click();
|
||||
protected virtual Action BackAction => () => InternalButtons.Selected?.Click();
|
||||
|
||||
/// <summary>
|
||||
/// Action that is invoked when <see cref="GlobalAction.Select"/> is triggered.
|
||||
/// </summary>
|
||||
protected virtual Action SelectAction => () => InternalButtons.Children.FirstOrDefault(f => f.Selected.Value)?.Click();
|
||||
protected virtual Action SelectAction => () => InternalButtons.Selected?.Click();
|
||||
|
||||
public abstract string Header { get; }
|
||||
|
||||
public abstract string Description { get; }
|
||||
|
||||
protected ButtonContainer InternalButtons;
|
||||
protected SelectionCycleFillFlowContainer<DialogButton> InternalButtons;
|
||||
public IReadOnlyList<DialogButton> Buttons => InternalButtons;
|
||||
|
||||
private FillFlowContainer retryCounterContainer;
|
||||
@ -116,7 +117,7 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
}
|
||||
},
|
||||
InternalButtons = new ButtonContainer
|
||||
InternalButtons = new SelectionCycleFillFlowContainer<DialogButton>
|
||||
{
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
@ -183,7 +184,7 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
};
|
||||
|
||||
button.Selected.ValueChanged += selected => buttonSelectionChanged(button, selected.NewValue);
|
||||
button.SelectedBindable.ValueChanged += selected => buttonSelectionChanged(button, selected.NewValue);
|
||||
|
||||
InternalButtons.Add(button);
|
||||
}
|
||||
@ -255,46 +256,6 @@ namespace osu.Game.Screens.Play
|
||||
};
|
||||
}
|
||||
|
||||
protected class ButtonContainer : FillFlowContainer<DialogButton>
|
||||
{
|
||||
private int selectedIndex = -1;
|
||||
|
||||
private void setSelected(int value)
|
||||
{
|
||||
if (selectedIndex == value)
|
||||
return;
|
||||
|
||||
// Deselect the previously-selected button
|
||||
if (selectedIndex != -1)
|
||||
this[selectedIndex].Selected.Value = false;
|
||||
|
||||
selectedIndex = value;
|
||||
|
||||
// Select the newly-selected button
|
||||
if (selectedIndex != -1)
|
||||
this[selectedIndex].Selected.Value = true;
|
||||
}
|
||||
|
||||
public void SelectNext()
|
||||
{
|
||||
if (selectedIndex == -1 || selectedIndex == Count - 1)
|
||||
setSelected(0);
|
||||
else
|
||||
setSelected(selectedIndex + 1);
|
||||
}
|
||||
|
||||
public void SelectPrevious()
|
||||
{
|
||||
if (selectedIndex == -1 || selectedIndex == 0)
|
||||
setSelected(Count - 1);
|
||||
else
|
||||
setSelected(selectedIndex - 1);
|
||||
}
|
||||
|
||||
public void Deselect() => setSelected(-1);
|
||||
public void Select(DialogButton button) => setSelected(IndexOf(button));
|
||||
}
|
||||
|
||||
private class Button : DialogButton
|
||||
{
|
||||
// required to ensure keyboard navigation always starts from an extremity (unless the cursor is moved)
|
||||
@ -302,7 +263,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
Selected.Value = true;
|
||||
Selected = true;
|
||||
return base.OnMouseMove(e);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user