From 425485b0598d4bf8f8f02daaf4bbefc4f0db90d7 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 31 Jan 2023 00:14:51 +0100 Subject: [PATCH] Nodes - Added hotkey press node --- .../Artemis.VisualScripting.csproj | 7 ++ .../Nodes/Input/HotkeyPressNode.cs | 69 +++++++++++++++++++ .../Screens/HotkeyPressNodeCustomView.axaml | 11 +++ .../HotkeyPressNodeCustomView.axaml.cs | 25 +++++++ .../Screens/HotkeyPressNodeCustomViewModel.cs | 55 +++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs create mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml create mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs create mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index 715ce5fe9..ac5bb81ea 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -23,4 +23,11 @@ + + + HotkeyPressNodeCustomView.axaml + Code + + + diff --git a/src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs b/src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs new file mode 100644 index 000000000..593eaf8bf --- /dev/null +++ b/src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs @@ -0,0 +1,69 @@ +using Artemis.Core; +using Artemis.Core.Services; +using Artemis.VisualScripting.Nodes.Input.Screens; + +namespace Artemis.VisualScripting.Nodes.Input; + +[Node("Hotkey press", "Outputs a boolean value for as long as a hotkey is pressed", "Input", OutputType = typeof(bool))] +public class HotkeyPressNode : Node, IDisposable +{ + private readonly IInputService _inputService; + private Hotkey? _toggleHotkey; + private bool _value; + + public HotkeyPressNode(IInputService inputService) + { + _inputService = inputService; + _inputService.KeyboardKeyDown += InputServiceOnKeyboardKeyDown; + _inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp; + + Output = CreateOutputPin(); + StorageModified += OnStorageModified; + } + + public OutputPin Output { get; } + + public override void Initialize(INodeScript script) + { + LoadHotkeys(); + } + + public override void Evaluate() + { + 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 InputServiceOnKeyboardKeyDown(object? sender, ArtemisKeyboardKeyEventArgs e) + { + if (Storage == null) + return; + if (_toggleHotkey != null && _toggleHotkey.MatchesEventArgs(e)) + _value = true; + } + + private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e) + { + if (Storage == null) + return; + if (_toggleHotkey != null && _toggleHotkey.MatchesEventArgs(e)) + _value = false; + } + + public void Dispose() + { + _inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp; + } +} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml new file mode 100644 index 000000000..19097f664 --- /dev/null +++ b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs new file mode 100644 index 000000000..fb8f76f7d --- /dev/null +++ b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs @@ -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 HotkeyPressNodeCustomView : ReactiveUserControl +{ + public HotkeyPressNodeCustomView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + + private void HotkeyBox_OnHotkeyChanged(HotkeyBox sender, EventArgs args) + { + ViewModel?.Save(); + } +} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs new file mode 100644 index 000000000..631a4644a --- /dev/null +++ b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs @@ -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 HotkeyPressNodeCustomViewModel : CustomNodeViewModel +{ + private readonly HotkeyPressNode _pressNode; + private readonly INodeEditorService _nodeEditorService; + private Hotkey? _toggleHotkey; + private bool _updating; + + /// + public HotkeyPressNodeCustomViewModel(HotkeyPressNode pressNode, INodeScript script, INodeEditorService nodeEditorService) : base(pressNode, script) + { + _pressNode = pressNode; + _nodeEditorService = nodeEditorService; + + this.WhenActivated(d => + { + Observable.FromEventPattern(x => _pressNode.StorageModified += x, x => _pressNode.StorageModified -= x).Subscribe(_ => Update()).DisposeWith(d); + Update(); + }); + + } + + private void Update() + { + _updating = true; + ToggleHotkey = _pressNode.Storage?.EnableHotkey != null ? new Hotkey(_pressNode.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(_pressNode, new HotkeyEnableDisableNodeEntity(ToggleHotkey, null), "hotkey") + ); + } +} \ No newline at end of file