diff --git a/Artemis/Artemis/App.xaml.cs b/Artemis/Artemis/App.xaml.cs index 3745a9ffa..609a451b9 100644 --- a/Artemis/Artemis/App.xaml.cs +++ b/Artemis/Artemis/App.xaml.cs @@ -28,7 +28,7 @@ namespace Artemis private void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { // Get rid of the keyboard hook in case of a crash, otherwise input freezes up system wide until Artemis is gone - KeyboardHook.Dispose(); + KeyboardHook.Stop(); if (DoHandle) { diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs index bcf6715ad..6cfb075d6 100644 --- a/Artemis/Artemis/ArtemisBootstrapper.cs +++ b/Artemis/Artemis/ArtemisBootstrapper.cs @@ -35,7 +35,7 @@ namespace Artemis Initialize(); BindSpecialValues(); - KeyboardHook.SetupKeyboardHook(); + KeyboardHook.Start(); AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; } @@ -43,7 +43,7 @@ namespace Artemis private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs) { // Get rid of the keyboard hook in case of a crash, otherwise input freezes up system wide until Artemis is gone - KeyboardHook.Dispose(); + KeyboardHook.Stop(); } private void BindSpecialValues() diff --git a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs index 46ad9388a..21c0cf413 100644 --- a/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs +++ b/Artemis/Artemis/DeviceProviders/Corsair/CorsairKeyboard.cs @@ -55,7 +55,7 @@ namespace Artemis.DeviceProviders.Corsair Height = 7; Width = 25; Slug = "corsair-k95-rgb"; - PreviewSettings = new PreviewSettings(new Thickness(0, -15, 0, 0), Resources.k95); + PreviewSettings = new PreviewSettings(new Thickness(12, -12, 12, 5), Resources.k95); break; case "K70 RGB": case "K70 RGB RAPIDFIRE": @@ -63,7 +63,7 @@ namespace Artemis.DeviceProviders.Corsair Height = 7; Width = 21; Slug = "corsair-k70-rgb"; - PreviewSettings = new PreviewSettings(new Thickness(0, -25, 0, 0), Resources.k70); + PreviewSettings = new PreviewSettings(new Thickness(12, -12, 12, 5), Resources.k70); break; case "K65 RGB": case "CGK65 RGB": @@ -72,13 +72,13 @@ namespace Artemis.DeviceProviders.Corsair Height = 7; Width = 18; Slug = "corsair-k65-rgb"; - PreviewSettings = new PreviewSettings(new Thickness(0, -30, 0, 0), Resources.k65); + PreviewSettings = new PreviewSettings(new Thickness(12, -12, 12, 5), Resources.k65); break; case "STRAFE RGB": Height = 7; Width = 22; Slug = "corsair-strafe-rgb"; - PreviewSettings = new PreviewSettings(new Thickness(0, -5, 0, 0), Resources.strafe); + PreviewSettings = new PreviewSettings(new Thickness(12, -12, 12, 5), Resources.strafe); break; } diff --git a/Artemis/Artemis/DeviceProviders/Logitech/G910.cs b/Artemis/Artemis/DeviceProviders/Logitech/G910.cs index fd7a69620..5e90e32f5 100644 --- a/Artemis/Artemis/DeviceProviders/Logitech/G910.cs +++ b/Artemis/Artemis/DeviceProviders/Logitech/G910.cs @@ -24,7 +24,7 @@ namespace Artemis.DeviceProviders.Logitech "If needed, you can select a different keyboard in Artemis under settings."; Height = 7; Width = 22; - PreviewSettings = new PreviewSettings(new Thickness(10, -70, 10, 50), Resources.g910); + PreviewSettings = new PreviewSettings(new Thickness(20, -55, 20, 65), Resources.g910); _generalSettings = SettingsProvider.Load(); } diff --git a/Artemis/Artemis/Managers/PreviewManager.cs b/Artemis/Artemis/Managers/PreviewManager.cs index c7a52dfdc..612f2e120 100644 --- a/Artemis/Artemis/Managers/PreviewManager.cs +++ b/Artemis/Artemis/Managers/PreviewManager.cs @@ -47,10 +47,9 @@ namespace Artemis.Managers if (string.IsNullOrEmpty(_generalSettings.LastKeyboard) || _deviceManager.ChangingKeyboard) return; - // If Artemis doesn't have focus, don't preview - var activePreview = PreviewViewModules.FirstOrDefault( - vm => vm.IsActive && vm.UsesProfileEditor && vm.ModuleModel.Settings.IsEnabled); - if (activePreview != null && ActiveWindowHelper.MainWindowActive) + // If Artemis doesn't have focus, don't preview unless overwritten by KeepActive + var activePreview = PreviewViewModules.FirstOrDefault(vm => (vm.IsActive || vm.ProfileEditor.KeepActive) && vm.UsesProfileEditor && vm.ModuleModel.Settings.IsEnabled); + if (activePreview != null && (activePreview.ProfileEditor.KeepActive || ActiveWindowHelper.MainWindowActive)) EnsurePreviewActive(activePreview); else EnsurePreviewInactive(); diff --git a/Artemis/Artemis/Modules/Abstract/ModuleViewModel.cs b/Artemis/Artemis/Modules/Abstract/ModuleViewModel.cs index 7176fbbaf..c439076ef 100644 --- a/Artemis/Artemis/Modules/Abstract/ModuleViewModel.cs +++ b/Artemis/Artemis/Modules/Abstract/ModuleViewModel.cs @@ -13,9 +13,9 @@ namespace Artemis.Modules.Abstract { public abstract class ModuleViewModel : Screen { + private readonly GeneralSettings _generalSettings; private readonly MainManager _mainManager; private readonly ModuleManager _moduleManager; - private readonly GeneralSettings _generalSettings; private ModuleSettings _settings; public ModuleViewModel(MainManager mainManager, ModuleModel moduleModel, IKernel kernel) @@ -56,7 +56,8 @@ namespace Artemis.Modules.Abstract get { return _settings; } set { - if (Equals(value, _settings)) return; + if (Equals(value, _settings)) + return; _settings = value; NotifyOfPropertyChange(() => Settings); } @@ -74,6 +75,9 @@ namespace Artemis.Modules.Abstract } } + /// + /// Indicates whether or not this module uses the profile editor + /// public abstract bool UsesProfileEditor { get; } private void MainManagerOnEnabledChanged(object sender, EnabledChangedEventArgs e) @@ -91,7 +95,7 @@ namespace Artemis.Modules.Abstract private void UpdatedEnabledSetting() { - if (!ModuleModel.IsGeneral || (_moduleManager.ActiveModule != null && !_moduleManager.ActiveModule.IsGeneral || Settings.IsEnabled == IsModuleActive)) + if (!ModuleModel.IsGeneral || _moduleManager.ActiveModule != null && !_moduleManager.ActiveModule.IsGeneral || Settings.IsEnabled == IsModuleActive) return; Settings.IsEnabled = IsModuleActive; @@ -161,4 +165,4 @@ namespace Artemis.Modules.Abstract ProfileEditor?.OnDeactivate(close); } } -} \ No newline at end of file +} diff --git a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs b/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs index 15c19d520..84ba6f6e0 100644 --- a/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs +++ b/Artemis/Artemis/Utilities/Keyboard/KeyboardHook.cs @@ -12,7 +12,7 @@ namespace Artemis.Utilities.Keyboard private static IKeyboardMouseEvents _globalHook; - public static void SetupKeyboardHook() + public static void Start() { _globalHook = Hook.GlobalEvents(); _globalHook.KeyDown += GlobalHookOnKeyDown; @@ -21,6 +21,19 @@ namespace Artemis.Utilities.Keyboard _globalHook.MouseUp += GlobalHookOnMouseUp; } + public static void Stop() + { + if (_globalHook == null) + return; + + _globalHook.KeyDown -= GlobalHookOnKeyDown; + _globalHook.KeyUp -= GlobalHookOnKeyUp; + _globalHook.MouseDown -= GlobalHookOnMouseDown; + _globalHook.MouseUp -= GlobalHookOnMouseUp; + _globalHook.Dispose(); + _globalHook = null; + } + private static async void GlobalHookOnMouseDown(object sender, MouseEventArgs e) { await Task.Factory.StartNew(() => { MouseDownCallback?.Invoke(e); }); @@ -45,18 +58,5 @@ namespace Artemis.Utilities.Keyboard public static event KeyCallbackHandler KeyUpCallback; public static event MouseCallbackHandler MouseDownCallback; public static event MouseCallbackHandler MouseUpCallback; - - public static void Dispose() - { - if (_globalHook == null) - return; - - _globalHook.KeyDown -= GlobalHookOnKeyDown; - _globalHook.KeyUp -= GlobalHookOnKeyUp; - _globalHook.MouseDown -= GlobalHookOnMouseDown; - _globalHook.MouseUp -= GlobalHookOnMouseUp; - _globalHook.Dispose(); - _globalHook = null; - } } } diff --git a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs index e02ea069b..51cb959bd 100644 --- a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs @@ -47,12 +47,12 @@ namespace Artemis.ViewModels { private readonly DeviceManager _deviceManager; private readonly MetroDialogService _dialogService; - private KeybindModel _copyKeybind; - private KeybindModel _pasteKeybind; private readonly LoopManager _loopManager; private readonly ModuleModel _moduleModel; + private readonly KeybindModel _copyKeybind; private ImageSource _keyboardPreview; private ObservableCollection _layers; + private readonly KeybindModel _pasteKeybind; private ObservableCollection _profileNames; private bool _saving; private LayerModel _selectedLayer; @@ -198,19 +198,19 @@ namespace Artemis.ViewModels } } - public ImageSource KeyboardImage => ImageUtilities.BitmapToBitmapImage( - _deviceManager.ActiveKeyboard?.PreviewSettings.Image ?? Resources.none); - + public ImageSource KeyboardImage => ImageUtilities.BitmapToBitmapImage(_deviceManager.ActiveKeyboard?.PreviewSettings.Image ?? Resources.none); public ProfileModel SelectedProfile => _moduleModel?.ProfileModel; public PreviewSettings? PreviewSettings => _deviceManager.ActiveKeyboard?.PreviewSettings; public bool ProfileSelected => SelectedProfile != null; public bool LayerSelected => SelectedProfile != null && SelectedLayer != null; - - public bool EditorEnabled => SelectedProfile != null && !SelectedProfile.IsDefault && - _deviceManager.ActiveKeyboard != null; - + public bool EditorEnabled => SelectedProfile != null && !SelectedProfile.IsDefault && _deviceManager.ActiveKeyboard != null; public bool LuaButtonVisible => !_moduleModel.IsOverlay; + /// + /// Set to true to keep the preview active if using the profile editor + /// + public bool KeepActive { get; set; } + #endregion #region Layers @@ -228,8 +228,10 @@ namespace Artemis.ViewModels if (SelectedLayer == null) return; + KeepActive = true; ProfileEditorModel.EditLayer(SelectedLayer, _moduleModel.DataModel); UpdateLayerList(SelectedLayer); + KeepActive = false; } public void EditLayer(LayerModel layerModel) @@ -237,8 +239,10 @@ namespace Artemis.ViewModels if (layerModel == null) return; + KeepActive = true; ProfileEditorModel.EditLayer(layerModel, _moduleModel.DataModel); UpdateLayerList(layerModel); + KeepActive = false; } public LayerModel AddLayer() @@ -284,6 +288,7 @@ namespace Artemis.ViewModels if (layer == null) return; + KeepActive = true; var newName = await _dialogService.ShowInputDialog("Rename layer", "Please enter a name for the layer", new MetroDialogSettings {DefaultText = layer.Name}); @@ -293,6 +298,7 @@ namespace Artemis.ViewModels layer.Name = newName; UpdateLayerList(layer); + KeepActive = false; } /// @@ -340,7 +346,9 @@ namespace Artemis.ViewModels return; if (SelectedLayer != null) + { SelectedLayer.InsertAfter(layerModel); + } else { SelectedProfile.Layers.Add(layerModel); @@ -630,7 +638,7 @@ namespace Artemis.ViewModels if (_draggingLayer != null) return; - var pos = e.GetPosition((Image) e.OriginalSource); + var pos = GetScaledPosition(e); var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y)); if (hoverLayer != null) @@ -646,7 +654,7 @@ namespace Artemis.ViewModels if (SelectedProfile == null) return; - var pos = e.GetPosition((Image) e.OriginalSource); + var pos = GetScaledPosition(e); var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y)); HandleDragging(e, pos.X, pos.Y, hoverLayer); @@ -671,6 +679,18 @@ namespace Artemis.ViewModels } } + private Point GetScaledPosition(MouseEventArgs e) + { + var sourceImage = (Image) e.OriginalSource; + var pos = e.GetPosition(sourceImage); + + // Scale the X and Y position down to match the keyboard's physical size and thus the layer positions + pos.X = pos.X * (SelectedProfile.Width / sourceImage.ActualWidth); + pos.Y = pos.Y * (SelectedProfile.Height / sourceImage.ActualHeight); + + return pos; + } + public Cursor KeyboardPreviewCursor { get { return _keyboardPreviewCursor; } diff --git a/Artemis/Artemis/Views/ProfileEditorView.xaml b/Artemis/Artemis/Views/ProfileEditorView.xaml index 25f269a0a..223eec6ed 100644 --- a/Artemis/Artemis/Views/ProfileEditorView.xaml +++ b/Artemis/Artemis/Views/ProfileEditorView.xaml @@ -35,8 +35,9 @@ diff --git a/Artemis/Artemis/Views/ShellView.xaml b/Artemis/Artemis/Views/ShellView.xaml index c1f0ee731..bf5c27746 100644 --- a/Artemis/Artemis/Views/ShellView.xaml +++ b/Artemis/Artemis/Views/ShellView.xaml @@ -10,7 +10,7 @@ xmlns:tb="http://www.hardcodet.net/taskbar" dialogs:DialogParticipation.Register="{Binding RelativeSource={RelativeSource Self}, Path=DataContext}" mc:Ignorable="d" d:DataContext="{d:DesignInstance viewModels:ShellViewModel}" - Title="Artemis" Height="800" Width="1210" MinHeight="600" MinWidth="600" GlowBrush="{DynamicResource AccentColorBrush}" Icon="../logo.ico"> + Title="Artemis" Height="800" Width="1210" ResizeMode="NoResize" GlowBrush="{DynamicResource AccentColorBrush}" Icon="../logo.ico">