diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs index 8ade31aac7..549c89023d 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation +// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -32,6 +32,9 @@ namespace Microsoft.PowerToys.Settings.UI.Lib public bool PowerRename { get; set; } + [JsonPropertyName("Keyboard Manager")] + public bool KeyboardManager { get; set; } + public string ToJsonString() { return JsonSerializer.Serialize(this); diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeyboadManagerConfigModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeyboardManagerProfile.cs similarity index 69% rename from src/core/Microsoft.PowerToys.Settings.UI.Lib/KeyboadManagerConfigModel.cs rename to src/core/Microsoft.PowerToys.Settings.UI.Lib/KeyboardManagerProfile.cs index 0b3d6c2377..00d1ff60e9 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeyboadManagerConfigModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeyboardManagerProfile.cs @@ -7,12 +7,18 @@ using System.Text.Json.Serialization; namespace Microsoft.PowerToys.Settings.UI.Lib { - public class KeyboadManagerConfigModel + public class KeyboardManagerProfile { [JsonPropertyName("remapKeys")] public RemapKeysDataModel RemapKeys { get; set; } [JsonPropertyName("remapShortcuts")] public ShortcutsKeyDataModel RemapShortcuts { get; set; } + + public KeyboardManagerProfile() + { + RemapKeys = new RemapKeysDataModel(); + RemapShortcuts = new ShortcutsKeyDataModel(); + } } } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeysDataModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeysDataModel.cs index 2b66cbc8ab..d9140f7da8 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeysDataModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/KeysDataModel.cs @@ -2,6 +2,9 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.PowerToys.Settings.UI.Lib.Utilities; +using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; namespace Microsoft.PowerToys.Settings.UI.Lib @@ -13,5 +16,24 @@ namespace Microsoft.PowerToys.Settings.UI.Lib [JsonPropertyName("newRemapKeys")] public string NewRemapKeys { get; set; } + + private List MapKeys(string stringOfKeys) + { + return stringOfKeys + .Split(';') + .Select(uint.Parse) + .Select(Helper.GetKeyName) + .ToList(); + } + + public List GetOriginalKeys() + { + return MapKeys(OriginalKeys); + } + + public List GetNewRemapKeys() + { + return MapKeys(NewRemapKeys); + } } } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs index af376a648c..67477c4214 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs @@ -11,5 +11,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib { [JsonPropertyName("inProcess")] public List InProcessRemapKeys { get; set; } + + public RemapKeysDataModel() + { + InProcessRemapKeys = new List(); + } } } \ No newline at end of file diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsUtils.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsUtils.cs index aea23689c6..abc6c1cd9d 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsUtils.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsUtils.cs @@ -41,7 +41,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib $"Microsoft\\PowerToys\\{powertoy}\\{fileName}"); } - public static bool SettingsExists(string powertoy, string fileName = DefaultFileName) + public static bool SettingsExists(string powertoy = DefaultModuleName, string fileName = DefaultFileName) { return File.Exists(GetSettingsPath(powertoy, fileName)); } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs index 7b75a86b11..ad245f4808 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs @@ -11,5 +11,10 @@ namespace Microsoft.PowerToys.Settings.UI.Lib { [JsonPropertyName("global")] public List GlobalRemapShortcuts { get; set; } + + public ShortcutsKeyDataModel() + { + GlobalRemapShortcuts = new List(); + } } } diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo.png b/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo.png new file mode 100644 index 0000000000..8495aaf09d Binary files /dev/null and b/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo.png differ diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo150.png b/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo150.png new file mode 100644 index 0000000000..3186a72996 Binary files /dev/null and b/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo150.png differ diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo44.png b/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo44.png new file mode 100644 index 0000000000..cbc9822292 Binary files /dev/null and b/src/core/Microsoft.PowerToys.Settings.UI/Assets/logo44.png differ diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj b/src/core/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj index 187430c591..6ce134a25e 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj +++ b/src/core/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj @@ -71,11 +71,9 @@ - - @@ -105,6 +103,7 @@ ShortcutGuidePage.xaml + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/KeyboardManagerViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/KeyboardManagerViewModel.cs index b27689b62c..7604231ab2 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/KeyboardManagerViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/KeyboardManagerViewModel.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Input; @@ -11,6 +13,9 @@ using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Lib; using Microsoft.PowerToys.Settings.UI.Lib.Utilities; using Microsoft.PowerToys.Settings.UI.Views; +using Microsoft.Toolkit.Uwp.Helpers; +using Windows.UI.Core; +using Windows.UI.Xaml; namespace Microsoft.PowerToys.Settings.UI.ViewModels { @@ -22,24 +27,31 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private const string EditShortcutActionName = "EditShortcut"; private const string EditShortcutActionValue = "Open Edit Shortcut Window"; private const string JsonFileType = ".json"; - private const string ConfigFileMutexName = "PowerToys.KeyboardManager.ConfigMutex"; - private const int ConfigFileMutexWaitTimeoutMiliSeconds = 1000; + private const string ProfileFileMutexName = "PowerToys.KeyboardManager.ConfigMutex"; + private const int ProfileFileMutexWaitTimeoutMilliseconds = 1000; + + private readonly CoreDispatcher dispatcher; + private readonly FileSystemWatcher watcher; private ICommand remapKeyboardCommand; private ICommand editShortcutCommand; - private FileSystemWatcher watcher; private KeyboardManagerSettings settings; - - public ICommand RemapKeyboardCommand => remapKeyboardCommand ?? (remapKeyboardCommand = new RelayCommand(OnRemapKeyboard)); - - public ICommand EditShortcutCommand => editShortcutCommand ?? (editShortcutCommand = new RelayCommand(OnEditShortcut)); + private KeyboardManagerProfile profile; + private GeneralSettings generalSettings; public KeyboardManagerViewModel() { + dispatcher = Window.Current.Dispatcher; if (SettingsUtils.SettingsExists(PowerToyName)) { // Todo: Be more resillent while reading and saving settings. settings = SettingsUtils.GetSettings(PowerToyName); + + // Load profile. + if (!LoadProfile()) + { + profile = new KeyboardManagerProfile(); + } } else { @@ -47,9 +59,78 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels SettingsUtils.SaveSettings(settings.ToJsonString(), PowerToyName); } - watcher = Helper.GetFileWatcher(PowerToyName, settings.Properties.ActiveConfiguration.Value + JsonFileType, OnConfigFileUpdate); + if (SettingsUtils.SettingsExists()) + { + generalSettings = SettingsUtils.GetSettings(string.Empty); + } + else + { + generalSettings = new GeneralSettings(); + SettingsUtils.SaveSettings(generalSettings.ToJsonString(), string.Empty); + } + + watcher = Helper.GetFileWatcher( + PowerToyName, + settings.Properties.ActiveConfiguration.Value + JsonFileType, + OnConfigFileUpdate); + } + public bool Enabled + { + get + { + return generalSettings.Enabled.KeyboardManager; + } + + set + { + if (generalSettings.Enabled.KeyboardManager != value) + { + generalSettings.Enabled.KeyboardManager = value; + OnPropertyChanged(nameof(Enabled)); + OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(generalSettings); + + ShellPage.DefaultSndMSGCallback(outgoing.ToString()); + } + } + } + + // store remappings + public List RemapKeys + { + get + { + if (profile != null) + { + return profile.RemapKeys.InProcessRemapKeys; + } + else + { + return new List(); + } + } + } + + public List RemapShortcuts + { + get + { + if (profile != null) + { + return profile.RemapShortcuts.GlobalRemapShortcuts; + } + else + { + return new List(); + } + } + } + + public ICommand RemapKeyboardCommand => remapKeyboardCommand ?? (remapKeyboardCommand = new RelayCommand(OnRemapKeyboard)); + + public ICommand EditShortcutCommand => editShortcutCommand ?? (editShortcutCommand = new RelayCommand(OnEditShortcut)); + private async void OnRemapKeyboard() { await Task.Run(() => OnRemapKeyboardBackground()); @@ -74,38 +155,54 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels await Task.CompletedTask; } - private void OnConfigFileUpdate() + private async void OnConfigFileUpdate() { // Note: FileSystemWatcher raise notification mutiple times for single update operation. // Todo: Handle duplicate events either by somehow supress them or re-read the configuration everytime since we will be updating the UI only if something is changed. - GetKeyboardManagerConfigFile(); + if (LoadProfile()) + { + await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + OnPropertyChanged(nameof(RemapKeys)); + OnPropertyChanged(nameof(RemapShortcuts)); + }); + } } - private void GetKeyboardManagerConfigFile() + private bool LoadProfile() { + var success = true; + try { - using (var configFileMutex = Mutex.OpenExisting(ConfigFileMutexName)) + using (var profileFileMutex = Mutex.OpenExisting(ProfileFileMutexName)) { - if (configFileMutex.WaitOne(ConfigFileMutexWaitTimeoutMiliSeconds)) + if (profileFileMutex.WaitOne(ProfileFileMutexWaitTimeoutMilliseconds)) { // update the UI element here. try { - var config = SettingsUtils.GetSettings(PowerToyName, settings.Properties.ActiveConfiguration.Value + JsonFileType); + profile = SettingsUtils.GetSettings(PowerToyName, settings.Properties.ActiveConfiguration.Value + JsonFileType); } finally { // Make sure to release the mutex. - configFileMutex.ReleaseMutex(); + profileFileMutex.ReleaseMutex(); } } + else + { + success = false; + } } } catch (Exception) { // Failed to load the configuration. + success = false; } + + return success; } } } diff --git a/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/Keys.cs b/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/Keys.cs deleted file mode 100644 index 34610dfd47..0000000000 --- a/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/Keys.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.PowerToys.Settings.UI.ViewModels -{ - public class Keys - { - public string From { get; set; } - - public string To { get; set; } - } -} diff --git a/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/RemapKeysModel.cs b/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/RemapKeysModel.cs deleted file mode 100644 index 7c64ca91c9..0000000000 --- a/src/core/Microsoft.PowerToys.Settings.UI/ViewModels/RemapKeysModel.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.ObjectModel; - -namespace Microsoft.PowerToys.Settings.UI.ViewModels -{ - // Dummy data model for the UI. Will be removed moving forward. - public class RemapKeysModel : ObservableCollection - { - public RemapKeysModel() - { - Add(new Keys { From = "A", To = "B" }); - Add(new Keys { From = "B", To = "A" }); - Add(new Keys { From = "Ctrl", To = "Shift" }); - Add(new Keys { From = "Shift", To = "Ctrl" }); - Add(new Keys { From = "A", To = "B" }); - Add(new Keys { From = "B", To = "B" }); - Add(new Keys { From = "Ctrl", To = "Shift" }); - Add(new Keys { From = "Shift", To = "Ctrl" }); - } - } -} diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Views/KeyboardManagerPage.xaml b/src/core/Microsoft.PowerToys.Settings.UI/Views/KeyboardManagerPage.xaml index e5d085d625..b1efe75cff 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Views/KeyboardManagerPage.xaml +++ b/src/core/Microsoft.PowerToys.Settings.UI/Views/KeyboardManagerPage.xaml @@ -7,58 +7,79 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewModel="using:Microsoft.PowerToys.Settings.UI.ViewModels" xmlns:extensions="using:Microsoft.Toolkit.Uwp.UI.Extensions" + xmlns:Lib="using:Microsoft.PowerToys.Settings.UI.Lib" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - + VerticalAlignment="Center" + Margin="5,0,5,0"/> + + + + + + + + + + + + + + + @@ -99,7 +120,7 @@ TextWrapping="Wrap"/> \ No newline at end of file