mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 21:38:38 +00:00
Nodes - Added hotkey toggle and hotkey enable/disable nodes
This commit is contained in:
parent
bef3a84e28
commit
704bdce68b
@ -16,7 +16,10 @@ public class Hotkey : CorePropertyChanged, IStorageModel
|
||||
Entity = new ProfileConfigurationHotkeyEntity();
|
||||
}
|
||||
|
||||
internal Hotkey(ProfileConfigurationHotkeyEntity entity)
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="Hotkey" /> based on the provided entity
|
||||
/// </summary>
|
||||
public Hotkey(ProfileConfigurationHotkeyEntity entity)
|
||||
{
|
||||
Entity = entity;
|
||||
Load();
|
||||
@ -32,7 +35,10 @@ public class Hotkey : CorePropertyChanged, IStorageModel
|
||||
/// </summary>
|
||||
public KeyboardModifierKey? Modifiers { get; set; }
|
||||
|
||||
internal ProfileConfigurationHotkeyEntity Entity { get; }
|
||||
/// <summary>
|
||||
/// Gets the entity used to store this hotkey
|
||||
/// </summary>
|
||||
public ProfileConfigurationHotkeyEntity Entity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the provided <see cref="ArtemisKeyboardKeyEventArgs" /> match the hotkey
|
||||
|
||||
@ -8,6 +8,7 @@ using Avalonia.Data;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using FluentAvalonia.Core;
|
||||
using Humanizer;
|
||||
using Material.Icons;
|
||||
|
||||
@ -47,7 +48,8 @@ public class HotkeyBox : UserControl
|
||||
Hotkey.Key = (KeyboardKey?) e.Key;
|
||||
Hotkey.Modifiers = (KeyboardModifierKey?) e.KeyModifiers;
|
||||
UpdateDisplayTextBox();
|
||||
|
||||
HotkeyChanged?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
@ -134,4 +136,13 @@ public class HotkeyBox : UserControl
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the hotkey changes.
|
||||
/// </summary>
|
||||
public event TypedEventHandler<HotkeyBox, EventArgs>? HotkeyChanged;
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -39,6 +39,9 @@
|
||||
|
||||
<dataModelPicker:DataModelPickerButton></dataModelPicker:DataModelPickerButton>
|
||||
<dataModelPicker:DataModelPickerButton Classes="condensed"></dataModelPicker:DataModelPickerButton>
|
||||
|
||||
<controls1:HotkeyBox></controls1:HotkeyBox>
|
||||
<controls1:HotkeyBox Classes="condensed"></controls1:HotkeyBox>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Design.PreviewWith>
|
||||
@ -110,4 +113,10 @@
|
||||
<Setter Property="MinHeight" Value="24" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="controls1|HotkeyBox.condensed > TextBox#DisplayTextBox">
|
||||
<Setter Property="Padding" Value="6 0" />
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="MinHeight" Value="24" />
|
||||
</Style>
|
||||
|
||||
</Styles>
|
||||
@ -0,0 +1,74 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.VisualScripting.Nodes.Input.Screens;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Input;
|
||||
|
||||
[Node("Hotkey enable/disable", "Outputs a boolean value enabled and disabled by a set of hotkeys", "Input", OutputType = typeof(bool))]
|
||||
public class HotkeyEnableDisableNode : Node<HotkeyEnableDisableNodeEntity, HotkeyEnableDisableNodeCustomViewModel>, IDisposable
|
||||
{
|
||||
private readonly IInputService _inputService;
|
||||
private Hotkey? _disableHotkey;
|
||||
private Hotkey? _enableHotkey;
|
||||
private bool _value;
|
||||
private bool _retrievedInitialValue;
|
||||
|
||||
public HotkeyEnableDisableNode(IInputService inputService)
|
||||
{
|
||||
_inputService = inputService;
|
||||
_inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp;
|
||||
|
||||
InitialValue = CreateInputPin<bool>();
|
||||
Output = CreateOutputPin<bool>();
|
||||
StorageModified += OnStorageModified;
|
||||
}
|
||||
|
||||
public InputPin<bool> InitialValue { get; }
|
||||
public OutputPin<bool> Output { get; }
|
||||
|
||||
public override void Initialize(INodeScript script)
|
||||
{
|
||||
LoadHotkeys();
|
||||
}
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
if (!_retrievedInitialValue)
|
||||
{
|
||||
_value = InitialValue.Value;
|
||||
_retrievedInitialValue = true;
|
||||
}
|
||||
|
||||
Output.Value = _value;
|
||||
}
|
||||
|
||||
private void OnStorageModified(object? sender, EventArgs e)
|
||||
{
|
||||
LoadHotkeys();
|
||||
}
|
||||
|
||||
private void LoadHotkeys()
|
||||
{
|
||||
if (Storage == null)
|
||||
return;
|
||||
|
||||
_enableHotkey = Storage.EnableHotkey != null ? new Hotkey(Storage.EnableHotkey) : null;
|
||||
_disableHotkey = Storage.DisableHotkey != null ? new Hotkey(Storage.DisableHotkey) : null;
|
||||
}
|
||||
|
||||
private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e)
|
||||
{
|
||||
if (Storage == null)
|
||||
return;
|
||||
|
||||
if (_disableHotkey != null && _disableHotkey.MatchesEventArgs(e))
|
||||
_value = false;
|
||||
else if (_enableHotkey != null && _enableHotkey.MatchesEventArgs(e))
|
||||
_value = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Input;
|
||||
|
||||
public class HotkeyEnableDisableNodeEntity
|
||||
{
|
||||
public HotkeyEnableDisableNodeEntity(Hotkey? enableHotkey, Hotkey? disableHotkey)
|
||||
{
|
||||
enableHotkey?.Save();
|
||||
EnableHotkey = enableHotkey?.Entity;
|
||||
disableHotkey?.Save();
|
||||
DisableHotkey = disableHotkey?.Entity;
|
||||
}
|
||||
|
||||
public ProfileConfigurationHotkeyEntity? EnableHotkey { get; set; }
|
||||
public ProfileConfigurationHotkeyEntity? DisableHotkey { get; set; }
|
||||
}
|
||||
69
src/Artemis.VisualScripting/Nodes/Input/HotkeyToggleNode.cs
Normal file
69
src/Artemis.VisualScripting/Nodes/Input/HotkeyToggleNode.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using Artemis.Core;
|
||||
using Artemis.Core.Services;
|
||||
using Artemis.VisualScripting.Nodes.Input.Screens;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Input;
|
||||
|
||||
[Node("Hotkey toggle", "Outputs a boolean value toggled by a hotkey", "Input", OutputType = typeof(bool))]
|
||||
public class HotkeyToggleNode : Node<HotkeyEnableDisableNodeEntity, HotkeyToggleNodeCustomViewModel>, IDisposable
|
||||
{
|
||||
private readonly IInputService _inputService;
|
||||
private Hotkey? _toggleHotkey;
|
||||
private bool _value;
|
||||
private bool _retrievedInitialValue;
|
||||
|
||||
public HotkeyToggleNode(IInputService inputService)
|
||||
{
|
||||
_inputService = inputService;
|
||||
_inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp;
|
||||
|
||||
InitialValue = CreateInputPin<bool>();
|
||||
Output = CreateOutputPin<bool>();
|
||||
StorageModified += OnStorageModified;
|
||||
}
|
||||
|
||||
public InputPin<bool> InitialValue { get; }
|
||||
public OutputPin<bool> Output { get; }
|
||||
|
||||
public override void Initialize(INodeScript script)
|
||||
{
|
||||
LoadHotkeys();
|
||||
}
|
||||
|
||||
public override void Evaluate()
|
||||
{
|
||||
if (!_retrievedInitialValue)
|
||||
{
|
||||
_value = InitialValue.Value;
|
||||
_retrievedInitialValue = true;
|
||||
}
|
||||
|
||||
Output.Value = _value;
|
||||
}
|
||||
|
||||
private void OnStorageModified(object? sender, EventArgs e)
|
||||
{
|
||||
LoadHotkeys();
|
||||
}
|
||||
|
||||
private void LoadHotkeys()
|
||||
{
|
||||
if (Storage == null)
|
||||
return;
|
||||
|
||||
_toggleHotkey = Storage.EnableHotkey != null ? new Hotkey(Storage.EnableHotkey) : null;
|
||||
}
|
||||
|
||||
private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e)
|
||||
{
|
||||
if (Storage == null)
|
||||
return;
|
||||
if (_toggleHotkey != null && _toggleHotkey.MatchesEventArgs(e))
|
||||
_value = !_value;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
<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:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:screens="clr-namespace:Artemis.VisualScripting.Nodes.Input.Screens"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.VisualScripting.Nodes.Input.Screens.HotkeyEnableDisableNodeCustomView"
|
||||
x:DataType="screens:HotkeyEnableDisableNodeCustomViewModel">
|
||||
<StackPanel>
|
||||
<TextBlock FontSize="13" Margin="0 -2 0 5">Enable</TextBlock>
|
||||
<shared:HotkeyBox Classes="condensed" Hotkey="{CompiledBinding EnableHotkey}" HotkeyChanged="HotkeyBox_OnHotkeyChanged" MinWidth="75" />
|
||||
<TextBlock FontSize="13" Margin="0 5">Disable</TextBlock>
|
||||
<shared:HotkeyBox Classes="condensed" Hotkey="{CompiledBinding DisableHotkey}" HotkeyChanged="HotkeyBox_OnHotkeyChanged" MinWidth="75" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@ -0,0 +1,25 @@
|
||||
using Artemis.UI.Shared;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Input.Screens;
|
||||
|
||||
public partial class HotkeyEnableDisableNodeCustomView : ReactiveUserControl<HotkeyEnableDisableNodeCustomViewModel>
|
||||
{
|
||||
public HotkeyEnableDisableNodeCustomView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
private void HotkeyBox_OnHotkeyChanged(HotkeyBox sender, EventArgs args)
|
||||
{
|
||||
ViewModel?.Save();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
using System.Reactive.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Services.NodeEditor;
|
||||
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
||||
using Artemis.UI.Shared.VisualScripting;
|
||||
using Avalonia.Controls.Mixins;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Input.Screens;
|
||||
|
||||
public class HotkeyEnableDisableNodeCustomViewModel : CustomNodeViewModel
|
||||
{
|
||||
private readonly HotkeyEnableDisableNode _enableDisableNode;
|
||||
private readonly INodeEditorService _nodeEditorService;
|
||||
private Hotkey? _enableHotkey;
|
||||
private Hotkey? _disableHotkey;
|
||||
private bool _updating;
|
||||
|
||||
/// <inheritdoc />
|
||||
public HotkeyEnableDisableNodeCustomViewModel(HotkeyEnableDisableNode enableDisableNode, INodeScript script, INodeEditorService nodeEditorService) : base(enableDisableNode, script)
|
||||
{
|
||||
_enableDisableNode = enableDisableNode;
|
||||
_nodeEditorService = nodeEditorService;
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
Observable.FromEventPattern(x => _enableDisableNode.StorageModified += x, x => _enableDisableNode.StorageModified -= x).Subscribe(_ => Update()).DisposeWith(d);
|
||||
Update();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
_updating = true;
|
||||
|
||||
EnableHotkey = _enableDisableNode.Storage?.EnableHotkey != null ? new Hotkey(_enableDisableNode.Storage.EnableHotkey) : null;
|
||||
DisableHotkey = _enableDisableNode.Storage?.DisableHotkey != null ? new Hotkey(_enableDisableNode.Storage.DisableHotkey) : null;
|
||||
|
||||
_updating = false;
|
||||
}
|
||||
|
||||
public Hotkey? EnableHotkey
|
||||
{
|
||||
get => _enableHotkey;
|
||||
set => this.RaiseAndSetIfChanged(ref _enableHotkey, value);
|
||||
}
|
||||
|
||||
public Hotkey? DisableHotkey
|
||||
{
|
||||
get => _disableHotkey;
|
||||
set => this.RaiseAndSetIfChanged(ref _disableHotkey, value);
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
_nodeEditorService.ExecuteCommand(
|
||||
Script,
|
||||
new UpdateStorage<HotkeyEnableDisableNodeEntity>(_enableDisableNode, new HotkeyEnableDisableNodeEntity(EnableHotkey, DisableHotkey), "hotkey")
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
<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:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
xmlns:screens="clr-namespace:Artemis.VisualScripting.Nodes.Input.Screens"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.VisualScripting.Nodes.Input.Screens.HotkeyToggleNodeCustomView"
|
||||
x:DataType="screens:HotkeyToggleNodeCustomViewModel">
|
||||
<shared:HotkeyBox Classes="condensed" Hotkey="{CompiledBinding ToggleHotkey}" HotkeyChanged="HotkeyBox_OnHotkeyChanged" MinWidth="75" />
|
||||
</UserControl>
|
||||
@ -0,0 +1,25 @@
|
||||
using Artemis.UI.Shared;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Input.Screens;
|
||||
|
||||
public partial class HotkeyToggleNodeCustomView : ReactiveUserControl<HotkeyToggleNodeCustomViewModel>
|
||||
{
|
||||
public HotkeyToggleNodeCustomView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
private void HotkeyBox_OnHotkeyChanged(HotkeyBox sender, EventArgs args)
|
||||
{
|
||||
ViewModel?.Save();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
using System.Reactive.Linq;
|
||||
using Artemis.Core;
|
||||
using Artemis.UI.Shared.Services.NodeEditor;
|
||||
using Artemis.UI.Shared.Services.NodeEditor.Commands;
|
||||
using Artemis.UI.Shared.VisualScripting;
|
||||
using Avalonia.Controls.Mixins;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.VisualScripting.Nodes.Input.Screens;
|
||||
|
||||
public class HotkeyToggleNodeCustomViewModel : CustomNodeViewModel
|
||||
{
|
||||
private readonly HotkeyToggleNode _toggleNode;
|
||||
private readonly INodeEditorService _nodeEditorService;
|
||||
private Hotkey? _toggleHotkey;
|
||||
private bool _updating;
|
||||
|
||||
/// <inheritdoc />
|
||||
public HotkeyToggleNodeCustomViewModel(HotkeyToggleNode toggleNode, INodeScript script, INodeEditorService nodeEditorService) : base(toggleNode, script)
|
||||
{
|
||||
_toggleNode = toggleNode;
|
||||
_nodeEditorService = nodeEditorService;
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
Observable.FromEventPattern(x => _toggleNode.StorageModified += x, x => _toggleNode.StorageModified -= x).Subscribe(_ => Update()).DisposeWith(d);
|
||||
Update();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
_updating = true;
|
||||
ToggleHotkey = _toggleNode.Storage?.EnableHotkey != null ? new Hotkey(_toggleNode.Storage.EnableHotkey) : null;
|
||||
_updating = false;
|
||||
}
|
||||
|
||||
public Hotkey? ToggleHotkey
|
||||
{
|
||||
get => _toggleHotkey;
|
||||
set => this.RaiseAndSetIfChanged(ref _toggleHotkey, value);
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (_updating)
|
||||
return;
|
||||
|
||||
_nodeEditorService.ExecuteCommand(
|
||||
Script,
|
||||
new UpdateStorage<HotkeyEnableDisableNodeEntity>(_toggleNode, new HotkeyEnableDisableNodeEntity(ToggleHotkey, null), "hotkey")
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user