using System;
using System.Linq;
using Artemis.Core;
using Artemis.Core.Services;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Humanizer;
using Material.Icons;
namespace Artemis.UI.Shared
{
///
/// Represents a control that can be used to display or edit instances.
///
public class HotkeyBox : UserControl
{
private readonly TextBox _displayTextBox;
///
/// Creates a new instance of the class
///
public HotkeyBox()
{
InitializeComponent();
_displayTextBox = this.Find("DisplayTextBox");
_displayTextBox.KeyDown += DisplayTextBoxOnKeyDown;
_displayTextBox.KeyUp += DisplayTextBoxOnKeyUp;
UpdateDisplayTextBox();
}
private static void HotkeyChanging(IAvaloniaObject sender, bool before)
{
((HotkeyBox) sender).UpdateDisplayTextBox();
}
private void DisplayTextBoxOnKeyDown(object? sender, KeyEventArgs e)
{
if (e.Key >= Key.LeftShift && e.Key <= Key.RightAlt)
return;
Hotkey ??= new Hotkey();
Hotkey.Key = (KeyboardKey?) e.Key;
Hotkey.Modifiers = (KeyboardModifierKey?) e.KeyModifiers;
UpdateDisplayTextBox();
e.Handled = true;
}
private void DisplayTextBoxOnKeyUp(object? sender, KeyEventArgs e)
{
if (e.KeyModifiers == KeyModifiers.None)
FocusManager.Instance?.Focus(null);
e.Handled = true;
}
private void UpdateDisplayTextBox()
{
string? display = null;
if (Hotkey?.Modifiers != null)
display = string.Join("+", Enum.GetValues().Skip(1).Where(m => Hotkey.Modifiers.Value.HasFlag(m)).Select(v => v.Humanize()));
if (Hotkey?.Key != null)
display = string.IsNullOrEmpty(display) ? Hotkey.Key.ToString() : $"{display}+{Hotkey.Key}";
_displayTextBox.Text = display;
_displayTextBox.CaretIndex = _displayTextBox.Text?.Length ?? 0;
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void Button_OnClick(object? sender, RoutedEventArgs e)
{
Hotkey = null;
FocusManager.Instance?.Focus(null);
UpdateDisplayTextBox();
}
#region Properties
///
/// Gets or sets the currently displayed icon as either a or an
/// pointing to an SVG
///
public static readonly StyledProperty HotkeyProperty =
AvaloniaProperty.Register(nameof(Hotkey), defaultBindingMode: BindingMode.TwoWay, notifying: HotkeyChanging);
///
/// Gets or sets the watermark of the hotkey box when it is empty.
///
public static readonly StyledProperty WatermarkProperty =
AvaloniaProperty.Register(nameof(Watermark));
///
/// Gets or sets a boolean indicating whether the watermark should float above the hotkey box when it is not empty.
///
public static readonly StyledProperty UseFloatingWatermarkProperty =
AvaloniaProperty.Register(nameof(UseFloatingWatermark));
///
/// Gets or sets the currently displayed icon as either a or an
/// pointing to an SVG
///
public Hotkey? Hotkey
{
get => GetValue(HotkeyProperty);
set => SetValue(HotkeyProperty, value);
}
///
/// Gets or sets the watermark of the hotkey box when it is empty.
///
public string? Watermark
{
get => GetValue(WatermarkProperty);
set => SetValue(WatermarkProperty, value);
}
///
/// Gets or sets a boolean indicating whether the watermark should float above the hotkey box when it is not empty.
///
public bool UseFloatingWatermark
{
get => GetValue(UseFloatingWatermarkProperty);
set => SetValue(UseFloatingWatermarkProperty, value);
}
#endregion
}
}