mirror of
https://github.com/ppy/osu.git
synced 2024-11-14 15:57:24 +08:00
Split KeyBindingRow
out into partial pieces
This commit is contained in:
parent
8e609b6f1d
commit
9b0c4acdef
@ -0,0 +1,75 @@
|
|||||||
|
// 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 osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Settings.Sections.Input
|
||||||
|
{
|
||||||
|
public partial class KeyBindingRow : IHasPopover
|
||||||
|
{
|
||||||
|
private readonly Bindable<KeyBindingConflictInfo> keyBindingConflictInfo = new Bindable<KeyBindingConflictInfo>();
|
||||||
|
|
||||||
|
public Popover GetPopover() => new KeyBindingConflictPopover
|
||||||
|
{
|
||||||
|
ConflictInfo = { BindTarget = keyBindingConflictInfo },
|
||||||
|
BindingConflictResolved = () => BindingUpdated?.Invoke(this, new KeyBindingUpdatedEventArgs(bindingConflictResolved: true, canAdvanceToNextBinding: false))
|
||||||
|
};
|
||||||
|
|
||||||
|
private void showBindingConflictPopover(KeyBindingConflictInfo conflictInfo)
|
||||||
|
{
|
||||||
|
keyBindingConflictInfo.Value = conflictInfo;
|
||||||
|
this.ShowPopover();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains information about the key binding conflict to be resolved.
|
||||||
|
/// </summary>
|
||||||
|
public class KeyBindingConflictInfo
|
||||||
|
{
|
||||||
|
public ConflictingKeyBinding Existing { get; }
|
||||||
|
public ConflictingKeyBinding New { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains information about the key binding conflict to be resolved.
|
||||||
|
/// </summary>
|
||||||
|
public KeyBindingConflictInfo(ConflictingKeyBinding existingBinding, ConflictingKeyBinding newBinding)
|
||||||
|
{
|
||||||
|
Existing = existingBinding;
|
||||||
|
New = newBinding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConflictingKeyBinding
|
||||||
|
{
|
||||||
|
public Guid ID { get; }
|
||||||
|
public object Action { get; }
|
||||||
|
public KeyCombination CombinationWhenChosen { get; }
|
||||||
|
public KeyCombination CombinationWhenNotChosen { get; }
|
||||||
|
|
||||||
|
public ConflictingKeyBinding(Guid id, object action, KeyCombination combinationWhenChosen, KeyCombination combinationWhenNotChosen)
|
||||||
|
{
|
||||||
|
ID = id;
|
||||||
|
Action = action;
|
||||||
|
CombinationWhenChosen = combinationWhenChosen;
|
||||||
|
CombinationWhenNotChosen = combinationWhenNotChosen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class KeyBindingUpdatedEventArgs
|
||||||
|
{
|
||||||
|
public bool BindingConflictResolved { get; }
|
||||||
|
public bool CanAdvanceToNextBinding { get; }
|
||||||
|
|
||||||
|
public KeyBindingUpdatedEventArgs(bool bindingConflictResolved, bool canAdvanceToNextBinding)
|
||||||
|
{
|
||||||
|
BindingConflictResolved = bindingConflictResolved;
|
||||||
|
CanAdvanceToNextBinding = canAdvanceToNextBinding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,168 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Input;
|
||||||
|
using osu.Game.Input.Bindings;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Settings.Sections.Input
|
||||||
|
{
|
||||||
|
public partial class KeyBindingRow
|
||||||
|
{
|
||||||
|
public partial class KeyButton : Container
|
||||||
|
{
|
||||||
|
public Bindable<RealmKeyBinding> KeyBinding { get; } = new Bindable<RealmKeyBinding>();
|
||||||
|
|
||||||
|
private readonly Box box;
|
||||||
|
public readonly OsuSpriteText Text;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OverlayColourProvider colourProvider { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private ReadableKeyCombinationProvider keyCombinationProvider { get; set; } = null!;
|
||||||
|
|
||||||
|
private bool isBinding;
|
||||||
|
|
||||||
|
public bool IsBinding
|
||||||
|
{
|
||||||
|
get => isBinding;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == isBinding) return;
|
||||||
|
|
||||||
|
isBinding = value;
|
||||||
|
|
||||||
|
updateHoverState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyButton()
|
||||||
|
{
|
||||||
|
Margin = new MarginPadding(padding);
|
||||||
|
|
||||||
|
Masking = true;
|
||||||
|
CornerRadius = padding;
|
||||||
|
|
||||||
|
Height = height;
|
||||||
|
AutoSizeAxes = Axes.X;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
AlwaysPresent = true,
|
||||||
|
Width = 80,
|
||||||
|
Height = height,
|
||||||
|
},
|
||||||
|
box = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
Text = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Font = OsuFont.Numeric.With(size: 10),
|
||||||
|
Margin = new MarginPadding(5),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
},
|
||||||
|
new HoverSounds()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
KeyBinding.BindValueChanged(_ =>
|
||||||
|
{
|
||||||
|
if (KeyBinding.Value.IsManaged)
|
||||||
|
throw new ArgumentException("Key binding should not be attached as we make temporary changes", nameof(KeyBinding));
|
||||||
|
|
||||||
|
updateKeyCombinationText();
|
||||||
|
});
|
||||||
|
keyCombinationProvider.KeymapChanged += updateKeyCombinationText;
|
||||||
|
updateKeyCombinationText();
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
updateHoverState();
|
||||||
|
FinishTransforms(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
{
|
||||||
|
updateHoverState();
|
||||||
|
return base.OnHover(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
|
{
|
||||||
|
updateHoverState();
|
||||||
|
base.OnHoverLost(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHoverState()
|
||||||
|
{
|
||||||
|
if (isBinding)
|
||||||
|
{
|
||||||
|
box.FadeColour(colourProvider.Light2, transition_time, Easing.OutQuint);
|
||||||
|
Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
box.FadeColour(IsHovered ? colourProvider.Light4 : colourProvider.Background6, transition_time, Easing.OutQuint);
|
||||||
|
Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update from a key combination, only allowing a single non-modifier key to be specified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fullState">A <see cref="KeyCombination"/> generated from the full input state.</param>
|
||||||
|
/// <param name="triggerKey">The key which triggered this update, and should be used as the binding.</param>
|
||||||
|
public void UpdateKeyCombination(KeyCombination fullState, InputKey triggerKey) =>
|
||||||
|
UpdateKeyCombination(new KeyCombination(fullState.Keys.Where(KeyCombination.IsModifierKey).Append(triggerKey)));
|
||||||
|
|
||||||
|
public void UpdateKeyCombination(KeyCombination newCombination)
|
||||||
|
{
|
||||||
|
if (KeyBinding.Value.RulesetName != null && !RealmKeyBindingStore.CheckValidForGameplay(newCombination))
|
||||||
|
return;
|
||||||
|
|
||||||
|
KeyBinding.Value.KeyCombination = newCombination;
|
||||||
|
updateKeyCombinationText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateKeyCombinationText()
|
||||||
|
{
|
||||||
|
Scheduler.AddOnce(updateText);
|
||||||
|
|
||||||
|
void updateText() => Text.Text = keyCombinationProvider.GetReadableString(KeyBinding.Value.KeyCombination);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
if (keyCombinationProvider.IsNotNull())
|
||||||
|
keyCombinationProvider.KeymapChanged -= updateKeyCombinationText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,33 +9,27 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Cursor;
|
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.UserInterfaceV2;
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
using osu.Game.Input;
|
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Input
|
namespace osu.Game.Overlays.Settings.Sections.Input
|
||||||
{
|
{
|
||||||
public partial class KeyBindingRow : Container, IFilterable, IHasPopover
|
public partial class KeyBindingRow : Container, IFilterable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the binding of this row is updated with a change being written.
|
/// Invoked when the binding of this row is updated with a change being written.
|
||||||
@ -210,18 +204,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateButtons()
|
|
||||||
{
|
|
||||||
if (buttons.Count > KeyBindings.Count)
|
|
||||||
buttons.RemoveRange(buttons.Skip(KeyBindings.Count).ToArray(), true);
|
|
||||||
|
|
||||||
while (buttons.Count < KeyBindings.Count)
|
|
||||||
buttons.Add(new KeyButton());
|
|
||||||
|
|
||||||
foreach (var (button, binding) in buttons.Zip(KeyBindings))
|
|
||||||
button.KeyBinding.Value = binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RestoreDefaults()
|
public void RestoreDefaults()
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -251,8 +233,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
base.OnHoverLost(e);
|
base.OnHoverLost(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool isModifier(Key k) => k < Key.F1;
|
|
||||||
|
|
||||||
protected override bool OnClick(ClickEvent e) => true;
|
protected override bool OnClick(ClickEvent e) => true;
|
||||||
|
|
||||||
protected override bool OnMouseDown(MouseDownEvent e)
|
protected override bool OnMouseDown(MouseDownEvent e)
|
||||||
@ -325,6 +305,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
if (!isModifier(e.Key)) finalise();
|
if (!isModifier(e.Key)) finalise();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
bool isModifier(Key k) => k < Key.F1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnKeyUp(KeyUpEvent e)
|
protected override void OnKeyUp(KeyUpEvent e)
|
||||||
@ -434,6 +416,18 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
finalise();
|
finalise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateButtons()
|
||||||
|
{
|
||||||
|
if (buttons.Count > KeyBindings.Count)
|
||||||
|
buttons.RemoveRange(buttons.Skip(KeyBindings.Count).ToArray(), true);
|
||||||
|
|
||||||
|
while (buttons.Count < KeyBindings.Count)
|
||||||
|
buttons.Add(new KeyButton());
|
||||||
|
|
||||||
|
foreach (var (button, binding) in buttons.Zip(KeyBindings))
|
||||||
|
button.KeyBinding.Value = binding;
|
||||||
|
}
|
||||||
|
|
||||||
private void clear()
|
private void clear()
|
||||||
{
|
{
|
||||||
if (bindTarget == null)
|
if (bindTarget == null)
|
||||||
@ -466,6 +460,24 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y;
|
cancelAndClearButtons.BypassAutoSizeAxes |= Axes.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnFocus(FocusEvent e)
|
||||||
|
{
|
||||||
|
content.AutoSizeDuration = 500;
|
||||||
|
content.AutoSizeEasing = Easing.OutQuint;
|
||||||
|
|
||||||
|
cancelAndClearButtons.FadeIn(300, Easing.OutQuint);
|
||||||
|
cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y;
|
||||||
|
|
||||||
|
updateBindTarget();
|
||||||
|
base.OnFocus(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocusLost(FocusLostEvent e)
|
||||||
|
{
|
||||||
|
finalise(false);
|
||||||
|
base.OnFocusLost(e);
|
||||||
|
}
|
||||||
|
|
||||||
private void tryPersistKeyBinding(RealmKeyBinding keyBinding, bool advanceToNextBinding)
|
private void tryPersistKeyBinding(RealmKeyBinding keyBinding, bool advanceToNextBinding)
|
||||||
{
|
{
|
||||||
List<RealmKeyBinding> bindings = GetAllSectionBindings();
|
List<RealmKeyBinding> bindings = GetAllSectionBindings();
|
||||||
@ -488,24 +500,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
new ConflictingKeyBinding(keyBindingBeforeUpdate.ID, Action, keyBinding.KeyCombination, keyBindingBeforeUpdate.KeyCombination)));
|
new ConflictingKeyBinding(keyBindingBeforeUpdate.ID, Action, keyBinding.KeyCombination, keyBindingBeforeUpdate.KeyCombination)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnFocus(FocusEvent e)
|
|
||||||
{
|
|
||||||
content.AutoSizeDuration = 500;
|
|
||||||
content.AutoSizeEasing = Easing.OutQuint;
|
|
||||||
|
|
||||||
cancelAndClearButtons.FadeIn(300, Easing.OutQuint);
|
|
||||||
cancelAndClearButtons.BypassAutoSizeAxes &= ~Axes.Y;
|
|
||||||
|
|
||||||
updateBindTarget();
|
|
||||||
base.OnFocus(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnFocusLost(FocusLostEvent e)
|
|
||||||
{
|
|
||||||
finalise(false);
|
|
||||||
base.OnFocusLost(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the bind target to the currently hovered key button or the first if clicked anywhere else.
|
/// Updates the bind target to the currently hovered key button or the first if clicked anywhere else.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -521,70 +515,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
isDefault.Value = KeyBindings.Select(b => b.KeyCombination).SequenceEqual(Defaults);
|
isDefault.Value = KeyBindings.Select(b => b.KeyCombination).SequenceEqual(Defaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Handling conflicts
|
|
||||||
|
|
||||||
private readonly Bindable<KeyBindingConflictInfo> keyBindingConflictInfo = new Bindable<KeyBindingConflictInfo>();
|
|
||||||
|
|
||||||
public Popover GetPopover() => new KeyBindingConflictPopover
|
|
||||||
{
|
|
||||||
ConflictInfo = { BindTarget = keyBindingConflictInfo },
|
|
||||||
BindingConflictResolved = () => BindingUpdated?.Invoke(this, new KeyBindingUpdatedEventArgs(bindingConflictResolved: true, canAdvanceToNextBinding: false))
|
|
||||||
};
|
|
||||||
|
|
||||||
private void showBindingConflictPopover(KeyBindingConflictInfo conflictInfo)
|
|
||||||
{
|
|
||||||
keyBindingConflictInfo.Value = conflictInfo;
|
|
||||||
this.ShowPopover();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Contains information about the key binding conflict to be resolved.
|
|
||||||
/// </summary>
|
|
||||||
public class KeyBindingConflictInfo
|
|
||||||
{
|
|
||||||
public ConflictingKeyBinding Existing { get; }
|
|
||||||
public ConflictingKeyBinding New { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Contains information about the key binding conflict to be resolved.
|
|
||||||
/// </summary>
|
|
||||||
public KeyBindingConflictInfo(ConflictingKeyBinding existingBinding, ConflictingKeyBinding newBinding)
|
|
||||||
{
|
|
||||||
Existing = existingBinding;
|
|
||||||
New = newBinding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConflictingKeyBinding
|
|
||||||
{
|
|
||||||
public Guid ID { get; }
|
|
||||||
public object Action { get; }
|
|
||||||
public KeyCombination CombinationWhenChosen { get; }
|
|
||||||
public KeyCombination CombinationWhenNotChosen { get; }
|
|
||||||
|
|
||||||
public ConflictingKeyBinding(Guid id, object action, KeyCombination combinationWhenChosen, KeyCombination combinationWhenNotChosen)
|
|
||||||
{
|
|
||||||
ID = id;
|
|
||||||
Action = action;
|
|
||||||
CombinationWhenChosen = combinationWhenChosen;
|
|
||||||
CombinationWhenNotChosen = combinationWhenNotChosen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class KeyBindingUpdatedEventArgs
|
|
||||||
{
|
|
||||||
public bool BindingConflictResolved { get; }
|
|
||||||
public bool CanAdvanceToNextBinding { get; }
|
|
||||||
|
|
||||||
public KeyBindingUpdatedEventArgs(bool bindingConflictResolved, bool canAdvanceToNextBinding)
|
|
||||||
{
|
|
||||||
BindingConflictResolved = bindingConflictResolved;
|
|
||||||
CanAdvanceToNextBinding = canAdvanceToNextBinding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private partial class CancelButton : RoundedButton
|
private partial class CancelButton : RoundedButton
|
||||||
{
|
{
|
||||||
public CancelButton()
|
public CancelButton()
|
||||||
@ -602,147 +532,5 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
Size = new Vector2(80, 20);
|
Size = new Vector2(80, 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class KeyButton : Container
|
|
||||||
{
|
|
||||||
public Bindable<RealmKeyBinding> KeyBinding { get; } = new Bindable<RealmKeyBinding>();
|
|
||||||
|
|
||||||
private readonly Box box;
|
|
||||||
public readonly OsuSpriteText Text;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OverlayColourProvider colourProvider { get; set; } = null!;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private ReadableKeyCombinationProvider keyCombinationProvider { get; set; } = null!;
|
|
||||||
|
|
||||||
private bool isBinding;
|
|
||||||
|
|
||||||
public bool IsBinding
|
|
||||||
{
|
|
||||||
get => isBinding;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value == isBinding) return;
|
|
||||||
|
|
||||||
isBinding = value;
|
|
||||||
|
|
||||||
updateHoverState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyButton()
|
|
||||||
{
|
|
||||||
Margin = new MarginPadding(padding);
|
|
||||||
|
|
||||||
Masking = true;
|
|
||||||
CornerRadius = padding;
|
|
||||||
|
|
||||||
Height = height;
|
|
||||||
AutoSizeAxes = Axes.X;
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
AlwaysPresent = true,
|
|
||||||
Width = 80,
|
|
||||||
Height = height,
|
|
||||||
},
|
|
||||||
box = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
Text = new OsuSpriteText
|
|
||||||
{
|
|
||||||
Font = OsuFont.Numeric.With(size: 10),
|
|
||||||
Margin = new MarginPadding(5),
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
|
||||||
new HoverSounds()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
KeyBinding.BindValueChanged(_ =>
|
|
||||||
{
|
|
||||||
if (KeyBinding.Value.IsManaged)
|
|
||||||
throw new ArgumentException("Key binding should not be attached as we make temporary changes", nameof(KeyBinding));
|
|
||||||
|
|
||||||
updateKeyCombinationText();
|
|
||||||
});
|
|
||||||
keyCombinationProvider.KeymapChanged += updateKeyCombinationText;
|
|
||||||
updateKeyCombinationText();
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
updateHoverState();
|
|
||||||
FinishTransforms(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
|
||||||
{
|
|
||||||
updateHoverState();
|
|
||||||
return base.OnHover(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnHoverLost(HoverLostEvent e)
|
|
||||||
{
|
|
||||||
updateHoverState();
|
|
||||||
base.OnHoverLost(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateHoverState()
|
|
||||||
{
|
|
||||||
if (isBinding)
|
|
||||||
{
|
|
||||||
box.FadeColour(colourProvider.Light2, transition_time, Easing.OutQuint);
|
|
||||||
Text.FadeColour(Color4.Black, transition_time, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
box.FadeColour(IsHovered ? colourProvider.Light4 : colourProvider.Background6, transition_time, Easing.OutQuint);
|
|
||||||
Text.FadeColour(IsHovered ? Color4.Black : Color4.White, transition_time, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update from a key combination, only allowing a single non-modifier key to be specified.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fullState">A <see cref="KeyCombination"/> generated from the full input state.</param>
|
|
||||||
/// <param name="triggerKey">The key which triggered this update, and should be used as the binding.</param>
|
|
||||||
public void UpdateKeyCombination(KeyCombination fullState, InputKey triggerKey) =>
|
|
||||||
UpdateKeyCombination(new KeyCombination(fullState.Keys.Where(KeyCombination.IsModifierKey).Append(triggerKey)));
|
|
||||||
|
|
||||||
public void UpdateKeyCombination(KeyCombination newCombination)
|
|
||||||
{
|
|
||||||
if (KeyBinding.Value.RulesetName != null && !RealmKeyBindingStore.CheckValidForGameplay(newCombination))
|
|
||||||
return;
|
|
||||||
|
|
||||||
KeyBinding.Value.KeyCombination = newCombination;
|
|
||||||
updateKeyCombinationText();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateKeyCombinationText()
|
|
||||||
{
|
|
||||||
Scheduler.AddOnce(updateText);
|
|
||||||
|
|
||||||
void updateText() => Text.Text = keyCombinationProvider.GetReadableString(KeyBinding.Value.KeyCombination);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
|
|
||||||
if (keyCombinationProvider.IsNotNull())
|
|
||||||
keyCombinationProvider.KeymapChanged -= updateKeyCombinationText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user