1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Core - Renamed ProfileConfigurationHotkey to Hotkey

Avalonia - Added HotkeyBox
This commit is contained in:
Robert 2021-12-07 00:14:23 +01:00
parent b801de1f30
commit ebed9f5560
11 changed files with 269 additions and 48 deletions

View File

@ -6,18 +6,18 @@ namespace Artemis.Core
/// <summary>
/// Represents a key or combination of keys that changes the suspension status of a <see cref="ProfileConfiguration"/>
/// </summary>
public class ProfileConfigurationHotkey : CorePropertyChanged, IStorageModel
public class Hotkey : CorePropertyChanged, IStorageModel
{
/// <summary>
/// Creates a new instance of <see cref="ProfileConfigurationHotkey" />
/// Creates a new instance of <see cref="Hotkey" />
/// </summary>
public ProfileConfigurationHotkey()
public Hotkey()
{
Entity = new ProfileConfigurationHotkeyEntity();
}
internal ProfileConfigurationHotkey(ProfileConfigurationHotkeyEntity entity)
internal Hotkey(ProfileConfigurationHotkeyEntity entity)
{
Entity = entity;
Load();

View File

@ -104,12 +104,12 @@ namespace Artemis.Core
/// <summary>
/// Gets or sets the hotkey used to enable or toggle the profile
/// </summary>
public ProfileConfigurationHotkey? EnableHotkey { get; set; }
public Hotkey? EnableHotkey { get; set; }
/// <summary>
/// Gets or sets the hotkey used to disable the profile
/// </summary>
public ProfileConfigurationHotkey? DisableHotkey { get; set; }
public Hotkey? DisableHotkey { get; set; }
/// <summary>
/// Gets the ID of the profile of this profile configuration
@ -246,8 +246,8 @@ namespace Artemis.Core
? new NodeScript<bool>("Activate profile", "Whether or not the profile should be active", Entity.ActivationCondition, this)
: new NodeScript<bool>("Activate profile", "Whether or not the profile should be active", this);
EnableHotkey = Entity.EnableHotkey != null ? new ProfileConfigurationHotkey(Entity.EnableHotkey) : null;
DisableHotkey = Entity.DisableHotkey != null ? new ProfileConfigurationHotkey(Entity.DisableHotkey) : null;
EnableHotkey = Entity.EnableHotkey != null ? new Hotkey(Entity.EnableHotkey) : null;
DisableHotkey = Entity.DisableHotkey != null ? new Hotkey(Entity.DisableHotkey) : null;
}
/// <inheritdoc />

View File

@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
namespace Artemis.Core.Services
{
@ -9,18 +10,23 @@ namespace Artemis.Core.Services
public enum KeyboardModifierKey
{
/// <summary>No modifiers are pressed.</summary>
[Description("None")]
None = 0,
/// <summary>The ALT key.</summary>
[Description("Alt")]
Alt = 1,
/// <summary>The CTRL key.</summary>
[Description("Ctrl")]
Control = 2,
/// <summary>The SHIFT key.</summary>
[Description("Shift")]
Shift = 4,
/// <summary>The Windows logo key.</summary>
[Description("Win")]
Windows = 8
}
}

View File

@ -96,6 +96,36 @@
<member name="M:Artemis.UI.Shared.Controls.EnumComboBox.OnDetachedFromLogicalTree(Avalonia.LogicalTree.LogicalTreeAttachmentEventArgs)">
<inheritdoc />
</member>
<member name="T:Artemis.UI.Shared.Controls.HotkeyBox">
<summary>
Represents a control that can be used to display or edit <see cref="T:Artemis.Core.Hotkey"/> instances.
</summary>
</member>
<member name="M:Artemis.UI.Shared.Controls.HotkeyBox.#ctor">
<summary>
Creates a new instance of the <see cref="T:Artemis.UI.Shared.Controls.HotkeyBox"/> class
</summary>
</member>
<member name="F:Artemis.UI.Shared.Controls.HotkeyBox.HotkeyProperty">
<summary>
Gets or sets the currently displayed icon as either a <see cref="T:Material.Icons.MaterialIconKind" /> or an <see cref="T:System.Uri" />
pointing
to an SVG
</summary>
</member>
<member name="P:Artemis.UI.Shared.Controls.HotkeyBox.Hotkey">
<summary>
Gets or sets the currently displayed icon as either a <see cref="T:Material.Icons.MaterialIconKind" /> or an <see cref="T:System.Uri" />
pointing
to an SVG
</summary>
</member>
<member name="M:Artemis.UI.Shared.Controls.NoInputTextBox.OnKeyDown(Avalonia.Input.KeyEventArgs)">
<inheritdoc />
</member>
<member name="M:Artemis.UI.Shared.Controls.NoInputTextBox.OnKeyUp(Avalonia.Input.KeyEventArgs)">
<inheritdoc />
</member>
<member name="F:Artemis.UI.Shared.Controls.ProfileConfigurationIcon.ConfigurationIconProperty">
<summary>
Gets or sets the <see cref="T:Artemis.Core.ProfileConfigurationIcon" /> to display

View File

@ -22,7 +22,7 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit
UpdateHotkeyDisplay();
}
public ProfileConfigurationHotkey Hotkey => _isDisableHotkey ? _profileConfiguration.DisableHotkey : _profileConfiguration.EnableHotkey;
public Hotkey Hotkey => _isDisableHotkey ? _profileConfiguration.DisableHotkey : _profileConfiguration.EnableHotkey;
public string Hint
{
@ -66,13 +66,13 @@ namespace Artemis.UI.Screens.Sidebar.Dialogs.ProfileEdit
if (_isDisableHotkey)
{
_profileConfiguration.DisableHotkey ??= new ProfileConfigurationHotkey();
_profileConfiguration.DisableHotkey ??= new Hotkey();
_profileConfiguration.DisableHotkey.Key = (KeyboardKey?) e.Key;
_profileConfiguration.DisableHotkey.Modifiers = (KeyboardModifierKey?) Keyboard.Modifiers;
}
else
{
_profileConfiguration.EnableHotkey ??= new ProfileConfigurationHotkey();
_profileConfiguration.EnableHotkey ??= new Hotkey();
_profileConfiguration.EnableHotkey.Key = (KeyboardKey?) e.Key;
_profileConfiguration.EnableHotkey.Modifiers = (KeyboardModifierKey?) Keyboard.Modifiers;
}

View File

@ -44,6 +44,9 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Controls\HotkeyBox.axaml.cs">
<DependentUpon>HotkeyBox.axaml</DependentUpon>
</Compile>
<Compile Update="Services\WindowService\ExceptionDialogView.axaml.cs">
<DependentUpon>%(Filename)</DependentUpon>
</Compile>

View File

@ -21,6 +21,19 @@ namespace Artemis.UI.Shared.Controls
public static readonly StyledProperty<object?> IconProperty =
AvaloniaProperty.Register<ArtemisIcon, object?>(nameof(Icon), notifying: IconChanging);
/// <summary>
/// Gets or sets the currently displayed icon as either a <see cref="MaterialIconKind" /> or an <see cref="Uri" /> pointing
/// to an SVG
/// </summary>
public object? Icon
{
get => GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
#endregion
private static void IconChanging(IAvaloniaObject sender, bool before)
{
if (before)
@ -58,17 +71,6 @@ namespace Artemis.UI.Shared.Controls
}
}
/// <summary>
/// Gets or sets the currently displayed icon as either a <see cref="MaterialIconKind" /> or an <see cref="Uri" /> pointing
/// to an SVG
/// </summary>
public object? Icon
{
get => GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
#endregion
public ArtemisIcon()
{

View File

@ -0,0 +1,26 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Shared.Controls.HotkeyBox">
<UserControl.Styles>
<Style Selector="TextBox#DisplayTextBox:focus:not(TextBox:empty)">
<Setter Property="InnerRightContent">
<Template>
<Button Classes="textBoxClearButton"
Click="Button_OnClick" />
</Template>
</Setter>
</Style>
</UserControl.Styles>
<controls:NoInputTextBox x:Name="DisplayTextBox"
Watermark="{Binding $parent.Watermark}"
UseFloatingWatermark="{Binding $parent.UseFloatingWatermark}"
Classes="clearButton"
IsReadOnly="True"
HorizontalAlignment="Stretch" />
</UserControl>

View File

@ -0,0 +1,127 @@
using System;
using System.Linq;
using Artemis.Core;
using Artemis.Core.Services;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Humanizer;
using Material.Icons;
namespace Artemis.UI.Shared.Controls
{
/// <summary>
/// Represents a control that can be used to display or edit <see cref="Core.Hotkey"/> instances.
/// </summary>
public class HotkeyBox : UserControl
{
private readonly TextBox _displayTextBox;
/// <summary>
/// Creates a new instance of the <see cref="HotkeyBox"/> class
/// </summary>
public HotkeyBox()
{
InitializeComponent();
_displayTextBox = this.Find<TextBox>("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<KeyboardModifierKey>().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
/// <summary>
/// Gets or sets the currently displayed icon as either a <see cref="MaterialIconKind" /> or an <see cref="Uri" />
/// pointing
/// to an SVG
/// </summary>
public static readonly StyledProperty<Hotkey?> HotkeyProperty =
AvaloniaProperty.Register<HotkeyBox, Hotkey?>(nameof(Hotkey), notifying: HotkeyChanging);
public static readonly StyledProperty<string?> WatermarkProperty =
AvaloniaProperty.Register<HotkeyBox, string?>(nameof(Watermark));
public static readonly StyledProperty<bool> UseFloatingWatermarkProperty =
AvaloniaProperty.Register<HotkeyBox, bool>(nameof(UseFloatingWatermark));
/// <summary>
/// Gets or sets the currently displayed icon as either a <see cref="MaterialIconKind" /> or an <see cref="Uri" />
/// pointing
/// to an SVG
/// </summary>
public Hotkey? Hotkey
{
get => GetValue(HotkeyProperty);
set => SetValue(HotkeyProperty, value);
}
public string? Watermark
{
get => GetValue(WatermarkProperty);
set => SetValue(WatermarkProperty, value);
}
public bool UseFloatingWatermark
{
get => GetValue(UseFloatingWatermarkProperty);
set => SetValue(UseFloatingWatermarkProperty, value);
}
#endregion
}
}

View File

@ -0,0 +1,24 @@
using System;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Styling;
namespace Artemis.UI.Shared.Controls
{
internal class NoInputTextBox : TextBox, IStyleable
{
/// <inheritdoc />
protected override void OnKeyDown(KeyEventArgs e)
{
// Don't call the base method on purpose
}
/// <inheritdoc />
protected override void OnKeyUp(KeyEventArgs e)
{
// Don't call the base method on purpose
}
Type IStyleable.StyleKey => typeof(TextBox);
}
}

View File

@ -3,6 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:builders="clr-namespace:Artemis.UI.Shared.Services.Builders;assembly=Artemis.UI.Shared"
xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.WorkshopView">
<StackPanel Margin="12">
@ -22,6 +23,8 @@
<Button Margin="0 5" Command="{Binding ShowNotification}" CommandParameter="{x:Static builders:NotificationSeverity.Success}">
Notification test (success)
</Button>
<controls:HotkeyBox Watermark="Some hotkey" Width="250" HorizontalAlignment="Left"></controls:HotkeyBox>
</StackPanel>
</Border>
</StackPanel>