From 497b6e0742d43b59ada55d5cb36024f173d2e8d9 Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Tue, 25 Apr 2023 00:14:35 +0100 Subject: [PATCH 01/14] wip: try to fix input id on linux i need this code on my linux machine to test --- .../Providers/Input/Enums/LinuxDeviceType.cs | 1 + .../Providers/Input/LinuxInputDevice.cs | 39 ++++--------------- .../Providers/Input/LinuxInputDeviceFinder.cs | 36 +++++++++++++++-- .../Providers/Input/LinuxInputProvider.cs | 4 +- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs b/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs index e0d1d0381..7eb5c4976 100644 --- a/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs +++ b/src/Artemis.UI.Linux/Providers/Input/Enums/LinuxDeviceType.cs @@ -2,6 +2,7 @@ public enum LinuxDeviceType { + Unknown, Keyboard, Mouse, Gamepad diff --git a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs index 6771d2a2b..fa6b23e43 100644 --- a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs +++ b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDevice.cs @@ -19,7 +19,7 @@ public class LinuxInputDevice switch (dataType) { case 'I': - InputId = new LinuxInputId(data); + InputId = data; break; case 'N': Name = data.Replace("\"", "").Replace("Name=", ""); @@ -27,14 +27,16 @@ public class LinuxInputDevice case 'H': Handlers = data.Replace("Handlers=", "").Split(" "); - if (Handlers?.Any(h => h.Contains("mouse")) == true) + if (Handlers.Any(h => h.Contains("mouse"))) DeviceType = LinuxDeviceType.Mouse; - else if (Handlers?.Any(h => h.Contains("kbd")) == true) + else if (Handlers.Any(h => h.Contains("kbd"))) DeviceType = LinuxDeviceType.Keyboard; - else if (Handlers?.Any(h => h.Contains("js")) == true) + else if (Handlers.Any(h => h.Contains("js"))) DeviceType = LinuxDeviceType.Gamepad; + else + DeviceType = LinuxDeviceType.Unknown; - string evt = Handlers!.First(h => h.Contains("event")); + string evt = Handlers.First(h => h.Contains("event")); EventPath = $"/dev/input/{evt}"; break; @@ -45,7 +47,7 @@ public class LinuxInputDevice throw new ArtemisLinuxInputProviderException("Linux device definition did not contain necessary data"); } - public LinuxInputId InputId { get; } + public string InputId { get; } public string Name { get; } public string[] Handlers { get; } public string EventPath { get; } @@ -60,29 +62,4 @@ public class LinuxInputDevice } #endregion - - public class LinuxInputId - { - public LinuxInputId(string line) - { - Dictionary components = line.Split(" ") - .Select(c => c.Split('=')) - .ToDictionary(c => c[0], c => c[1]); - - Bus = components["Bus"]; - Vendor = components["Vendor"]; - Product = components["Product"]; - Version = components["Version"]; - } - - public string Bus { get; } - public string Vendor { get; } - public string Product { get; } - public string Version { get; } - - public override string ToString() - { - return $"Bus={Bus} Vendor={Vendor} Product={Product} Version={Version}"; - } - } } \ No newline at end of file diff --git a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs index be532d250..e8e6dfbc5 100644 --- a/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs +++ b/src/Artemis.UI.Linux/Providers/Input/LinuxInputDeviceFinder.cs @@ -11,9 +11,37 @@ public static class LinuxInputDeviceFinder public static IEnumerable Find() { - return File.ReadAllLines(DEVICES_FILE) - .PartitionBy(s => s?.Length == 0) //split on empty lines - .Select(lineGroup => new LinuxInputDevice(lineGroup)); + var lineGroups = File.ReadAllLines(DEVICES_FILE) + .PartitionBy(s => s?.Length == 0); //split on empty lines + + foreach (var lineGroup in lineGroups) + { + LinuxInputDevice device; + + try + { + device = new LinuxInputDevice(lineGroup); + } + catch + { + continue; + //some devices don't have all the required data, we can ignore those + } + + if (ShouldReadDevice(device)) + { + yield return device; + } + } + } + + private static bool ShouldReadDevice(LinuxInputDevice device) + { + if (device.DeviceType == LinuxDeviceType.Unknown) + return false; + //possibly add more checks here + + return true; } //https://stackoverflow.com/questions/56623354 @@ -34,7 +62,7 @@ public static class LinuxInputDeviceFinder return groupNumber; }; return a - .Select(x => new {Value = x, GroupNumber = getGroupNumber(predicate(x))}) + .Select(x => new { Value = x, GroupNumber = getGroupNumber(predicate(x)) }) .Where(x => x.GroupNumber != null) .GroupBy(x => x.GroupNumber) .Select(g => g.Select(x => x.Value)); diff --git a/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs b/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs index 62866cb00..5c4349231 100644 --- a/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs +++ b/src/Artemis.UI.Linux/Providers/Input/LinuxInputProvider.cs @@ -75,7 +75,7 @@ public class LinuxInputProvider : InputProvider //_logger.Verbose($"Keyboard Key: {(LinuxKeyboardKeyCodes)args.Code} | Down: {isDown}"); - LinuxInputDevice.LinuxInputId identifier = keyboard.InputId; + string identifier = keyboard.InputId; OnIdentifierReceived(identifier, InputDeviceType.Keyboard); ArtemisDevice? device = null; @@ -93,7 +93,7 @@ public class LinuxInputProvider : InputProvider private void HandleMouseData(LinuxInputDevice mouse, LinuxInputEventArgs args) { - LinuxInputDevice.LinuxInputId identifier = mouse.InputId; + string identifier = mouse.InputId; OnIdentifierReceived(identifier, InputDeviceType.Mouse); ArtemisDevice? device = null; From 97b858b332a9d54ca12258b8bea15c18ec1a684d Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Tue, 25 Apr 2023 00:58:47 +0100 Subject: [PATCH 02/14] Linux - input identification fixes --- src/Artemis.UI.Linux/Utilities/InputUtilities.cs | 4 ++-- .../Screens/Device/DeviceDetectInputViewModel.cs | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Artemis.UI.Linux/Utilities/InputUtilities.cs b/src/Artemis.UI.Linux/Utilities/InputUtilities.cs index f898ebb1e..1b567245a 100644 --- a/src/Artemis.UI.Linux/Utilities/InputUtilities.cs +++ b/src/Artemis.UI.Linux/Utilities/InputUtilities.cs @@ -52,7 +52,7 @@ public static class InputUtilities LinuxKeyboardKeyCodes.KEY_APOSTROPHE => KeyboardKey.OemQuotes, LinuxKeyboardKeyCodes.KEY_GRAVE => KeyboardKey.OemTilde, LinuxKeyboardKeyCodes.KEY_LEFTSHIFT => KeyboardKey.LeftShift, - LinuxKeyboardKeyCodes.KEY_BACKSLASH => KeyboardKey.OemBackslash, + LinuxKeyboardKeyCodes.KEY_BACKSLASH => KeyboardKey.OemPipe, LinuxKeyboardKeyCodes.KEY_Z => KeyboardKey.Z, LinuxKeyboardKeyCodes.KEY_X => KeyboardKey.X, LinuxKeyboardKeyCodes.KEY_C => KeyboardKey.C, @@ -94,7 +94,7 @@ public static class InputUtilities LinuxKeyboardKeyCodes.KEY_KP0 => KeyboardKey.NumPad0, LinuxKeyboardKeyCodes.KEY_KPDOT => KeyboardKey.NumPadDecimal, // LinuxKeyboardKeyCodes.KEY_ZENKAKUHANKAKU => expr, - // LinuxKeyboardKeyCodes.KEY_102ND => expr, + LinuxKeyboardKeyCodes.KEY_102ND => KeyboardKey.OemBackslash, LinuxKeyboardKeyCodes.KEY_F11 => KeyboardKey.F11, LinuxKeyboardKeyCodes.KEY_F12 => KeyboardKey.F12, //LinuxKeyboardKeyCodes.KEY_RO => expr, diff --git a/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs b/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs index ee5d0922a..b915e14c6 100644 --- a/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs +++ b/src/Artemis.UI/Screens/Device/DeviceDetectInputViewModel.cs @@ -7,6 +7,7 @@ using Artemis.Core.Services; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.Builders; +using Avalonia.Threading; using FluentAvalonia.UI.Controls; using ReactiveUI; using RGB.NET.Core; @@ -57,10 +58,13 @@ public class DeviceDetectInputViewModel : ContentDialogViewModelBase private void InputServiceOnDeviceIdentified() { - ContentDialog?.Hide(ContentDialogResult.Primary); - _notificationService.CreateNotification() - .WithMessage($"{Device.RgbDevice.DeviceInfo.DeviceName} identified 😁") - .WithSeverity(NotificationSeverity.Success) - .Show(); + Dispatcher.UIThread.Post(() => + { + ContentDialog?.Hide(ContentDialogResult.Primary); + _notificationService.CreateNotification() + .WithMessage($"{Device.RgbDevice.DeviceInfo.DeviceName} identified 😁") + .WithSeverity(NotificationSeverity.Success) + .Show(); + }); } } \ No newline at end of file From c50a572363d65a9af7793c169d95136505786462 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 26 Apr 2023 21:38:15 +0200 Subject: [PATCH 03/14] UI - Update Avalonia to preview7 UI - Update FluentAvalonia to preview7 --- src/Artemis.UI.Linux/Artemis.UI.Linux.csproj | 8 ++-- src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj | 8 ++-- .../Artemis.UI.Shared.csproj | 10 ++--- .../DataModelPicker/DataModelPicker.cs | 2 +- .../Controls/EnumComboBox.axaml.cs | 2 +- .../Shared/DataModelVisualizationViewModel.cs | 4 +- .../DryIoc/ContainerExtensions.cs | 2 +- .../Services/Builders/NotificationBuilder.cs | 18 ++++++--- .../Window/ExceptionDialogViewModel.cs | 5 +-- .../Styles/Controls/DataModelPicker.axaml | 2 +- .../Styles/Controls/GradientPicker.axaml | 6 +-- src/Artemis.UI.Shared/Utilities.cs | 6 +++ .../Artemis.UI.Windows.csproj | 10 ++--- .../Extensions/IWindowImplExtensions.cs | 18 +++++++++ .../Providers/Input/WindowsInputProvider.cs | 10 +++-- .../SkiaSharp/Vulkan/Win32VkContext.cs | 3 +- src/Artemis.UI/Artemis.UI.csproj | 14 +++---- .../BrushPropertyInputView.axaml | 2 +- .../Extensions/ProfileElementExtensions.cs | 15 ++------ src/Artemis.UI/MainWindow.axaml.cs | 1 + .../Screens/Debugger/DebugView.axaml | 2 +- .../Tabs/DataModel/DataModelDebugView.axaml | 2 +- .../PerformanceDebugPluginView.axaml | 2 +- .../PerformanceDebugProfilerView.axaml | 2 +- .../Performance/PerformanceDebugView.axaml | 2 +- .../Performance/PerformanceDebugViewModel.cs | 2 +- .../Screens/Device/DevicePropertiesView.axaml | 4 +- .../Device/Tabs/DeviceInfoTabView.axaml | 38 +++++++++---------- .../Device/Tabs/DeviceInfoTabView.axaml.cs | 11 ++++++ .../Device/Tabs/DeviceInfoTabViewModel.cs | 10 +---- .../Device/Tabs/DeviceLedsTabView.axaml | 2 +- .../Tabs/DeviceLogicalLayoutDialogView.axaml | 2 +- .../Device/Tabs/InputMappingsTabView.axaml | 2 +- ...PluginPrerequisitesInstallDialogView.axaml | 2 +- ...uginPrerequisitesUninstallDialogView.axaml | 2 +- .../Screens/Plugins/PluginSettingsView.axaml | 2 +- .../Screens/Plugins/PluginView.axaml | 2 +- .../DisplayConditionScriptView.axaml | 2 +- .../Panels/Playback/PlaybackViewModel.cs | 4 +- .../Dialogs/LayerHintsDialogView.axaml | 2 +- .../Panels/ProfileTree/ProfileTreeView.axaml | 2 +- .../Panels/ProfileTree/TreeItemViewModel.cs | 10 +---- .../Properties/Dialogs/AddEffectView.axaml | 2 +- .../Panels/Properties/PropertiesView.axaml | 2 +- .../Keyframes/TimelineKeyframeView.axaml | 2 +- .../Keyframes/TimelineKeyframeViewModel.cs | 18 ++------- .../Timeline/TimelineGroupView.axaml | 4 +- .../Timeline/TimelinePropertyView.axaml | 2 +- .../Properties/Timeline/TimelineView.axaml | 2 +- .../Properties/Timeline/TimelineViewModel.cs | 4 +- .../Tree/Dialogs/LayerBrushPresetView.axaml | 2 +- .../Properties/Tree/TreeGroupView.axaml | 2 +- .../VisualEditor/VisualEditorView.axaml | 6 +-- .../ProfileEditor/ProfileEditorView.axaml | 14 +++---- .../ScriptConfigurationCreateView.axaml | 5 ++- .../Screens/Scripting/ScriptsDialogView.axaml | 2 +- .../Screens/Settings/SettingsView.axaml | 2 +- .../Settings/Tabs/DevicesTabView.axaml | 6 ++- .../Settings/Tabs/GeneralTabView.axaml | 12 +++--- .../Settings/Tabs/PluginsTabView.axaml | 2 +- .../Settings/Tabs/ReleasesTabView.axaml | 2 +- .../ModuleActivationRequirementViewModel.cs | 2 +- .../ModuleActivationRequirementsView.axaml | 2 +- .../ProfileConfigurationEditView.axaml | 6 +-- .../Screens/Sidebar/SidebarCategoryView.axaml | 2 +- .../Screens/Sidebar/SidebarView.axaml | 4 +- .../StartupWizard/Steps/DevicesStep.axaml | 2 +- .../SurfaceEditor/SurfaceEditorView.axaml | 4 +- .../VisualScripting/NodePickerView.axaml | 2 +- .../VisualScripting/NodeScriptView.axaml | 4 +- .../VisualScripting/NodeScriptViewModel.cs | 10 +---- .../NodeScriptWindowView.axaml | 4 +- .../NodeScriptWindowViewModel.cs | 4 +- .../Screens/VisualScripting/NodeView.axaml | 8 ++-- .../Pins/InputPinCollectionView.axaml | 2 +- .../Pins/OutputPinCollectionView.axaml | 2 +- .../Artemis.VisualScripting.csproj | 6 +-- .../Screens/LayerPropertyNodeCustomView.axaml | 4 +- .../PressedKeyPositionNodeCustomView.axaml | 2 +- .../Screens/EnumEqualsNodeCustomView.axaml | 2 +- .../DisplayValueNodeCustomViewModel.cs | 2 +- .../EasingFunctionNodeCustomView.axaml | 2 +- 82 files changed, 214 insertions(+), 208 deletions(-) create mode 100644 src/Artemis.UI.Windows/Extensions/IWindowImplExtensions.cs diff --git a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj index 210637896..757dae819 100644 --- a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj +++ b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj @@ -16,11 +16,11 @@ - - + + - - + + diff --git a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj index 000fe864e..389802cda 100644 --- a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj +++ b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj @@ -15,11 +15,11 @@ - - + + - - + + diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 35cf357d8..ecaac854d 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -10,13 +10,13 @@ - + - - - + + + - + diff --git a/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPicker.cs b/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPicker.cs index 621a96161..e3168eaba 100644 --- a/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPicker.cs +++ b/src/Artemis.UI.Shared/Controls/DataModelPicker/DataModelPicker.cs @@ -308,7 +308,7 @@ public class DataModelPicker : TemplatedControl { GetDataModel(); UpdateCurrentPath(true); - _updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(200), DispatcherPriority.Normal, Update); + _updateTimer = new DispatcherTimer(TimeSpan.FromMilliseconds(200), DispatcherPriority.Background, Update); _updateTimer.Start(); } diff --git a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs index ff2869519..bd702941f 100644 --- a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs @@ -91,7 +91,7 @@ public partial class EnumComboBox : UserControl protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) { _enumComboBox = this.Get("ChildEnumComboBox"); - _enumComboBox.Items = _currentValues; + _enumComboBox.ItemsSource = _currentValues; UpdateValues(); UpdateSelection(); diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs index 59ceef437..aa1a25ab4 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs @@ -37,8 +37,8 @@ public abstract class DataModelVisualizationViewModel : ReactiveObject, IDisposa CopyPath = ReactiveCommand.CreateFromTask(async () => { - if (Application.Current?.Clipboard != null && Path != null) - await Application.Current.Clipboard.SetTextAsync(Path); + if (Path != null) + await UI.Clipboard.SetTextAsync(Path); }); if (parent == null) diff --git a/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs b/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs index 1c86ecf84..c1e7006a7 100644 --- a/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.UI.Shared/DryIoc/ContainerExtensions.cs @@ -16,7 +16,7 @@ public static class ContainerExtensions public static void RegisterSharedUI(this IContainer container) { Assembly artemisShared = typeof(IArtemisSharedUIService).GetAssembly(); - container.RegisterMany(new[] { artemisShared }, type => type.IsAssignableTo(), Reuse.Singleton); + container.RegisterMany(new[] {artemisShared}, type => type.IsAssignableTo(), Reuse.Singleton); UI.Locator = container; } diff --git a/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs b/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs index 5ba268315..c506ee1d9 100644 --- a/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs +++ b/src/Artemis.UI.Shared/Services/Builders/NotificationBuilder.cs @@ -26,7 +26,8 @@ public class NotificationBuilder public NotificationBuilder(Window parent) { _parent = parent; - _infoBar = new InfoBar {Classes = Classes.Parse("notification-info-bar")}; + _infoBar = new InfoBar(); + _infoBar.Classes.Add("notification-info-bar"); } /// @@ -204,11 +205,18 @@ public class NotificationButtonBuilder internal Control Build() { + Button button = new() {Content = _text}; + button.Classes.Add("AppBarButton"); + if (_action != null) - return new Button {Content = _text, Command = ReactiveCommand.Create(() => _action()), Classes = new Classes("AppBarButton")}; - if (_command != null) - return new Button {Content = _text, Command = _command, CommandParameter = _commandParameter, Classes = new Classes("AppBarButton")}; - return new Button {Content = _text, Classes = new Classes("AppBarButton")}; + button.Command = ReactiveCommand.Create(() => _action()); + else if (_command != null) + { + button.Command = _command; + button.CommandParameter = _commandParameter; + } + + return button; } } diff --git a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogViewModel.cs b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogViewModel.cs index 7b256509e..06a3ea86c 100644 --- a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogViewModel.cs +++ b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogViewModel.cs @@ -23,10 +23,7 @@ internal class ExceptionDialogViewModel : DialogViewModelBase public async Task CopyException() { - if (Application.Current?.Clipboard == null) - return; - - await Application.Current.Clipboard.SetTextAsync(Exception.ToString()); + await UI.Clipboard.SetTextAsync(Exception.ToString()); _notificationService.CreateNotification() .WithMessage("Copied stack trace to clipboard.") .WithSeverity(NotificationSeverity.Success) diff --git a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml index 67ff351ca..425316ee9 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml @@ -53,7 +53,7 @@ + ItemsSource="{Binding DataModelViewModel.Children, RelativeSource={RelativeSource TemplatedParent}}"> diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowViewModel.cs index 831c69b93..ba87decff 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowViewModel.cs @@ -67,9 +67,9 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase { _keyBindingsEnabled = Shared.UI.KeyBindingsEnabled.ToProperty(this, vm => vm.KeyBindingsEnabled).DisposeWith(d); - DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Normal, Update); + DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Background, Update); // TODO: Remove in favor of saving each time a node editor command is executed - DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Normal, Save); + DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Background, Save); updateTimer.Start(); saveTimer.Start(); diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeView.axaml b/src/Artemis.UI/Screens/VisualScripting/NodeView.axaml index 62838e70c..ea4dc37ad 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeView.axaml +++ b/src/Artemis.UI/Screens/VisualScripting/NodeView.axaml @@ -75,8 +75,8 @@ IsVisible="{CompiledBinding DisplayCustomViewModelAbove}" /> - - + + - - + + - + diff --git a/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinCollectionView.axaml b/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinCollectionView.axaml index 4c4eef93f..b98412f7a 100644 --- a/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinCollectionView.axaml +++ b/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinCollectionView.axaml @@ -14,7 +14,7 @@ Command="{CompiledBinding AddPin}"> - + diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index 03500a177..9c0d6b679 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -8,9 +8,9 @@ - - - + + + diff --git a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml index bfe7ab314..4a323a590 100644 --- a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml @@ -8,8 +8,8 @@ x:DataType="screens:LayerPropertyNodeCustomViewModel"> - - + + diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml index f9a87a72c..bcb70f3f2 100644 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml @@ -11,7 +11,7 @@ x:DataType="screens:PressedKeyPositionNodeCustomViewModel"> Layer - + diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml index b97440803..ef9b82c8e 100644 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml @@ -5,7 +5,7 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.VisualScripting.Nodes.Operators.Screens.EnumEqualsNodeCustomView"> { - DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Normal, Update); + DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Background, Update); updateTimer.Start(); Disposable.Create(() => updateTimer.Stop()).DisposeWith(d); }); diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml index 0170bd620..457cb2994 100644 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml @@ -6,5 +6,5 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.VisualScripting.Nodes.Transition.Screens.EasingFunctionNodeCustomView" x:DataType="screens:EasingFunctionNodeCustomViewModel"> - + \ No newline at end of file From ebe7f68e9d166381eb61f3a5656667ca5be44012 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 27 Apr 2023 10:50:13 +0200 Subject: [PATCH 04/14] Windows - Use user32 APIs to manage windows for input provider and Vulkan --- .../Extensions/IWindowImplExtensions.cs | 18 ------- .../Providers/Input/WindowsInputProvider.cs | 43 ++++------------ .../SkiaSharp/Vulkan/Win32VkContext.cs | 15 +++--- src/Artemis.UI.Windows/User32.cs | 51 +++++++++++++++++++ .../Utilities/WindowUtilities.cs | 11 +--- 5 files changed, 69 insertions(+), 69 deletions(-) delete mode 100644 src/Artemis.UI.Windows/Extensions/IWindowImplExtensions.cs create mode 100644 src/Artemis.UI.Windows/User32.cs diff --git a/src/Artemis.UI.Windows/Extensions/IWindowImplExtensions.cs b/src/Artemis.UI.Windows/Extensions/IWindowImplExtensions.cs deleted file mode 100644 index 18355336e..000000000 --- a/src/Artemis.UI.Windows/Extensions/IWindowImplExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Linq; -using Artemis.UI.Exceptions; -using Avalonia.Platform; - -namespace Artemis.UI.Windows.Extensions; - -public static class IWindowImplExtensions -{ - public static IPlatformHandle GetHandle(this IWindowImpl window) - { - // This is unfortunate - IPlatformHandle? handle = (IPlatformHandle?) window.GetType().GetProperties().FirstOrDefault(p => p.Name == "Handle")?.GetValue(window); - if (handle == null) - throw new ArtemisUIException("Could not get IWindowImpl internal platform handle, Avalonia API change?"); - - return handle; - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs b/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs index 2052da205..45c5624d3 100644 --- a/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs +++ b/src/Artemis.UI.Windows/Providers/Input/WindowsInputProvider.cs @@ -4,10 +4,7 @@ using System.Runtime.InteropServices; using System.Timers; using Artemis.Core; using Artemis.Core.Services; -using Artemis.UI.Windows.Extensions; using Artemis.UI.Windows.Utilities; -using Avalonia.Controls.Platform; -using Avalonia.Platform; using Linearstar.Windows.RawInput; using Linearstar.Windows.RawInput.Native; using Serilog; @@ -19,7 +16,7 @@ public class WindowsInputProvider : InputProvider private const int GWL_WNDPROC = -4; private const int WM_INPUT = 0x00FF; - private readonly IWindowImpl _window; + private readonly nint _hWnd; private readonly nint _hWndProcHook; private readonly WndProc? _fnWndProcHook; private readonly IInputService _inputService; @@ -32,7 +29,7 @@ public class WindowsInputProvider : InputProvider private nint CustomWndProc(nint hWnd, uint msg, nint wParam, nint lParam) { OnWndProcCalled(hWnd, msg, wParam, lParam); - return CallWindowProc(_hWndProcHook, hWnd, msg, wParam, lParam); + return User32.CallWindowProc(_hWndProcHook, hWnd, msg, wParam, lParam); } public WindowsInputProvider(ILogger logger, IInputService inputService) @@ -44,16 +41,14 @@ public class WindowsInputProvider : InputProvider _taskManagerTimer.Elapsed += TaskManagerTimerOnElapsed; _taskManagerTimer.Start(); - _window = PlatformManager.CreateWindow(); - - IPlatformHandle handle = _window.GetHandle(); - _hWndProcHook = GetWindowLongPtr(handle.Handle, GWL_WNDPROC); + _hWnd = User32.CreateWindowEx(0, "STATIC", "", 0x80000000, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + _hWndProcHook = User32.GetWindowLongPtr(_hWnd, GWL_WNDPROC); _fnWndProcHook = CustomWndProc; nint newLong = Marshal.GetFunctionPointerForDelegate(_fnWndProcHook); - SetWindowLongPtr(handle.Handle, GWL_WNDPROC, newLong); + User32.SetWindowLongPtr(_hWnd, GWL_WNDPROC, newLong); - RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, handle.Handle); - RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, handle.Handle); + RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, _hWnd); + RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, _hWnd); } public static Guid Id { get; } = new("6737b204-ffb1-4cd9-8776-9fb851db303a"); @@ -238,31 +233,11 @@ public class WindowsInputProvider : InputProvider #endregion #region Native - - [DllImport("user32.dll", CharSet = CharSet.Unicode)] - static extern IntPtr CallWindowProc(nint lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Unicode)] - private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Unicode)] - private static extern IntPtr SetWindowLongPtr(nint hWnd, int nIndex, IntPtr dwNewLong); - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool GetCursorPos(ref Win32Point pt); - - [StructLayout(LayoutKind.Sequential)] - private struct Win32Point - { - public readonly int X; - public readonly int Y; - } - + private static Win32Point GetCursorPosition() { Win32Point w32Mouse = new(); - GetCursorPos(ref w32Mouse); + User32.GetCursorPos(ref w32Mouse); return w32Mouse; } diff --git a/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs b/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs index 690f28168..6e70f6bdb 100644 --- a/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs +++ b/src/Artemis.UI.Windows/SkiaSharp/Vulkan/Win32VkContext.cs @@ -1,8 +1,5 @@ using System; using System.Linq; -using Artemis.UI.Windows.Extensions; -using Avalonia.Controls.Platform; -using Avalonia.Platform; using SharpVk; using SharpVk.Khronos; @@ -10,12 +7,16 @@ namespace Artemis.UI.Windows.SkiaSharp.Vulkan; internal sealed class Win32VkContext : VkContext { + private readonly nint _hWnd; + public Win32VkContext() { - Window = PlatformManager.CreateWindow(); + // Use WS_CHILD and WS_VISIBLE with WS_VISIBLE set to false + _hWnd = User32.CreateWindowEx(0, "STATIC", "", 0x80000000, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + Instance = Instance.Create(null, new[] {"VK_KHR_surface", "VK_KHR_win32_surface"}); PhysicalDevice = Instance.EnumeratePhysicalDevices().First(); - Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, Window.GetHandle().Handle); + Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, _hWnd); (GraphicsFamily, PresentFamily) = FindQueueFamilies(); @@ -45,12 +46,10 @@ internal sealed class Win32VkContext : VkContext }; } - public IWindowImpl Window { get; } - public override void Dispose() { base.Dispose(); - Window.Dispose(); + User32.DestroyWindow(_hWnd); } private IntPtr Proc(string name, IntPtr instanceHandle, IntPtr deviceHandle) diff --git a/src/Artemis.UI.Windows/User32.cs b/src/Artemis.UI.Windows/User32.cs new file mode 100644 index 000000000..b407f9e51 --- /dev/null +++ b/src/Artemis.UI.Windows/User32.cs @@ -0,0 +1,51 @@ +using System; +using System.Runtime.InteropServices; + +namespace Artemis.UI.Windows; + +static class User32 +{ + [DllImport("user32.dll")] + public static extern IntPtr CreateWindowEx( + uint dwExStyle, + string lpClassName, + string lpWindowName, + uint dwStyle, + int x, + int y, + int nWidth, + int nHeight, + IntPtr hWndParent, + IntPtr hMenu, + IntPtr hInstance, + IntPtr lpParam); + + [DllImport("user32.dll")] + public static extern bool DestroyWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + public static extern IntPtr CallWindowProc(nint lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Unicode)] + public static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Unicode)] + public static extern IntPtr SetWindowLongPtr(nint hWnd, int nIndex, IntPtr dwNewLong); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetCursorPos(ref Win32Point pt); +} + +[StructLayout(LayoutKind.Sequential)] +public struct Win32Point +{ + public readonly int X; + public readonly int Y; +} \ No newline at end of file diff --git a/src/Artemis.UI.Windows/Utilities/WindowUtilities.cs b/src/Artemis.UI.Windows/Utilities/WindowUtilities.cs index 414c12eab..716cc5892 100644 --- a/src/Artemis.UI.Windows/Utilities/WindowUtilities.cs +++ b/src/Artemis.UI.Windows/Utilities/WindowUtilities.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.InteropServices; namespace Artemis.UI.Windows.Utilities; @@ -8,15 +7,9 @@ public static class WindowUtilities public static int GetActiveProcessId() { // Get foreground window handle - IntPtr hWnd = GetForegroundWindow(); + IntPtr hWnd = User32.GetForegroundWindow(); - GetWindowThreadProcessId(hWnd, out uint processId); + User32.GetWindowThreadProcessId(hWnd, out uint processId); return (int) processId; } - - [DllImport("user32.dll")] - private static extern IntPtr GetForegroundWindow(); - - [DllImport("user32.dll")] - private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); } \ No newline at end of file From 33f375e6080f21b79582801dfb78eb53b0915595 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 30 Apr 2023 20:58:30 +0200 Subject: [PATCH 05/14] Added Nuget feed and updated Avalonia to CI build for now --- src/Artemis.UI.Linux/Artemis.UI.Linux.csproj | 8 ++++---- src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj | 8 ++++---- src/Artemis.UI.Shared/Artemis.UI.Shared.csproj | 8 ++++---- src/Artemis.UI.Windows/Artemis.UI.Windows.csproj | 10 +++++----- src/Artemis.UI/Artemis.UI.csproj | 10 +++++----- .../Screens/Device/Tabs/InputMappingsTabViewModel.cs | 10 +++++++--- .../Properties/DataBinding/DataBindingViewModel.cs | 2 +- .../Artemis.VisualScripting.csproj | 4 ++-- src/NuGet.config | 7 +++++++ 9 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 src/NuGet.config diff --git a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj index 757dae819..be2074278 100644 --- a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj +++ b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj @@ -16,11 +16,11 @@ - - + + - - + + diff --git a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj index 389802cda..13707476b 100644 --- a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj +++ b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj @@ -15,11 +15,11 @@ - - + + - - + + diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index ecaac854d..10d2a3f16 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -10,13 +10,13 @@ - + - - + + - + diff --git a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj index 4ef2523c2..f344dc3a0 100644 --- a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj +++ b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj @@ -21,12 +21,12 @@ - - + + - - - + + + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index a7912ac2c..e480ed3aa 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -15,17 +15,17 @@ - + - + - - + + - + diff --git a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs index 355c4a117..5ab20e8fe 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs @@ -6,8 +6,10 @@ using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Exceptions; using Artemis.UI.Shared; +using HidSharp.Reports.Units; using ReactiveUI; using RGB.NET.Core; +using Unit = System.Reactive.Unit; namespace Artemis.UI.Screens.Device; @@ -30,13 +32,13 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase Device = device; DisplayName = "Input Mappings"; InputMappings = new ObservableCollection<(ArtemisLed, ArtemisLed)>(); - + DeleteMapping = ReactiveCommand.Create<(ArtemisLed, ArtemisLed)>(ExecuteDeleteMapping); + this.WhenActivated(d => { _selectedLeds.CollectionChanged += SelectedLedsOnCollectionChanged; _inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp; UpdateInputMappings(); - Disposable.Create(() => { _selectedLeds.CollectionChanged -= SelectedLedsOnCollectionChanged; @@ -46,6 +48,8 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase }); } + public ReactiveCommand<(ArtemisLed, ArtemisLed), Unit> DeleteMapping { get; } + public ArtemisDevice Device { get; } public ArtemisLed? SelectedLed @@ -56,7 +60,7 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase public ObservableCollection<(ArtemisLed, ArtemisLed)> InputMappings { get; } - public void DeleteMapping((ArtemisLed, ArtemisLed) inputMapping) + private void ExecuteDeleteMapping((ArtemisLed, ArtemisLed) inputMapping) { Device.InputMappings.Remove(inputMapping.Item1); UpdateInputMappings(); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs index 078452a81..672e50490 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingViewModel.cs @@ -50,7 +50,7 @@ public class DataBindingViewModel : ActivatableViewModelBase .DisposeWith(d); _profileEditorService.Playing.CombineLatest(_profileEditorService.SuspendedEditing).Subscribe(tuple => _playing = tuple.First || tuple.Second).DisposeWith(d); - DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Render, Update); + DispatcherTimer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000), DispatcherPriority.Background, Update); // TODO: Remove in favor of saving each time a node editor command is executed DispatcherTimer saveTimer = new(TimeSpan.FromMinutes(2), DispatcherPriority.Normal, Save); diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index 9c0d6b679..e4b45b4b7 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/src/NuGet.config b/src/NuGet.config new file mode 100644 index 000000000..2a6054bcd --- /dev/null +++ b/src/NuGet.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 59f9479d9ac6e72d6e16663682c228bd7c3993d0 Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Sun, 30 Apr 2023 17:22:01 +0100 Subject: [PATCH 06/14] WIP - Changed Bindings into CompiledBindings --- src/Artemis.UI.Linux/App.axaml | 16 ++++--- src/Artemis.UI.MacOS/App.axaml | 16 ++++--- .../Controls/DraggableNumberBox.axaml | 14 +++--- .../Controls/HotkeyBox.axaml | 4 +- .../Controls/HotkeyBox.axaml.cs | 2 + .../Display/DefaultDataModelDisplayView.axaml | 12 ++--- .../Services/Window/ExceptionDialogView.axaml | 12 ++--- .../Styles/Controls/DataModelPicker.axaml | 36 +++++++-------- .../Styles/Controls/GradientPicker.axaml | 22 +++++----- src/Artemis.UI.Windows/App.axaml | 16 ++++--- .../BrushPropertyInputView.axaml | 2 +- .../PropertyInput/PropertyInputStyles.axaml | 4 +- src/Artemis.UI/MainWindow.axaml | 9 ++-- .../Tabs/DataModel/DataModelDebugView.axaml | 44 ++++++++++--------- .../PerformanceDebugPluginView.axaml | 8 ++-- .../PerformanceDebugProfilerView.axaml | 17 +++---- .../Performance/PerformanceDebugView.axaml | 12 ++--- .../Tabs/Render/RenderDebugView.axaml | 12 ++--- .../Device/DeviceDetectInputView.axaml | 6 ++- .../Screens/Device/DeviceSettingsView.axaml | 20 +++++---- .../Device/Tabs/DeviceLedsTabView.axaml | 20 ++++----- .../Tabs/DeviceLogicalLayoutDialogView.axaml | 2 +- .../Device/Tabs/DevicePropertiesTabView.axaml | 12 ++--- .../Plugins/Features/PluginFeatureView.axaml | 2 +- .../Plugins/PluginSettingsWindowView.axaml | 2 +- .../Dialogs/LayerHintsDialogView.axaml | 12 ++--- .../ProfileTree/FolderTreeItemView.axaml | 4 +- .../Panels/ProfileTree/ProfileTreeView.axaml | 22 +++++----- .../DataBinding/DataBindingView.axaml | 2 +- .../Timeline/Segments/EndSegmentView.axaml | 6 +-- .../Timeline/Segments/MainSegmentView.axaml | 8 ++-- .../Timeline/Segments/StartSegmentView.axaml | 6 +-- .../Timeline/TimelineGroupView.axaml | 5 ++- .../Properties/Timeline/TimelineView.axaml | 2 +- .../Properties/Tree/TreeGroupView.axaml | 2 +- .../BrushConfigurationWindowView.axaml | 8 ++-- .../EffectConfigurationWindowView.axaml | 8 ++-- .../Panels/StatusBar/StatusBarView.axaml | 16 ++++--- .../Tools/SelectionAddToolView.axaml | 4 +- .../Tools/SelectionRemoveToolView.axaml | 4 +- .../VisualEditor/VisualEditorView.axaml | 15 ++++--- .../Screens/Root/DefaultTitleBarView.axaml | 4 +- src/Artemis.UI/Screens/Root/RootView.axaml | 4 +- .../Screens/Settings/SettingsView.axaml | 2 +- .../Screens/Settings/Tabs/AboutTabView.axaml | 20 +++++---- .../Screens/Sidebar/SidebarCategoryView.axaml | 12 ++--- .../SidebarProfileConfigurationView.axaml | 2 +- .../Screens/Sidebar/SidebarScreenView.axaml | 6 ++- .../StartupWizard/Steps/DevicesStep.axaml | 2 +- .../StartupWizard/Steps/WelcomeStep.axaml | 2 +- .../Screens/VisualScripting/CableView.axaml | 8 ++-- .../VisualScripting/NodePickerView.axaml | 14 +++--- .../VisualScripting/NodeScriptView.axaml | 8 ++-- .../NodeScriptWindowView.axaml | 8 ++-- .../Screens/Workshop/WorkshopView.axaml | 2 +- .../Screens/DisplayValueNodeCustomView.axaml | 4 +- 56 files changed, 293 insertions(+), 251 deletions(-) diff --git a/src/Artemis.UI.Linux/App.axaml b/src/Artemis.UI.Linux/App.axaml index 28101d004..61b3b65c3 100644 --- a/src/Artemis.UI.Linux/App.axaml +++ b/src/Artemis.UI.Linux/App.axaml @@ -1,6 +1,8 @@ @@ -12,16 +14,16 @@ - + - - - - + + + + - - + + diff --git a/src/Artemis.UI.MacOS/App.axaml b/src/Artemis.UI.MacOS/App.axaml index 9eae579ca..a1b602647 100644 --- a/src/Artemis.UI.MacOS/App.axaml +++ b/src/Artemis.UI.MacOS/App.axaml @@ -1,6 +1,8 @@ @@ -12,16 +14,16 @@ - + - - - - + + + + - - + + diff --git a/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml b/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml index 3edd26150..792428eb7 100644 --- a/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml +++ b/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml @@ -1,4 +1,4 @@ - diff --git a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml index 6b7e0c0c1..a3b624d5a 100644 --- a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml +++ b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml @@ -26,8 +26,8 @@ diff --git a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs index 555d21320..0448f9746 100644 --- a/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/HotkeyBox.axaml.cs @@ -35,6 +35,7 @@ public partial class HotkeyBox : UserControl UpdateDisplayTextBox(); } + /// protected override void OnGotFocus(GotFocusEventArgs e) { _inputService.KeyboardKeyDown += InputServiceOnKeyboardKeyDown; @@ -43,6 +44,7 @@ public partial class HotkeyBox : UserControl base.OnGotFocus(e); } + /// protected override void OnLostFocus(RoutedEventArgs e) { _inputService.KeyboardKeyDown -= InputServiceOnKeyboardKeyDown; diff --git a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml index 8b3e3f3ee..bf4eb32f4 100644 --- a/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml +++ b/src/Artemis.UI.Shared/DefaultTypes/DataModel/Display/DefaultDataModelDisplayView.axaml @@ -3,22 +3,24 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + xmlns:local="clr-namespace:Artemis.UI.Shared.DefaultTypes.DataModel.Display" + x:DataType="local:DefaultDataModelDisplayViewModel" x:Class="Artemis.UI.Shared.DefaultTypes.DataModel.Display.DefaultDataModelDisplayView"> - + diff --git a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml index c4c3c9350..3bb950a0f 100644 --- a/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml +++ b/src/Artemis.UI.Shared/Services/Window/ExceptionDialogView.axaml @@ -2,9 +2,11 @@ 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:local="clr-namespace:Artemis.UI.Shared.Services" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="800" x:Class="Artemis.UI.Shared.Services.ExceptionDialogView" - Title="{Binding Title}" + x:DataType="local:ExceptionDialogViewModel" + Title="{CompiledBinding Title}" ExtendClientAreaToDecorationsHint="True" Width="800" Height="800" @@ -16,7 +18,7 @@ - + Awww :( @@ -27,7 +29,7 @@ - - - diff --git a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml index 425316ee9..662a1109f 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml @@ -19,7 +19,7 @@ + IsVisible="{CompiledBinding DataModelPath, RelativeSource={RelativeSource TemplatedParent}, Converter={x:Static ObjectConverters.IsNotNull}}"> + IsVisible="{CompiledBinding !IsEventPicker, RelativeSource={RelativeSource TemplatedParent}}"/> + IsVisible="{CompiledBinding IsEventPicker, RelativeSource={RelativeSource TemplatedParent}}"/> Welcome to the data model picker Select a value from the data model below @@ -53,19 +53,19 @@ + ItemsSource="{CompiledBinding DataModelViewModel.Children, RelativeSource={RelativeSource TemplatedParent}}"> - + - + @@ -75,29 +75,29 @@ - + + ToolTip.Tip="{CompiledBinding PropertyDescription.Description}" + IsVisible="{CompiledBinding IsEventPicker, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dataModelPicker:DataModelPicker}}}"/> - + - + - - + + diff --git a/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml b/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml index 7c3915871..ce985c2c6 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/GradientPicker.axaml @@ -103,10 +103,10 @@ - + GradientPicker="{CompiledBinding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type gradientPicker:GradientPicker}}}"> @@ -152,7 +152,7 @@ - + @@ -174,8 +174,8 @@ UseColorTriangle="True" IsMoreButtonVisible="True" IsVisible="{TemplateBinding SelectedColorStop, Converter={x:Static ObjectConverters.IsNotNull}}" - IsCompact="{Binding IsCompact, RelativeSource={RelativeSource TemplatedParent}}" - Color="{Binding SelectedColorStop.Color, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SKColorToColorConverter}}" /> + IsCompact="{CompiledBinding IsCompact, RelativeSource={RelativeSource TemplatedParent}}" + Color="{CompiledBinding SelectedColorStop.Color, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource SKColorToColorConverter}}" /> @@ -196,19 +196,19 @@ BorderBrush="{DynamicResource ButtonBorderBrush}" ClipToBounds="True" Background="{DynamicResource LightCheckerboardBrush}"> - + - + - + diff --git a/src/Artemis.UI.Windows/App.axaml b/src/Artemis.UI.Windows/App.axaml index 2dfcff610..b9e069434 100644 --- a/src/Artemis.UI.Windows/App.axaml +++ b/src/Artemis.UI.Windows/App.axaml @@ -1,6 +1,8 @@ @@ -12,16 +14,16 @@ - + - - - - + + + + - - + + diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml index 703fb2eba..c84206870 100644 --- a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml +++ b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputView.axaml @@ -34,7 +34,7 @@ - + IsVisible="{CompiledBinding (DataValidationErrors.HasErrors)}" /> - + @@ -30,9 +31,9 @@ - + - + diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml index a34d03df0..cab34445c 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml @@ -5,7 +5,9 @@ xmlns:dataModel="clr-namespace:Artemis.UI.Shared.DataModelVisualization.Shared;assembly=Artemis.UI.Shared" xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" + xmlns:local="clr-namespace:Artemis.UI.Screens.Debugger.DataModel" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:DataType="local:DataModelDebugViewModel" x:Class="Artemis.UI.Screens.Debugger.DataModel.DataModelDebugView"> @@ -21,14 +23,14 @@ - + - + [ - + ] - + - + [ - + ] - + @@ -74,13 +76,13 @@ [ - + ] - + - + @@ -88,29 +90,29 @@ [ - + ] List item # - + - + - + [ - + ] - + diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml index a63c6b3c2..811534402 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugPluginView.axaml @@ -4,15 +4,17 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + xmlns:vm="clr-namespace:Artemis.UI.Screens.Debugger.Performance" + x:DataType="vm:PerformanceDebugPluginViewModel" x:Class="Artemis.UI.Screens.Debugger.Performance.PerformanceDebugPluginView"> - - + + - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml index 73b41e704..da9e2c95e 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugProfilerView.axaml @@ -4,11 +4,12 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Artemis.UI.Screens.Debugger.Performance" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:DataType="local:PerformanceDebugProfilerViewModel" x:Class="Artemis.UI.Screens.Debugger.Performance.PerformanceDebugProfilerView"> - + - - - - - - - + + + + + + diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml index 9debe0621..af60e504b 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Performance/PerformanceDebugView.axaml @@ -3,7 +3,9 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" + xmlns:debugger="clr-namespace:Artemis.UI.Screens.Debugger.Performance;assembly=Artemis.UI" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:DataType="debugger:PerformanceDebugViewModel" x:Class="Artemis.UI.Screens.Debugger.Performance.PerformanceDebugView"> @@ -23,18 +25,18 @@ - + - + - + - + - + diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml index c5258f3a3..9266fbc69 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Render/RenderDebugView.axaml @@ -2,7 +2,9 @@ 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:local="clr-namespace:Artemis.UI.Screens.Debugger.Render" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:DataType="local:RenderDebugViewModel" x:Class="Artemis.UI.Screens.Debugger.Render.RenderDebugView"> Render @@ -15,17 +17,17 @@ - + - + - + - + - + diff --git a/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml b/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml index 310120d5c..5bbc3c926 100644 --- a/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml +++ b/src/Artemis.UI/Screens/Device/DeviceDetectInputView.axaml @@ -4,6 +4,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="1050" + xmlns:devicedetectinput="clr-namespace:Artemis.UI.Screens.Device;assembly=Artemis.UI" + x:DataType="devicedetectinput:DeviceDetectInputViewModel" x:Class="Artemis.UI.Screens.Device.DeviceDetectInputView"> @@ -15,12 +17,12 @@ Width="300" Height="300" HorizontalAlignment="Center" - IsVisible="{Binding !IsMouse}" /> + IsVisible="{CompiledBinding !IsMouse}" /> + IsVisible="{CompiledBinding IsMouse}" /> This will teach Artemis to associate button/key presses with this specific device. diff --git a/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml b/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml index b3f5fe049..6c6330055 100644 --- a/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml +++ b/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml @@ -5,7 +5,9 @@ xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared" + xmlns:local="clr-namespace:Artemis.UI.Screens.Device" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:DataType="local:DeviceSettingsViewModel" x:Class="Artemis.UI.Screens.Device.DeviceSettingsView"> @@ -14,7 +16,7 @@ HorizontalAlignment="Center" Margin="5" ShowColors="False" - Device="{Binding Device}" + Device="{CompiledBinding Device}" Grid.Row="0" /> - + - - + + - + - + - + - + diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml b/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml index dd1ad41cb..bdd07da58 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceLedsTabView.axaml @@ -14,21 +14,21 @@ - - + + - + - - - - - - - + + + + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml b/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml index 1a6f7e5fc..213762d55 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml +++ b/src/Artemis.UI/Screens/Device/Tabs/DeviceLogicalLayoutDialogView.axaml @@ -18,7 +18,7 @@ - + Don't load default layout @@ -169,13 +169,13 @@ - - @@ -189,14 +189,14 @@ - - + + diff --git a/src/Artemis.UI/Screens/Plugins/Features/PluginFeatureView.axaml b/src/Artemis.UI/Screens/Plugins/Features/PluginFeatureView.axaml index 0b8bd3873..4141ec69e 100644 --- a/src/Artemis.UI/Screens/Plugins/Features/PluginFeatureView.axaml +++ b/src/Artemis.UI/Screens/Plugins/Features/PluginFeatureView.axaml @@ -38,7 +38,7 @@ IsVisible="{CompiledBinding LoadException, Converter={x:Static ObjectConverters.IsNotNull}}" Foreground="#E74C4C" ToolTip.Tip="An exception occurred while enabling this feature, click to view" - Command="{Binding ViewLoadException}"> + Command="{CompiledBinding ViewLoadException}"> diff --git a/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml b/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml index a38d666b6..7943954b6 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml +++ b/src/Artemis.UI/Screens/Plugins/PluginSettingsWindowView.axaml @@ -13,7 +13,7 @@ Height="800" WindowStartupLocation="CenterOwner"> - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml index 3f56d7596..95274a66e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/Dialogs/LayerHintsDialogView.axaml @@ -46,7 +46,7 @@ - + @@ -67,22 +67,22 @@ - + - + - + - + @@ -91,7 +91,7 @@ Add hint - + diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml index aa95e39f5..a29cd584d 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/FolderTreeItemView.axaml @@ -20,11 +20,11 @@ + IsVisible="{CompiledBinding !IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" /> + IsVisible="{CompiledBinding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeViewItem}}}" /> diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml index f11b1d995..bfea0d4e5 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/ProfileTree/ProfileTreeView.axaml @@ -54,8 +54,8 @@ - - + + @@ -66,10 +66,10 @@ - - - - + + + + @@ -80,8 +80,8 @@ - - + + @@ -96,12 +96,12 @@ SelectionChanged="ProfileTreeView_OnSelectionChanged"> - - + + diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml index f339a35f5..7ef69ab69 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/DataBinding/DataBindingView.axaml @@ -26,7 +26,7 @@ VerticalAlignment="Center" HorizontalAlignment="Right" Margin="10" - Command="{Binding OpenEditor}"> + Command="{CompiledBinding OpenEditor}"> diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml index 4b81a53c7..d49617362 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml @@ -22,7 +22,7 @@ - + @@ -38,7 +38,7 @@ Name="AddMainSegment" Classes="AppBarButton icon-button icon-button-small" ToolTip.Tip="Add main segment" - Command="{Binding AddMainSegment}" + Command="{CompiledBinding AddMainSegment}" IsVisible="{CompiledBinding ShowAddMain}"> @@ -52,7 +52,7 @@ diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml index 9325e0d67..846f1d021 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml @@ -22,7 +22,7 @@ - + @@ -39,7 +39,7 @@ Classes="AppBarButton icon-button icon-button-small" VerticalAlignment="Center" ToolTip.Tip="Add a start segment" - Command="{Binding AddStartSegment}" + Command="{CompiledBinding AddStartSegment}" IsVisible="{CompiledBinding ShowAddStart}"> @@ -56,7 +56,7 @@ @@ -66,7 +66,7 @@ Classes="AppBarButton icon-button icon-button-small" VerticalAlignment="Center" ToolTip.Tip="Add an end segment" - Command="{Binding AddEndSegment}" + Command="{CompiledBinding AddEndSegment}" IsVisible="{CompiledBinding ShowAddEnd}"> diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml index b58b57539..a121edb07 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml @@ -22,7 +22,7 @@ - + @@ -39,7 +39,7 @@ @@ -48,7 +48,7 @@ Name="AddMainSegment" Classes="AppBarButton icon-button icon-button-small" ToolTip.Tip="Add main segment" - Command="{Binding AddMainSegment}" + Command="{CompiledBinding AddMainSegment}" IsVisible="{CompiledBinding ShowAddMain}"> diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml index b003a3401..5f78cb52e 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineGroupView.axaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:properties="clr-namespace:Artemis.UI.Screens.ProfileEditor.Properties" xmlns:timeline="clr-namespace:Artemis.UI.Screens.ProfileEditor.Properties.Timeline" + xmlns:system="clr-namespace:System;assembly=netstandard" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.ProfileEditor.Properties.Timeline.TimelineGroupView" x:DataType="timeline:TimelineGroupViewModel"> @@ -19,8 +20,8 @@ - diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml index 76f2b6cd4..bba79ebed 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/TimelineView.axaml @@ -10,7 +10,7 @@ x:DataType="timeline:TimelineViewModel"> - + diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml index 849f556e6..9ed3c8be1 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreeGroupView.axaml @@ -25,7 +25,7 @@ BorderBrush="{DynamicResource ButtonBorderBrush}" BorderThickness="0,0,0,1" Height="29"> - + - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml index a6ef2ccd7..134bb9147 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Windows/EffectConfigurationWindowView.axaml @@ -3,16 +3,18 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia" + xmlns:local="clr-namespace:Artemis.UI.Screens.ProfileEditor.Properties.Windows" + x:DataType="local:EffectConfigurationWindowViewModel" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.ProfileEditor.Properties.Windows.EffectConfigurationWindowView" Icon="/Assets/Images/Logo/application.ico" Title="Artemis | Effect configuration" - Width="{Binding Configuration.DialogWidth}" - Height="{Binding Configuration.DialogHeight}" + Width="{CompiledBinding Configuration.DialogWidth}" + Height="{CompiledBinding Configuration.DialogHeight}" WindowStartupLocation="CenterOwner"> - + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml index 4ee09fed8..25c79efee 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/StatusBar/StatusBarView.axaml @@ -5,7 +5,9 @@ xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="23" - x:Class="Artemis.UI.Screens.ProfileEditor.StatusBar.StatusBarView"> + xmlns:vm="clr-namespace:Artemis.UI.Screens.ProfileEditor.StatusBar;assembly=Artemis.UI" + x:DataType="vm:StatusBarViewModel" + x:Class="Artemis.UI.Screens.ProfileEditor.StatusBar.StatusBarView"> - + - + - + - - + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml index 5a5634690..031b8bad3 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionAddToolView.axaml @@ -6,12 +6,12 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.ProfileEditor.VisualEditor.Tools.SelectionAddToolView" ClipToBounds="False"> - + ZoomRatio="{CompiledBinding $parent[ZoomBorder].ZoomX}"> diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml index 16e6a5aba..3c5bd1fc1 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/Tools/SelectionRemoveToolView.axaml @@ -8,12 +8,12 @@ x:Class="Artemis.UI.Screens.ProfileEditor.VisualEditor.Tools.SelectionRemoveToolView" ClipToBounds="False"> - + ZoomRatio="{CompiledBinding $parent[ZoomBorder].ZoomX}"> diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml index 16b1c867c..1056b0f8f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml @@ -5,6 +5,7 @@ xmlns:paz="clr-namespace:Avalonia.Controls.PanAndZoom;assembly=Avalonia.Controls.PanAndZoom" xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core" xmlns:visualEditor="clr-namespace:Artemis.UI.Screens.ProfileEditor.VisualEditor" + xmlns:vis="clr-namespace:Artemis.UI.Screens.ProfileEditor.VisualEditor.Visualizers" xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.ProfileEditor.VisualEditor.VisualEditorView" @@ -40,9 +41,9 @@ - @@ -52,7 +53,7 @@ - + @@ -60,9 +61,9 @@ - diff --git a/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml b/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml index 057fca3d0..975bc5e35 100644 --- a/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml +++ b/src/Artemis.UI/Screens/Root/DefaultTitleBarView.axaml @@ -4,9 +4,11 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia" + xmlns:root="clr-namespace:Artemis.UI.Screens.Root;assembly=Artemis.UI" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:DataType="root:DefaultTitleBarViewModel" x:Class="Artemis.UI.Screens.Root.DefaultTitleBarView"> - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Root/RootView.axaml b/src/Artemis.UI/Screens/Root/RootView.axaml index c3fcadfac..ace901eb7 100644 --- a/src/Artemis.UI/Screens/Root/RootView.axaml +++ b/src/Artemis.UI/Screens/Root/RootView.axaml @@ -4,8 +4,10 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:reactiveUi="http://reactiveui.net" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + xmlns:vm="clr-namespace:Artemis.UI.Screens.Root;assembly=Artemis.UI" + x:DataType="vm:RootViewModel" x:Class="Artemis.UI.Screens.Root.RootView"> - + diff --git a/src/Artemis.UI/Screens/Settings/SettingsView.axaml b/src/Artemis.UI/Screens/Settings/SettingsView.axaml index 8009344d7..386c31d3c 100644 --- a/src/Artemis.UI/Screens/Settings/SettingsView.axaml +++ b/src/Artemis.UI/Screens/Settings/SettingsView.axaml @@ -10,7 +10,7 @@ - + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml index 00014fa1e..a407de94a 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml @@ -4,6 +4,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" + xmlns:vm="clr-namespace:Artemis.UI.Screens.Settings;assembly=Artemis.UI" + x:DataType="vm:AboutTabViewModel" mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="1400" x:Class="Artemis.UI.Screens.Settings.AboutTabView"> @@ -30,7 +32,7 @@ Grid.Column="1" VerticalAlignment="Top" Classes="subtitle" - Text="{Binding Version}" /> + Text="{CompiledBinding Version}" /> + IsVisible="{CompiledBinding RobertProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> - + @@ -78,9 +80,9 @@ Height="75" Width="75" Margin="0 0 15 0" - IsVisible="{Binding DarthAffeProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> + IsVisible="{CompiledBinding DarthAffeProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> - + @@ -106,9 +108,9 @@ Height="75" Width="75" Margin="0 0 15 0" - IsVisible="{Binding DrMeteorProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> + IsVisible="{CompiledBinding DrMeteorProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> - + @@ -134,9 +136,9 @@ Height="75" Width="75" Margin="0 0 15 0" - IsVisible="{Binding KaiProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> + IsVisible="{CompiledBinding KaiProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> - + diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarCategoryView.axaml b/src/Artemis.UI/Screens/Sidebar/SidebarCategoryView.axaml index 8c50f252d..25f43bbf2 100644 --- a/src/Artemis.UI/Screens/Sidebar/SidebarCategoryView.axaml +++ b/src/Artemis.UI/Screens/Sidebar/SidebarCategoryView.axaml @@ -115,8 +115,8 @@ - - + + @@ -125,8 +125,8 @@ - - + + @@ -139,8 +139,8 @@ Margin="0 8 0 0" RowDefinitions="Auto,*" ContextFlyout="{StaticResource CategoryMenuFlyout}" - Classes.flyout-open="{Binding IsOpen, Source={StaticResource CategoryMenuFlyout}}" - Classes.plus-flyout-open="{Binding IsOpen, Source={StaticResource PlusMenuFlyout}}"> + Classes.flyout-open="{CompiledBinding IsOpen, Source={StaticResource CategoryMenuFlyout}}" + Classes.plus-flyout-open="{CompiledBinding IsOpen, Source={StaticResource PlusMenuFlyout}}"> + Classes.flyout-open="{CompiledBinding IsOpen, Source={StaticResource ProfileMenuFlyout}}"> - - + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/StartupWizard/Steps/DevicesStep.axaml b/src/Artemis.UI/Screens/StartupWizard/Steps/DevicesStep.axaml index ae37209bb..49ac924a0 100644 --- a/src/Artemis.UI/Screens/StartupWizard/Steps/DevicesStep.axaml +++ b/src/Artemis.UI/Screens/StartupWizard/Steps/DevicesStep.axaml @@ -28,7 +28,7 @@ - + diff --git a/src/Artemis.UI/Screens/StartupWizard/Steps/WelcomeStep.axaml b/src/Artemis.UI/Screens/StartupWizard/Steps/WelcomeStep.axaml index 6422e2508..5c9df872f 100644 --- a/src/Artemis.UI/Screens/StartupWizard/Steps/WelcomeStep.axaml +++ b/src/Artemis.UI/Screens/StartupWizard/Steps/WelcomeStep.axaml @@ -31,7 +31,7 @@ Grid.Column="1" VerticalAlignment="Top" Classes="subtitle" - Text="{Binding Version}" /> + Text="{CompiledBinding Version}" /> - + @@ -64,13 +64,13 @@ - + - + - + diff --git a/src/Artemis.UI/Screens/VisualScripting/NodePickerView.axaml b/src/Artemis.UI/Screens/VisualScripting/NodePickerView.axaml index 197f4f354..8fe19c727 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodePickerView.axaml +++ b/src/Artemis.UI/Screens/VisualScripting/NodePickerView.axaml @@ -19,12 +19,12 @@ diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml index de10ffaa4..8ddaf5f77 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml @@ -38,7 +38,7 @@ ClipToBounds="True"> - + @@ -46,7 +46,7 @@ - + From 542934639616f357ebe7570adc4363078f7fcdd6 Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Sun, 30 Apr 2023 17:32:51 +0100 Subject: [PATCH 07/14] UI - Replaced tuples with custom classes for binding As far as i know, it's not possible to have CompiledBindings with tuples, since tuple values are fields and not properties. This change allows for compiled bindings, and makes the intent behind the tuples clearer --- .../Controls/EnumComboBox.axaml | 5 +- .../Controls/EnumComboBox.axaml.cs | 58 +++++++++++++------ .../Device/Tabs/InputMappingsTabView.axaml | 4 +- .../Device/Tabs/InputMappingsTabViewModel.cs | 41 ++++++++++--- .../Properties/Tree/TreePropertyView.axaml | 2 +- .../Pins/InputPinView.axaml.cs | 2 +- .../Pins/OutputPinView.axaml.cs | 2 +- .../Screens/EnumEqualsNodeCustomView.axaml | 10 ++-- .../Screens/EnumEqualsNodeCustomViewModel.cs | 41 ++++++++++--- 9 files changed, 120 insertions(+), 45 deletions(-) diff --git a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml index 1849c97e5..19c39fd7d 100644 --- a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml +++ b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml @@ -3,11 +3,12 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + xmlns:local="clr-namespace:Artemis.UI.Shared" x:Class="Artemis.UI.Shared.EnumComboBox"> - - + + diff --git a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs index bd702941f..8fcd1eba4 100644 --- a/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/EnumComboBox.axaml.cs @@ -20,11 +20,9 @@ public partial class EnumComboBox : UserControl /// public static readonly StyledProperty ValueProperty = AvaloniaProperty.Register(nameof(Value), defaultBindingMode: BindingMode.TwoWay); - private readonly ObservableCollection<(Enum, string)> _currentValues = new(); + private readonly ObservableCollection _currentValues = new(); private Type? _currentType; - private ComboBox? _enumComboBox; - /// /// Creates a new instance of the class. /// @@ -54,35 +52,35 @@ public partial class EnumComboBox : UserControl private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e) { - if (_enumComboBox == null || _enumComboBox.SelectedIndex == -1) + if (ChildEnumComboBox == null || ChildEnumComboBox.SelectedIndex == -1) return; - (Enum enumValue, _) = _currentValues[_enumComboBox.SelectedIndex]; - if (!Equals(Value, enumValue)) - Value = enumValue; + EnumComboBoxItem v = _currentValues[ChildEnumComboBox.SelectedIndex]; + if (!Equals(Value, v.Value)) + Value = v.Value; } private void UpdateValues() { Type? newType = Value?.GetType(); - if (_enumComboBox == null || newType == null || _currentType == newType) + if (ChildEnumComboBox == null || newType == null || _currentType == newType) return; _currentValues.Clear(); foreach ((Enum, string) valueDesc in EnumUtilities.GetAllValuesAndDescriptions(newType)) - _currentValues.Add(valueDesc); + _currentValues.Add(new EnumComboBoxItem(value: valueDesc.Item1, description: valueDesc.Item2)); _currentType = newType; } private void UpdateSelection() { - if (_enumComboBox == null || Value is not Enum) + if (ChildEnumComboBox == null || Value is not Enum) return; - (Enum, string) value = _currentValues.FirstOrDefault(v => v.Item1.Equals(Value)); - if (!Equals(value.Item1, _enumComboBox.SelectedItem)) - _enumComboBox.SelectedItem = value; + EnumComboBoxItem? value = _currentValues.FirstOrDefault(v => v.Value.Equals(Value)); + if (!Equals(value?.Value, ChildEnumComboBox.SelectedItem)) + ChildEnumComboBox.SelectedItem = value; } #region Overrides of TemplatedControl @@ -90,12 +88,11 @@ public partial class EnumComboBox : UserControl /// protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) { - _enumComboBox = this.Get("ChildEnumComboBox"); - _enumComboBox.ItemsSource = _currentValues; + ChildEnumComboBox.ItemsSource = _currentValues; UpdateValues(); UpdateSelection(); - _enumComboBox.SelectionChanged += OnSelectionChanged; + ChildEnumComboBox.SelectionChanged += OnSelectionChanged; base.OnAttachedToLogicalTree(e); } @@ -103,11 +100,36 @@ public partial class EnumComboBox : UserControl /// protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) { - if (_enumComboBox != null) - _enumComboBox.SelectionChanged -= OnSelectionChanged; + if (ChildEnumComboBox != null) + ChildEnumComboBox.SelectionChanged -= OnSelectionChanged; base.OnDetachedFromLogicalTree(e); } #endregion +} + +/// +/// Represents an item in the +/// +public class EnumComboBoxItem +{ + /// + /// Creates a new instance of the class. + /// + public EnumComboBoxItem(Enum value, string description) + { + Value = value; + Description = description; + } + + /// + /// Gets or sets the value of the item + /// + public Enum Value { get; set; } + + /// + /// Gets or sets the description of the item + /// + public string Description { get; set; } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml index ccd896545..e7c3bb42d 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml +++ b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabView.axaml @@ -48,8 +48,8 @@ AutoGenerateColumns="False" Margin="10"> - - + + diff --git a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs index 5ab20e8fe..4d3acd760 100644 --- a/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs +++ b/src/Artemis.UI/Screens/Device/Tabs/InputMappingsTabViewModel.cs @@ -1,4 +1,4 @@ -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; using System.Reactive.Disposables; @@ -31,8 +31,8 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase Device = device; DisplayName = "Input Mappings"; - InputMappings = new ObservableCollection<(ArtemisLed, ArtemisLed)>(); - DeleteMapping = ReactiveCommand.Create<(ArtemisLed, ArtemisLed)>(ExecuteDeleteMapping); + InputMappings = new ObservableCollection(); + DeleteMapping = ReactiveCommand.Create(ExecuteDeleteMapping); this.WhenActivated(d => { @@ -48,7 +48,7 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase }); } - public ReactiveCommand<(ArtemisLed, ArtemisLed), Unit> DeleteMapping { get; } + public ReactiveCommand DeleteMapping { get; } public ArtemisDevice Device { get; } @@ -58,11 +58,11 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase set => RaiseAndSetIfChanged(ref _selectedLed, value); } - public ObservableCollection<(ArtemisLed, ArtemisLed)> InputMappings { get; } + public ObservableCollection InputMappings { get; } - private void ExecuteDeleteMapping((ArtemisLed, ArtemisLed) inputMapping) + private void ExecuteDeleteMapping(ArtemisInputMapping inputMapping) { - Device.InputMappings.Remove(inputMapping.Item1); + Device.InputMappings.Remove(inputMapping.Original); UpdateInputMappings(); } @@ -92,7 +92,7 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase if (InputMappings.Any()) InputMappings.Clear(); - foreach ((ArtemisLed, ArtemisLed) tuple in Device.InputMappings.Select(m => (m.Key, m.Value))) + foreach (ArtemisInputMapping tuple in Device.InputMappings.Select(m => new ArtemisInputMapping(m.Key, m.Value))) InputMappings.Add(tuple); } @@ -100,4 +100,29 @@ public class InputMappingsTabViewModel : ActivatableViewModelBase { SelectedLed = _selectedLeds.FirstOrDefault(); } +} + +/// +/// Represents a pair of LEDs, the original and the replacement +/// +public class ArtemisInputMapping +{ + /// + /// Creates a new instance of the class + /// + public ArtemisInputMapping(ArtemisLed original, ArtemisLed replacement) + { + Original = original; + Replacement = replacement; + } + + /// + /// The original LED + /// + public ArtemisLed Original { get; set; } + + /// + /// The replacement LED + /// + public ArtemisLed Replacement { get; set; } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml index 64b32bf15..2d87a8108 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Tree/TreePropertyView.axaml @@ -15,7 +15,7 @@ BorderBrush="{DynamicResource ButtonBorderBrush}" BorderThickness="0,0,0,1" Height="29"> - + ("PinPoint")); + InitializePin(PinPoint); } diff --git a/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinView.axaml.cs b/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinView.axaml.cs index 9ba43f5c8..ed186c039 100644 --- a/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinView.axaml.cs +++ b/src/Artemis.UI/Screens/VisualScripting/Pins/OutputPinView.axaml.cs @@ -10,7 +10,7 @@ public partial class OutputPinView : PinView public OutputPinView() { InitializeComponent(); - InitializePin(this.Get("PinPoint")); + InitializePin(PinPoint); } diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml index ef9b82c8e..3d6357933 100644 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml @@ -3,10 +3,12 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + xmlns:vm="clr-namespace:Artemis.VisualScripting.Nodes.Operators.Screens" + x:DataType="vm:EnumEqualsNodeCustomViewModel" x:Class="Artemis.VisualScripting.Nodes.Operators.Screens.EnumEqualsNodeCustomView"> - @@ -17,7 +19,7 @@ - + diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs index 7fee56fa6..f4a99a08d 100644 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs +++ b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs @@ -42,15 +42,15 @@ public class EnumEqualsNodeCustomViewModel : CustomNodeViewModel }); } - public ObservableCollection<(long, string)> EnumValues { get; } = new(); + public ObservableCollection EnumValues { get; } = new(); - public (long, string) CurrentValue + public EnumValueItem CurrentValue { - get => EnumValues.FirstOrDefault(v => v.Item1 == _node.Storage); + get => EnumValues.FirstOrDefault(v => v.Value == _node.Storage); set { - if (!Equals(_node.Storage, value.Item1)) - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value.Item1)); + if (!Equals(_node.Storage, value.Value)) + _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value.Value)); } } @@ -58,13 +58,38 @@ public class EnumEqualsNodeCustomViewModel : CustomNodeViewModel { Dispatcher.UIThread.Post(() => { - List<(long, string)> values = Enum.GetValues(type).Cast().Select(e => (Convert.ToInt64(e), e.Humanize())).ToList(); + List values = Enum.GetValues(type).Cast().Select(e => new EnumValueItem(value: Convert.ToInt64(e), name: e.Humanize())).ToList(); if (values.Count > 20) - EnumValues.AddRange(values.OrderBy(v => v.Item2)); + EnumValues.AddRange(values.OrderBy(v => v.Name)); else - EnumValues.AddRange(Enum.GetValues(type).Cast().Select(e => (Convert.ToInt64(e), e.Humanize()))); + EnumValues.AddRange(values); this.RaisePropertyChanged(nameof(CurrentValue)); }, DispatcherPriority.Background); } +} + +/// +/// Represents a single enum value +/// +public class EnumValueItem +{ + /// + /// Creates a new instance of the class. + /// + public EnumValueItem(long value, string name) + { + Value = value; + Name = name; + } + + /// + /// The underlying value of the enum + /// + public long Value { get; set; } + + /// + /// The name of the enum value + /// + public string Name { get; set; } } \ No newline at end of file From 5fc2f9e23c6c61cb3224e89f98d80a25c8a44f75 Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 6 May 2023 13:11:09 +0200 Subject: [PATCH 08/14] Fix draggable number box min and max not applying Disable transitions --- src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml | 2 ++ src/Artemis.UI/Screens/Root/RootView.axaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml b/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml index 3edd26150..68335adf2 100644 --- a/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml +++ b/src/Artemis.UI.Shared/Controls/DraggableNumberBox.axaml @@ -27,6 +27,8 @@ AcceptsExpression="True" LargeChange="{Binding $parent[sharedControls:DraggableNumberBox].LargeChange}" SmallChange="{Binding $parent[sharedControls:DraggableNumberBox].SmallChange}" + Minimum="{Binding $parent[sharedControls:DraggableNumberBox].Minimum}" + Maximum="{Binding $parent[sharedControls:DraggableNumberBox].Maximum}" SimpleNumberFormat="{Binding $parent[sharedControls:DraggableNumberBox].SimpleNumberFormat}" attachedProperties:NumberBoxAssist.PrefixText="{Binding $parent[sharedControls:DraggableNumberBox].Prefix}" attachedProperties:NumberBoxAssist.SuffixText="{Binding $parent[sharedControls:DraggableNumberBox].Suffix}" diff --git a/src/Artemis.UI/Screens/Root/RootView.axaml b/src/Artemis.UI/Screens/Root/RootView.axaml index c3fcadfac..2caea8d00 100644 --- a/src/Artemis.UI/Screens/Root/RootView.axaml +++ b/src/Artemis.UI/Screens/Root/RootView.axaml @@ -7,7 +7,7 @@ x:Class="Artemis.UI.Screens.Root.RootView"> - + \ No newline at end of file From c793c0ba3584e8b7f2c72565d7b6c473137042de Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 6 May 2023 14:36:17 +0200 Subject: [PATCH 09/14] Fix editor margin --- src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml index c93da2de2..e2693f3ee 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileEditorView.axaml @@ -47,8 +47,8 @@ - From becc6e0715f6da061964ca4962505bc2f632bf7f Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Sat, 6 May 2023 15:39:47 +0100 Subject: [PATCH 10/14] Linux - cleanup initialization --- src/Artemis.UI.Linux/App.axaml.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Artemis.UI.Linux/App.axaml.cs b/src/Artemis.UI.Linux/App.axaml.cs index 1a6cd64a5..52f729727 100644 --- a/src/Artemis.UI.Linux/App.axaml.cs +++ b/src/Artemis.UI.Linux/App.axaml.cs @@ -22,18 +22,20 @@ public class App : Application Program.CreateLogger(_container); RxApp.MainThreadScheduler = AvaloniaScheduler.Instance; AvaloniaXamlLoader.Load(this); - - RegisterProviders(); } public override void OnFrameworkInitializationCompleted() { if (Design.IsDesignMode) return; - + + if (ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop) + return; + ArtemisBootstrapper.Initialize(); - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - _applicationStateManager = new ApplicationStateManager(_container!, desktop.Args); + + _applicationStateManager = new ApplicationStateManager(_container!, desktop.Args); + RegisterProviders(); } private void RegisterProviders() From bf6674e44f39260db1cef726b8ae81e3ee9f57cd Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 11 May 2023 23:10:40 +0200 Subject: [PATCH 11/14] Upgraded to preview8 --- src/Artemis.Core/Artemis.Core.csproj | 2 +- src/Artemis.UI.Linux/Artemis.UI.Linux.csproj | 8 ++-- src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj | 8 ++-- .../Artemis.UI.Shared.csproj | 10 ++--- .../Controls/ArtemisIcon.axaml.cs | 2 +- .../Controls/DeviceVisualizer.cs | 7 ++- .../Controls/DeviceVisualizerLed.cs | 3 +- .../ProfileConfigurationIcon.axaml.cs | 2 +- .../Artemis.UI.Windows.csproj | 10 ++--- .../Providers/AutoRunProvider.cs | 8 +--- .../Providers/CursorProvider.cs | 8 ++-- src/Artemis.UI/Artemis.UI.csproj | 18 ++++---- src/Artemis.UI/DryIoc/ContainerExtensions.cs | 6 +-- src/Artemis.UI/MainWindow.axaml.cs | 26 ++++++----- .../Panels/Playback/PlaybackViewModel.cs | 2 +- .../Properties/PropertyGroupViewModel.cs | 6 +-- src/Artemis.UI/Screens/Root/RootViewModel.cs | 3 -- .../Screens/Settings/Tabs/AboutTabView.axaml | 22 +++++---- .../ProfileConfigurationEditView.axaml | 13 ++++-- .../VisualScripting/NodeMenuItemViewModel.cs | 2 + .../NodeScriptWindowView.axaml | 45 ++++++++++++------- .../Artemis.VisualScripting.csproj | 8 ++-- .../Artemis.WebClient.Updating.csproj | 4 +- src/NuGet.config | 7 --- 24 files changed, 117 insertions(+), 113 deletions(-) delete mode 100644 src/NuGet.config diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index f4e4d85f2..daffe59a4 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -35,7 +35,7 @@ - + diff --git a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj index be2074278..9607a10d8 100644 --- a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj +++ b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj @@ -16,11 +16,11 @@ - - + + - - + + diff --git a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj index 13707476b..e674a2ad6 100644 --- a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj +++ b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj @@ -15,11 +15,11 @@ - - + + - - + + diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 10d2a3f16..4c5b91ce8 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -10,13 +10,13 @@ - + - - - + + + - + diff --git a/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs b/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs index e403d0c93..6e174235d 100644 --- a/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/ArtemisIcon.axaml.cs @@ -64,7 +64,7 @@ public partial class ArtemisIcon : UserControl Background = TextElement.GetForeground(this), VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch, - OpacityMask = new ImageBrush(new Bitmap(iconString)) {BitmapInterpolationMode = BitmapInterpolationMode.MediumQuality} + OpacityMask = new ImageBrush(new Bitmap(iconString)) }; } else diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index b93053583..8541d98a6 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -67,8 +67,7 @@ public class DeviceVisualizer : Control drawingContext.DrawImage( _deviceImage, new Rect(_deviceImage.Size), - new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height), - RenderOptions.GetBitmapInterpolationMode(this) + new Rect(0, 0, Device.RgbDevice.ActualSize.Width, Device.RgbDevice.ActualSize.Height) ); if (!ShowColors) @@ -306,8 +305,8 @@ public class DeviceVisualizer : Control using DrawingContext context = renderTargetBitmap.CreateDrawingContext(); using Bitmap bitmap = new(device.Layout.Image.LocalPath); - context.DrawImage(bitmap, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size), BitmapInterpolationMode.HighQuality); - + + context.DrawImage(bitmap, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size)); lock (_deviceVisualizerLeds) { foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds) diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs index 5164d5844..29e219fb9 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs @@ -49,8 +49,7 @@ internal class DeviceVisualizerLed drawingContext.DrawImage( bitmap, new Rect(bitmap.Size), - new Rect(Led.RgbLed.Location.X * scale, Led.RgbLed.Location.Y * scale, Led.RgbLed.Size.Width * scale, Led.RgbLed.Size.Height * scale), - BitmapInterpolationMode.HighQuality + new Rect(Led.RgbLed.Location.X * scale, Led.RgbLed.Location.Y * scale, Led.RgbLed.Size.Width * scale, Led.RgbLed.Size.Height * scale) ); } catch diff --git a/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs b/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs index 4dd0711ba..0e8b9adcb 100644 --- a/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs +++ b/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs @@ -75,7 +75,7 @@ public partial class ProfileConfigurationIcon : UserControl, IDisposable Background = TextElement.GetForeground(this), VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch, - OpacityMask = new ImageBrush(new Bitmap(stream)) {BitmapInterpolationMode = BitmapInterpolationMode.MediumQuality} + OpacityMask = new ImageBrush(new Bitmap(stream)) }; } diff --git a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj index f344dc3a0..bdea0536c 100644 --- a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj +++ b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj @@ -21,12 +21,12 @@ - - + + - - - + + + diff --git a/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs b/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs index 331352a9a..3108bf5fe 100644 --- a/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs +++ b/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs @@ -16,12 +16,6 @@ public class AutoRunProvider : IAutoRunProvider { private readonly string _autorunName = $"Artemis 2 autorun {Environment.UserName}"; private readonly string _oldAutorunName = "Artemis 2 autorun"; - private readonly IAssetLoader _assetLoader; - - public AutoRunProvider(IAssetLoader assetLoader) - { - _assetLoader = assetLoader; - } private async Task IsAutoRunTaskCreated(string autorunName) { @@ -43,7 +37,7 @@ public class AutoRunProvider : IAutoRunProvider private async Task CreateAutoRunTask(TimeSpan autoRunDelay, string autorunName) { - await using Stream taskFile = _assetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/autorun.xml")); + await using Stream taskFile = AssetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/autorun.xml")); XDocument document = await XDocument.LoadAsync(taskFile, LoadOptions.None, CancellationToken.None); XElement task = document.Descendants().First(); diff --git a/src/Artemis.UI.Windows/Providers/CursorProvider.cs b/src/Artemis.UI.Windows/Providers/CursorProvider.cs index 97a53f032..68227810e 100644 --- a/src/Artemis.UI.Windows/Providers/CursorProvider.cs +++ b/src/Artemis.UI.Windows/Providers/CursorProvider.cs @@ -9,11 +9,11 @@ namespace Artemis.UI.Windows.Providers; public class CursorProvider : ICursorProvider { - public CursorProvider(IAssetLoader assetLoader) + public CursorProvider() { - Rotate = new Cursor(new Bitmap(assetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/Cursors/aero_rotate.png"))), new PixelPoint(21, 10)); - Drag = new Cursor(new Bitmap(assetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/Cursors/aero_drag.png"))), new PixelPoint(11, 3)); - DragHorizontal = new Cursor(new Bitmap(assetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/Cursors/aero_drag_horizontal.png"))), new PixelPoint(16, 5)); + Rotate = new Cursor(new Bitmap(AssetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/Cursors/aero_rotate.png"))), new PixelPoint(21, 10)); + Drag = new Cursor(new Bitmap(AssetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/Cursors/aero_drag.png"))), new PixelPoint(11, 3)); + DragHorizontal = new Cursor(new Bitmap(AssetLoader.Open(new Uri("avares://Artemis.UI.Windows/Assets/Cursors/aero_drag_horizontal.png"))), new PixelPoint(16, 5)); } public Cursor Rotate { get; } diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index e480ed3aa..75fa4b7da 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -15,17 +15,17 @@ - - - - + + + + - - - - + + + + - + diff --git a/src/Artemis.UI/DryIoc/ContainerExtensions.cs b/src/Artemis.UI/DryIoc/ContainerExtensions.cs index 9d63bb539..310b06b21 100644 --- a/src/Artemis.UI/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.UI/DryIoc/ContainerExtensions.cs @@ -7,7 +7,6 @@ using Artemis.UI.Services.Updating; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.NodeEditor; using Artemis.UI.Shared.Services.ProfileEditor; -using Avalonia.Platform; using DryIoc; namespace Artemis.UI.DryIoc; @@ -24,11 +23,8 @@ public static class ContainerExtensions public static void RegisterUI(this IContainer container) { Assembly[] thisAssembly = {typeof(ContainerExtensions).Assembly}; - - container.RegisterInstance(new AssetLoader(), IfAlreadyRegistered.Throw); - container.Register(Reuse.Singleton); - container.RegisterMany(thisAssembly, type => type.IsAssignableTo()); + container.RegisterMany(thisAssembly, type => type.IsAssignableTo(), setup: Setup.With(preventDisposal: true)); container.RegisterMany(thisAssembly, type => type.IsAssignableTo() && type.IsInterface); container.RegisterMany(thisAssembly, type => type.IsAssignableTo() && type != typeof(PropertyVmFactory)); diff --git a/src/Artemis.UI/MainWindow.axaml.cs b/src/Artemis.UI/MainWindow.axaml.cs index a687aad64..701519b20 100644 --- a/src/Artemis.UI/MainWindow.axaml.cs +++ b/src/Artemis.UI/MainWindow.axaml.cs @@ -6,7 +6,6 @@ using Artemis.UI.Screens.Root; using Artemis.UI.Shared; using Avalonia; using Avalonia.Controls; -using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; using ReactiveUI; @@ -15,28 +14,24 @@ namespace Artemis.UI; public partial class MainWindow : ReactiveAppWindow { private bool _activated; + private IDisposable? _positionObserver; public MainWindow() { Opened += OnOpened; + Closed += OnClosed; Activated += OnActivated; Deactivated += OnDeactivated; InitializeComponent(); ApplyWindowSize(); - + Shared.UI.Clipboard = GetTopLevel(this)!.Clipboard!; RootPanel.LayoutUpdated += OnLayoutUpdated; #if DEBUG this.AttachDevTools(); #endif - - Observable.FromEventPattern(x => PositionChanged += x, x => PositionChanged -= x) - .Select(_ => Unit.Default) - .Merge(this.WhenAnyValue(vm => vm.WindowState, vm => vm.Width, vm => vm.Width, vm => vm.Height).Select(_ => Unit.Default)) - .Throttle(TimeSpan.FromMilliseconds(200), AvaloniaScheduler.Instance) - .Subscribe(_ => SaveWindowSize()); } private void ApplyWindowSize() @@ -53,7 +48,7 @@ public partial class MainWindow : ReactiveAppWindow RootViewModel.WindowSizeSetting.Value ??= new WindowSize(); RootViewModel.WindowSizeSetting.Value.ApplyFromWindow(this); } - + private void OnLayoutUpdated(object? sender, EventArgs e) { SidebarContentControl.Width = RootPanel.Bounds.Width >= 1800 ? 300 : 240; @@ -61,8 +56,18 @@ public partial class MainWindow : ReactiveAppWindow private void OnOpened(object? sender, EventArgs e) { - Opened -= OnOpened; TitleBar.ExtendsContentIntoTitleBar = true; + + _positionObserver = Observable.FromEventPattern(x => PositionChanged += x, x => PositionChanged -= x) + .Select(_ => Unit.Default) + .Merge(this.WhenAnyValue(vm => vm.WindowState, vm => vm.Width, vm => vm.Width, vm => vm.Height).Select(_ => Unit.Default)) + .Throttle(TimeSpan.FromMilliseconds(200), AvaloniaScheduler.Instance) + .Subscribe(_ => SaveWindowSize()); + } + + private void OnClosed(object? sender, EventArgs e) + { + _positionObserver?.Dispose(); } private void OnActivated(object? sender, EventArgs e) @@ -74,5 +79,4 @@ public partial class MainWindow : ReactiveAppWindow { ViewModel?.Unfocused(); } - } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs index 06c735466..dc4390255 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Playback/PlaybackViewModel.cs @@ -59,7 +59,7 @@ public class PlaybackViewModel : ActivatableViewModelBase updateTimer.Start(); Disposable.Create(() => { - // updateTimer.Stop(); + updateTimer.Stop(); _settingsService.GetSetting("ProfileEditor.RepeatTimeline", true).Value = _repeating && _repeatTimeline; _settingsService.GetSetting("ProfileEditor.RepeatSegment", false).Value = _repeating && _repeatSegment; }).DisposeWith(d); diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs index bb0c78c20..7427545ab 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/PropertyGroupViewModel.cs @@ -179,12 +179,12 @@ public class PropertyGroupViewModel : PropertyViewModelBase, IDisposable public void Dispose() { LayerPropertyGroup.VisibilityChanged -= LayerPropertyGroupOnVisibilityChanged; - foreach (ViewModelBase viewModelBase in Children) + while (Children.Any()) { - if (viewModelBase is IDisposable disposable) + if (Children[0] is IDisposable disposable) disposable.Dispose(); + Children.RemoveAt(0); } - _keyframeSubscription.Dispose(); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Root/RootViewModel.cs b/src/Artemis.UI/Screens/Root/RootViewModel.cs index dd90f1dd8..b9860c8c1 100644 --- a/src/Artemis.UI/Screens/Root/RootViewModel.cs +++ b/src/Artemis.UI/Screens/Root/RootViewModel.cs @@ -22,7 +22,6 @@ namespace Artemis.UI.Screens.Root; public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvider { - private readonly IAssetLoader _assetLoader; private readonly ICoreService _coreService; private readonly IDebugService _debugService; private readonly DefaultTitleBarViewModel _defaultTitleBarViewModel; @@ -41,7 +40,6 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi IMainWindowService mainWindowService, IDebugService debugService, IUpdateService updateService, - IAssetLoader assetLoader, DefaultTitleBarViewModel defaultTitleBarViewModel, ISidebarVmFactory sidebarVmFactory) { @@ -53,7 +51,6 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi _windowService = windowService; _debugService = debugService; _updateService = updateService; - _assetLoader = assetLoader; _defaultTitleBarViewModel = defaultTitleBarViewModel; _sidebarVmFactory = sidebarVmFactory; _lifeTime = (IClassicDesktopStyleApplicationLifetime) Application.Current!.ApplicationLifetime!; diff --git a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml index a407de94a..d0d5aed6e 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/AboutTabView.axaml @@ -11,7 +11,7 @@ - + Artemis 2 @@ -52,9 +52,10 @@ Height="75" Width="75" Margin="0 0 15 0" - IsVisible="{CompiledBinding RobertProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> + IsVisible="{CompiledBinding RobertProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" + RenderOptions.BitmapInterpolationMode="HighQuality"> - + @@ -80,9 +81,10 @@ Height="75" Width="75" Margin="0 0 15 0" - IsVisible="{CompiledBinding DarthAffeProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> + IsVisible="{CompiledBinding DarthAffeProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" + RenderOptions.BitmapInterpolationMode="HighQuality"> - + @@ -108,9 +110,10 @@ Height="75" Width="75" Margin="0 0 15 0" - IsVisible="{CompiledBinding DrMeteorProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> + IsVisible="{CompiledBinding DrMeteorProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" + RenderOptions.BitmapInterpolationMode="HighQuality"> - + @@ -136,9 +139,10 @@ Height="75" Width="75" Margin="0 0 15 0" - IsVisible="{CompiledBinding KaiProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> + IsVisible="{CompiledBinding KaiProfileImage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" + RenderOptions.BitmapInterpolationMode="HighQuality"> - + diff --git a/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditView.axaml b/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditView.axaml index 4f714ae75..3aad0ce29 100644 --- a/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditView.axaml +++ b/src/Artemis.UI/Screens/Sidebar/Dialogs/ProfileConfigurationEditView.axaml @@ -79,9 +79,13 @@ - + - + @@ -127,8 +131,9 @@ - Fade when enabling and disabling - + + Fade when enabling and disabling + diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeMenuItemViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeMenuItemViewModel.cs index 8ca0c9a41..c8f346714 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeMenuItemViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeMenuItemViewModel.cs @@ -18,11 +18,13 @@ public class NodeMenuItemViewModel public NodeMenuItemViewModel(ReactiveCommand createNode, NodeData nodeData) { Header = nodeData.Name; + Subtitle = nodeData.Description; Items = new List(); CreateNode = ReactiveCommand.Create(() => { createNode.Execute(nodeData).Subscribe(); }); } public string Header { get; } + public string? Subtitle { get; } public List Items { get; } public ReactiveCommand? CreateNode { get; } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowView.axaml b/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowView.axaml index 94f643cd5..491fcfb1e 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowView.axaml +++ b/src/Artemis.UI/Screens/VisualScripting/NodeScriptWindowView.axaml @@ -1,20 +1,20 @@ + 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:visualScripting="clr-namespace:Artemis.UI.Screens.VisualScripting" + xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" + xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" + xmlns:core="clr-namespace:Artemis.Core;assembly=Artemis.Core" + xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia" + xmlns:system="clr-namespace:System;assembly=System.Runtime" + mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:Class="Artemis.UI.Screens.VisualScripting.NodeScriptWindowView" + x:DataType="visualScripting:NodeScriptWindowViewModel" + Icon="/Assets/Images/Logo/application.ico" + Title="Artemis | Visual Script Editor" + Width="1200" + Height="800"> @@ -30,10 +30,21 @@ + + + + + + + + + diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index e4b45b4b7..2a69a2d53 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -8,10 +8,10 @@ - - - - + + + + diff --git a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj index 3492a7f04..c31da3c25 100644 --- a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj +++ b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/src/NuGet.config b/src/NuGet.config deleted file mode 100644 index 2a6054bcd..000000000 --- a/src/NuGet.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file From f04d7cf8972406eefe29ad2088d04fd8e8d1c1a1 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 11 May 2023 23:33:36 +0200 Subject: [PATCH 12/14] BitmapInterpolationMode fixes --- .../Controls/DeviceVisualizer.cs | 4 +- .../Controls/DeviceVisualizerLed.cs | 6 +-- .../Screens/Device/DeviceSettingsView.axaml | 37 ++++++++++--------- src/Artemis.UI/Screens/Root/SplashView.axaml | 2 +- .../SurfaceEditor/SurfaceDeviceView.axaml | 2 +- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index 8541d98a6..3d8a3192e 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -41,7 +41,6 @@ public class DeviceVisualizer : Control PropertyChanged += OnPropertyChanged; } - /// public override void Render(DrawingContext drawingContext) { @@ -305,8 +304,9 @@ public class DeviceVisualizer : Control using DrawingContext context = renderTargetBitmap.CreateDrawingContext(); using Bitmap bitmap = new(device.Layout.Image.LocalPath); + using Bitmap scaledBitmap = bitmap.CreateScaledBitmap(renderTargetBitmap.PixelSize); - context.DrawImage(bitmap, new Rect(bitmap.Size), new Rect(renderTargetBitmap.Size)); + context.DrawImage(scaledBitmap, new Rect(scaledBitmap.Size)); lock (_deviceVisualizerLeds) { foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds) diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs index 29e219fb9..6c69cc674 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizerLed.cs @@ -46,10 +46,10 @@ internal class DeviceVisualizerLed try { using Bitmap bitmap = new(Led.Layout.Image.LocalPath); + using Bitmap scaledBitmap = bitmap.CreateScaledBitmap(new PixelSize((Led.RgbLed.Size.Width * scale).RoundToInt(), (Led.RgbLed.Size.Height * scale).RoundToInt())); drawingContext.DrawImage( - bitmap, - new Rect(bitmap.Size), - new Rect(Led.RgbLed.Location.X * scale, Led.RgbLed.Location.Y * scale, Led.RgbLed.Size.Width * scale, Led.RgbLed.Size.Height * scale) + scaledBitmap, + new Rect(Led.RgbLed.Location.X * scale, Led.RgbLed.Location.Y * scale, scaledBitmap.Size.Width, scaledBitmap.Size.Height) ); } catch diff --git a/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml b/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml index 6c6330055..080b36def 100644 --- a/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml +++ b/src/Artemis.UI/Screens/Device/DeviceSettingsView.axaml @@ -11,13 +11,14 @@ x:Class="Artemis.UI.Screens.Device.DeviceSettingsView"> - - + + RenderOptions.BitmapInterpolationMode="HighQuality" />