From ce058f1dc7966e702681580a96b57859f5c9886d Mon Sep 17 00:00:00 2001 From: PesBandi <127593627+PesBandi@users.noreply.github.com> Date: Fri, 13 Jun 2025 12:01:40 +0200 Subject: [PATCH] [ColorPicker]Add option to choose what clicking individual mouse buttons does (#39025) ## Summary of the Pull Request Enables the users to choose what left, right, and middle click does when color picker is open. ## PR Checklist - [x] **Closes:** #39006 - [x] **Communication:** I've discussed this with core contributors already - [x] **Tests:** All pass - [x] **Localization:** All end user facing strings can be localized - [x] **Dev docs:** No need - [x] **New binaries:** None - [x] **Documentation updated:** No need ## Detailed Description of the Pull Request / Additional comments ![Screenshot of the settings](https://github.com/user-attachments/assets/a3e1349b-6bb9-4e2f-97f3-a5106a7d92ce) Adds option to choose from 3 click behaviors for each standard mouse button: * **Pick color and open editor**: Copies color to clipboard, saves it to the color history and opens the editor * **Pick color and close**: Copies color to clipboard, saves it to the color history and exits * **Close**: Closes color picker without copying the color Pressing Enter or Space does what clicking the primary button would. Left and middle click actions execute on mouse down, right click on mouse up for reasons discussed previously (I can't find the conversation now) Default settings are chosen in such a way that very little or nothing changes by updating. ## Validation Steps Performed Tested: * Migrating settings from v2.0 to v2.1 (v1 to v2.1 not tested) * Settings page displays and saves settings correctly * Default settings load correctly * All three click actions do what they are supposed to * Activation behavior works as expected, doesn't affect click actions --- .github/actions/spell-check/expect.txt | 3 + .../ColorPickerUI/Helpers/AppStateHandler.cs | 17 ++--- .../ColorPickerUI/Mouse/IMouseInfoProvider.cs | 4 +- .../ColorPickerUI/Mouse/MouseHook.cs | 46 +++++++++++--- .../ColorPickerUI/Mouse/MouseInfoProvider.cs | 20 ++++-- .../ColorPickerUI/Settings/IUserSettings.cs | 6 ++ .../ColorPickerUI/Settings/UserSettings.cs | 14 ++++- .../ColorPickerUI/ViewModels/MainViewModel.cs | 63 +++++++++++++------ .../ColorPickerProperties.cs | 14 ++++- .../ColorPickerPropertiesVersion1.cs | 2 +- .../ColorPickerSettings.cs | 19 +++++- .../ColorPickerActivationAction.cs | 7 +-- .../Enumerations/ColorPickerClickAction.cs | 18 ++++++ .../Settings.UI.Library/SettingsUtils.cs | 7 +++ .../SettingsXAML/Views/ColorPickerPage.xaml | 33 +++++++++- .../Settings.UI/Strings/en-us/Resources.resw | 39 +++++++++--- .../ViewModels/ColorPickerViewModel.cs | 45 +++++++++++++ 17 files changed, 291 insertions(+), 66 deletions(-) create mode 100644 src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerClickAction.cs diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 6e3f041fba..1dcfdef0e1 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -910,6 +910,7 @@ metafile mfc Mgmt Microwaved +middleclickaction midl mii mindaro @@ -1251,6 +1252,7 @@ prg prgh prgms pri +primaryclickaction PRINTCLIENT printmanagement prm @@ -1426,6 +1428,7 @@ SDKDDK sdns searchterm SEARCHUI +secondaryclickaction SECONDARYDISPLAY secpol securestring diff --git a/src/modules/colorPicker/ColorPickerUI/Helpers/AppStateHandler.cs b/src/modules/colorPicker/ColorPickerUI/Helpers/AppStateHandler.cs index b3350702c7..705324cb93 100644 --- a/src/modules/colorPicker/ColorPickerUI/Helpers/AppStateHandler.cs +++ b/src/modules/colorPicker/ColorPickerUI/Helpers/AppStateHandler.cs @@ -107,21 +107,14 @@ namespace ColorPicker.Helpers } } - public void OnColorPickerMouseDown() + public void OpenColorEditor() { - if (_userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenColorPickerAndThenEditor || _userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenEditor) + lock (_colorPickerVisibilityLock) { - lock (_colorPickerVisibilityLock) - { - HideColorPicker(); - } + HideColorPicker(); + } - ShowColorPickerEditor(); - } - else - { - EndUserSession(); - } + ShowColorPickerEditor(); } public static void SetTopMost() diff --git a/src/modules/colorPicker/ColorPickerUI/Mouse/IMouseInfoProvider.cs b/src/modules/colorPicker/ColorPickerUI/Mouse/IMouseInfoProvider.cs index 3361b95cb4..51bb35ac51 100644 --- a/src/modules/colorPicker/ColorPickerUI/Mouse/IMouseInfoProvider.cs +++ b/src/modules/colorPicker/ColorPickerUI/Mouse/IMouseInfoProvider.cs @@ -16,10 +16,12 @@ namespace ColorPicker.Mouse // position and bool indicating zoom in or zoom out event EventHandler> OnMouseWheel; - event MouseUpEventHandler OnMouseDown; + event PrimaryMouseDownEventHandler OnPrimaryMouseDown; event SecondaryMouseUpEventHandler OnSecondaryMouseUp; + event MiddleMouseDownEventHandler OnMiddleMouseDown; + System.Windows.Point CurrentPosition { get; } Color CurrentColor { get; } diff --git a/src/modules/colorPicker/ColorPickerUI/Mouse/MouseHook.cs b/src/modules/colorPicker/ColorPickerUI/Mouse/MouseHook.cs index 8476398c99..72fffd1445 100644 --- a/src/modules/colorPicker/ColorPickerUI/Mouse/MouseHook.cs +++ b/src/modules/colorPicker/ColorPickerUI/Mouse/MouseHook.cs @@ -7,17 +7,18 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Input; -using ColorPicker.Helpers; using ManagedCommon; using static ColorPicker.NativeMethods; namespace ColorPicker.Mouse { - public delegate void MouseUpEventHandler(object sender, System.Drawing.Point p); + public delegate void PrimaryMouseDownEventHandler(object sender, IntPtr wParam); public delegate void SecondaryMouseUpEventHandler(object sender, IntPtr wParam); + public delegate void MiddleMouseDownEventHandler(object sender, IntPtr wParam); + internal class MouseHook { [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop object")] @@ -30,23 +31,25 @@ namespace ColorPicker.Mouse private const int WM_RBUTTONUP = 0x0205; [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop object")] private const int WM_RBUTTONDOWN = 0x0204; + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop object")] + private const int WM_MBUTTONDOWN = 0x0207; private IntPtr _mouseHookHandle; private HookProc _mouseDelegate; - private event MouseUpEventHandler MouseDown; + private event PrimaryMouseDownEventHandler PrimaryMouseDown; - public event MouseUpEventHandler OnMouseDown + public event PrimaryMouseDownEventHandler OnPrimaryMouseDown { add { Subscribe(); - MouseDown += value; + PrimaryMouseDown += value; } remove { - MouseDown -= value; + PrimaryMouseDown -= value; Unsubscribe(); } } @@ -68,6 +71,23 @@ namespace ColorPicker.Mouse } } + private event MiddleMouseDownEventHandler MiddleMouseDown; + + public event MiddleMouseDownEventHandler OnMiddleMouseDown + { + add + { + Subscribe(); + MiddleMouseDown += value; + } + + remove + { + MiddleMouseDown -= value; + Unsubscribe(); + } + } + private event MouseWheelEventHandler MouseWheel; public event MouseWheelEventHandler OnMouseWheel @@ -126,9 +146,9 @@ namespace ColorPicker.Mouse MSLLHOOKSTRUCT mouseHookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)); if (wParam.ToInt32() == WM_LBUTTONDOWN) { - if (MouseDown != null) + if (PrimaryMouseDown != null) { - MouseDown.Invoke(null, new System.Drawing.Point(mouseHookStruct.pt.x, mouseHookStruct.pt.y)); + PrimaryMouseDown.Invoke(null, wParam); } return new IntPtr(-1); @@ -150,6 +170,16 @@ namespace ColorPicker.Mouse return new IntPtr(-1); } + if (wParam.ToInt32() == WM_MBUTTONDOWN) + { + if (MiddleMouseDown != null) + { + MiddleMouseDown.Invoke(null, wParam); + } + + return new IntPtr(-1); + } + if (wParam.ToInt32() == WM_MOUSEWHEEL) { if (MouseWheel != null) diff --git a/src/modules/colorPicker/ColorPickerUI/Mouse/MouseInfoProvider.cs b/src/modules/colorPicker/ColorPickerUI/Mouse/MouseInfoProvider.cs index c28dcc1ae6..4d6596bc3f 100644 --- a/src/modules/colorPicker/ColorPickerUI/Mouse/MouseInfoProvider.cs +++ b/src/modules/colorPicker/ColorPickerUI/Mouse/MouseInfoProvider.cs @@ -56,10 +56,12 @@ namespace ColorPicker.Mouse public event EventHandler> OnMouseWheel; - public event MouseUpEventHandler OnMouseDown; + public event PrimaryMouseDownEventHandler OnPrimaryMouseDown; public event SecondaryMouseUpEventHandler OnSecondaryMouseUp; + public event MiddleMouseDownEventHandler OnMiddleMouseDown; + public System.Windows.Point CurrentPosition { get @@ -148,9 +150,10 @@ namespace ColorPicker.Mouse _timer.Start(); } - _mouseHook.OnMouseDown += MouseHook_OnMouseDown; + _mouseHook.OnPrimaryMouseDown += MouseHook_OnPrimaryMouseDown; _mouseHook.OnMouseWheel += MouseHook_OnMouseWheel; _mouseHook.OnSecondaryMouseUp += MouseHook_OnSecondaryMouseUp; + _mouseHook.OnMiddleMouseDown += MouseHook_OnMiddleMouseDown; if (_userSettings.ChangeCursor.Value) { @@ -169,10 +172,10 @@ namespace ColorPicker.Mouse OnMouseWheel?.Invoke(this, new Tuple(_previousMousePosition, zoomIn)); } - private void MouseHook_OnMouseDown(object sender, Point p) + private void MouseHook_OnPrimaryMouseDown(object sender, IntPtr wParam) { DisposeHook(); - OnMouseDown?.Invoke(this, p); + OnPrimaryMouseDown?.Invoke(this, wParam); } private void MouseHook_OnSecondaryMouseUp(object sender, IntPtr wParam) @@ -181,6 +184,12 @@ namespace ColorPicker.Mouse OnSecondaryMouseUp?.Invoke(this, wParam); } + private void MouseHook_OnMiddleMouseDown(object sender, IntPtr wParam) + { + DisposeHook(); + OnMiddleMouseDown?.Invoke(this, wParam); + } + private void CopiedColorRepresentation_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { _colorFormatChanged = true; @@ -194,9 +203,10 @@ namespace ColorPicker.Mouse } _previousMousePosition = new System.Windows.Point(-1, 1); - _mouseHook.OnMouseDown -= MouseHook_OnMouseDown; + _mouseHook.OnPrimaryMouseDown -= MouseHook_OnPrimaryMouseDown; _mouseHook.OnMouseWheel -= MouseHook_OnMouseWheel; _mouseHook.OnSecondaryMouseUp -= MouseHook_OnSecondaryMouseUp; + _mouseHook.OnMiddleMouseDown -= MouseHook_OnMiddleMouseDown; if (_userSettings.ChangeCursor.Value) { diff --git a/src/modules/colorPicker/ColorPickerUI/Settings/IUserSettings.cs b/src/modules/colorPicker/ColorPickerUI/Settings/IUserSettings.cs index ab92e64081..170b58c944 100644 --- a/src/modules/colorPicker/ColorPickerUI/Settings/IUserSettings.cs +++ b/src/modules/colorPicker/ColorPickerUI/Settings/IUserSettings.cs @@ -21,6 +21,12 @@ namespace ColorPicker.Settings SettingItem ActivationAction { get; } + SettingItem PrimaryClickAction { get; } + + SettingItem MiddleClickAction { get; } + + SettingItem SecondaryClickAction { get; } + RangeObservableCollection ColorHistory { get; } SettingItem ColorHistoryLimit { get; } diff --git a/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs b/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs index eb6a9db7aa..e15a792259 100644 --- a/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs +++ b/src/modules/colorPicker/ColorPickerUI/Settings/UserSettings.cs @@ -49,7 +49,10 @@ namespace ColorPicker.Settings ChangeCursor = new SettingItem(true); ActivationShortcut = new SettingItem(DefaultActivationShortcut); CopiedColorRepresentation = new SettingItem(ColorRepresentationType.HEX.ToString()); - ActivationAction = new SettingItem(ColorPickerActivationAction.OpenEditor); + ActivationAction = new SettingItem(ColorPickerActivationAction.OpenColorPicker); + PrimaryClickAction = new SettingItem(ColorPickerClickAction.PickColorThenEditor); + MiddleClickAction = new SettingItem(ColorPickerClickAction.PickColorAndClose); + SecondaryClickAction = new SettingItem(ColorPickerClickAction.Close); ColorHistoryLimit = new SettingItem(20); ColorHistory.CollectionChanged += ColorHistory_CollectionChanged; ShowColorName = new SettingItem(false); @@ -78,6 +81,12 @@ namespace ColorPicker.Settings public SettingItem ActivationAction { get; private set; } + public SettingItem PrimaryClickAction { get; private set; } + + public SettingItem MiddleClickAction { get; private set; } + + public SettingItem SecondaryClickAction { get; private set; } + public RangeObservableCollection ColorHistory { get; private set; } = new RangeObservableCollection(); public SettingItem ColorHistoryLimit { get; } @@ -121,6 +130,9 @@ namespace ColorPicker.Settings CopiedColorRepresentation.Value = settings.Properties.CopiedColorRepresentation; CopiedColorRepresentationFormat = new SettingItem(string.Empty); ActivationAction.Value = settings.Properties.ActivationAction; + PrimaryClickAction.Value = settings.Properties.PrimaryClickAction; + MiddleClickAction.Value = settings.Properties.MiddleClickAction; + SecondaryClickAction.Value = settings.Properties.SecondaryClickAction; ColorHistoryLimit.Value = settings.Properties.ColorHistoryLimit; ShowColorName.Value = settings.Properties.ShowColorName; diff --git a/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs b/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs index 518f253456..e4d0a54b44 100644 --- a/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs +++ b/src/modules/colorPicker/ColorPickerUI/ViewModels/MainViewModel.cs @@ -16,6 +16,7 @@ using ColorPicker.Settings; using ColorPicker.ViewModelContracts; using Common.UI; using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Library.Enumerations; using PowerToys.Interop; namespace ColorPicker.ViewModels @@ -79,9 +80,10 @@ namespace ColorPicker.ViewModels { SetColorDetails(mouseInfoProvider.CurrentColor); mouseInfoProvider.MouseColorChanged += Mouse_ColorChanged; - mouseInfoProvider.OnMouseDown += MouseInfoProvider_OnMouseDown; + mouseInfoProvider.OnPrimaryMouseDown += MouseInfoProvider_OnPrimaryMouseDown; mouseInfoProvider.OnMouseWheel += MouseInfoProvider_OnMouseWheel; mouseInfoProvider.OnSecondaryMouseUp += MouseInfoProvider_OnSecondaryMouseUp; + mouseInfoProvider.OnMiddleMouseDown += MouseInfoProvider_OnMiddleMouseDown; } _userSettings.ShowColorName.PropertyChanged += (s, e) => { OnPropertyChanged(nameof(ShowColorName)); }; @@ -113,7 +115,7 @@ namespace ColorPicker.ViewModels private void AppStateHandler_EnterPressed(object sender, EventArgs e) { - MouseInfoProvider_OnMouseDown(null, default(System.Drawing.Point)); + MouseInfoProvider_OnPrimaryMouseDown(null, default); } /// @@ -167,18 +169,50 @@ namespace ColorPicker.ViewModels SetColorDetails(color); } - /// - /// Tell the color picker that the user have press a mouse button (after release the button) - /// - /// The sender of this event - /// The current of the mouse cursor - private void MouseInfoProvider_OnMouseDown(object sender, System.Drawing.Point p) + private void MouseInfoProvider_OnPrimaryMouseDown(object sender, IntPtr wParam) { - ClipboardHelper.CopyToClipboard(ColorText); + HandleMouseClickAction(_userSettings.PrimaryClickAction.Value); + } - var color = GetColorString(); + private void MouseInfoProvider_OnMiddleMouseDown(object sender, IntPtr wParam) + { + HandleMouseClickAction(_userSettings.MiddleClickAction.Value); + } - var oldIndex = _userSettings.ColorHistory.IndexOf(color); + private void MouseInfoProvider_OnSecondaryMouseUp(object sender, IntPtr wParam) + { + HandleMouseClickAction(_userSettings.SecondaryClickAction.Value); + } + + private void HandleMouseClickAction(ColorPickerClickAction action) + { + switch (action) + { + case ColorPickerClickAction.PickColorThenEditor: + ClipboardHelper.CopyToClipboard(ColorText); + UpdateColorHistory(GetColorString()); + + _appStateHandler.OpenColorEditor(); + + break; + + case ColorPickerClickAction.PickColorAndClose: + ClipboardHelper.CopyToClipboard(ColorText); + UpdateColorHistory(GetColorString()); + + _appStateHandler.EndUserSession(); + + break; + + case ColorPickerClickAction.Close: + _appStateHandler.EndUserSession(); + break; + } + } + + private void UpdateColorHistory(string color) + { + int oldIndex = _userSettings.ColorHistory.IndexOf(color); if (oldIndex != -1) { _userSettings.ColorHistory.Move(oldIndex, 0); @@ -192,13 +226,6 @@ namespace ColorPicker.ViewModels { _userSettings.ColorHistory.RemoveAt(_userSettings.ColorHistory.Count - 1); } - - _appStateHandler.OnColorPickerMouseDown(); - } - - private void MouseInfoProvider_OnSecondaryMouseUp(object sender, IntPtr wParam) - { - _appStateHandler.EndUserSession(); } private string GetColorString() diff --git a/src/settings-ui/Settings.UI.Library/ColorPickerProperties.cs b/src/settings-ui/Settings.UI.Library/ColorPickerProperties.cs index b82ef56888..c4d870cfbd 100644 --- a/src/settings-ui/Settings.UI.Library/ColorPickerProperties.cs +++ b/src/settings-ui/Settings.UI.Library/ColorPickerProperties.cs @@ -40,7 +40,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library VisibleColorFormats.Add("Decimal", new KeyValuePair(false, ColorFormatHelper.GetDefaultFormat("Decimal"))); VisibleColorFormats.Add("HEX Int", new KeyValuePair(false, ColorFormatHelper.GetDefaultFormat("HEX Int"))); ShowColorName = false; - ActivationAction = ColorPickerActivationAction.OpenColorPickerAndThenEditor; + ActivationAction = ColorPickerActivationAction.OpenColorPicker; + PrimaryClickAction = ColorPickerClickAction.PickColorThenEditor; + MiddleClickAction = ColorPickerClickAction.PickColorAndClose; + SecondaryClickAction = ColorPickerClickAction.Close; CopiedColorRepresentation = "HEX"; } @@ -57,6 +60,15 @@ namespace Microsoft.PowerToys.Settings.UI.Library [JsonPropertyName("activationaction")] public ColorPickerActivationAction ActivationAction { get; set; } + [JsonPropertyName("primaryclickaction")] + public ColorPickerClickAction PrimaryClickAction { get; set; } + + [JsonPropertyName("middleclickaction")] + public ColorPickerClickAction MiddleClickAction { get; set; } + + [JsonPropertyName("secondaryclickaction")] + public ColorPickerClickAction SecondaryClickAction { get; set; } + // Property ColorHistory is not used, the color history is saved separately in the colorHistory.json file [JsonPropertyName("colorhistory")] [CmdConfigureIgnoreAttribute] diff --git a/src/settings-ui/Settings.UI.Library/ColorPickerPropertiesVersion1.cs b/src/settings-ui/Settings.UI.Library/ColorPickerPropertiesVersion1.cs index d0e60d0eec..24f593213b 100644 --- a/src/settings-ui/Settings.UI.Library/ColorPickerPropertiesVersion1.cs +++ b/src/settings-ui/Settings.UI.Library/ColorPickerPropertiesVersion1.cs @@ -25,7 +25,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library VisibleColorFormats.Add("RGB", true); VisibleColorFormats.Add("HSL", true); ShowColorName = false; - ActivationAction = ColorPickerActivationAction.OpenColorPickerAndThenEditor; + ActivationAction = ColorPickerActivationAction.OpenColorPicker; } public HotkeySettings ActivationShortcut { get; set; } diff --git a/src/settings-ui/Settings.UI.Library/ColorPickerSettings.cs b/src/settings-ui/Settings.UI.Library/ColorPickerSettings.cs index 58a2b3f69d..641625e180 100644 --- a/src/settings-ui/Settings.UI.Library/ColorPickerSettings.cs +++ b/src/settings-ui/Settings.UI.Library/ColorPickerSettings.cs @@ -9,6 +9,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Library.Enumerations; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; namespace Microsoft.PowerToys.Settings.UI.Library @@ -23,7 +24,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library public ColorPickerSettings() { Properties = new ColorPickerProperties(); - Version = "2"; + Version = "2.1"; Name = ModuleName; } @@ -47,7 +48,21 @@ namespace Microsoft.PowerToys.Settings.UI.Library // This can be utilized in the future if the settings.json file is to be modified/deleted. public bool UpgradeSettingsConfiguration() - => false; + { + // Upgrading V1 to V2 doesn't set the version to 2.0, therefore V2 settings still report Version == 1.0 + if (Version == "1.0") + { + if (!Enum.IsDefined(Properties.ActivationAction)) + { + Properties.ActivationAction = ColorPickerActivationAction.OpenColorPicker; + } + + Version = "2.1"; + return true; + } + + return false; + } public static object UpgradeSettings(object oldSettingsObject) { diff --git a/src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerActivationAction.cs b/src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerActivationAction.cs index 459f6ddd2b..b3a9f55812 100644 --- a/src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerActivationAction.cs +++ b/src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerActivationAction.cs @@ -9,10 +9,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Enumerations // Activation shortcut opens editor OpenEditor, - // Activation shortcut opens color picker and after picking a color is copied into clipboard and opens editor - OpenColorPickerAndThenEditor, - - // Activation shortcut opens color picker only and picking color copies color into clipboard - OpenOnlyColorPicker, + // Activation shortcut opens color picker and after picking a color is copied into clipboard and editor optionally opens depending on which mouse button was pressed + OpenColorPicker, } } diff --git a/src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerClickAction.cs b/src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerClickAction.cs new file mode 100644 index 0000000000..9cb159f10f --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/Enumerations/ColorPickerClickAction.cs @@ -0,0 +1,18 @@ +// 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.Library.Enumerations +{ + public enum ColorPickerClickAction + { + // Clicking copies the picked color and opens the editor + PickColorThenEditor, + + // Clicking only copies the picked color and then exits color picker + PickColorAndClose, + + // Clicking exits color picker, without copying anything + Close, + } +} diff --git a/src/settings-ui/Settings.UI.Library/SettingsUtils.cs b/src/settings-ui/Settings.UI.Library/SettingsUtils.cs index 2c41850201..ea466f7077 100644 --- a/src/settings-ui/Settings.UI.Library/SettingsUtils.cs +++ b/src/settings-ui/Settings.UI.Library/SettingsUtils.cs @@ -130,6 +130,13 @@ namespace Microsoft.PowerToys.Settings.UI.Library T2 oldSettings = GetSettings(powertoy, fileName); T newSettings = (T)settingsUpgrader(oldSettings); Logger.LogInfo($"Settings file {fileName} for {powertoy} was read successfully in the old format."); + + // If the file needs to be modified, to save the new configurations accordingly. + if (newSettings.UpgradeSettingsConfiguration()) + { + SaveSettings(newSettings.ToJsonString(), powertoy, fileName); + } + return newSettings; } catch (Exception) diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/ColorPickerPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/ColorPickerPage.xaml index 4d036a517a..3d95a5c724 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/ColorPickerPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/ColorPickerPage.xaml @@ -50,12 +50,39 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index f4d91465d0..c1b7ec561d 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -1507,18 +1507,39 @@ Made with 💗 by Microsoft and the PowerToys community. Default color format - - Pick a color and open editor - - - Open editor - - - Only pick a color - Activation behavior + + Open editor + + + Pick a color first + + + Mouse actions + + + Choose what clicking individual buttons does + + + Primary click + + + Middle click + + + Secondary click + + + Pick a color and open editor + + + Pick a color and close + + + Close + Picker behavior diff --git a/src/settings-ui/Settings.UI/ViewModels/ColorPickerViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/ColorPickerViewModel.cs index d6006a58f7..5e7a9e85a4 100644 --- a/src/settings-ui/Settings.UI/ViewModels/ColorPickerViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/ColorPickerViewModel.cs @@ -182,6 +182,51 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public int PrimaryClickBehavior + { + get => (int)_colorPickerSettings.Properties.PrimaryClickAction; + + set + { + if (value != (int)_colorPickerSettings.Properties.PrimaryClickAction) + { + _colorPickerSettings.Properties.PrimaryClickAction = (ColorPickerClickAction)value; + OnPropertyChanged(nameof(PrimaryClickBehavior)); + NotifySettingsChanged(); + } + } + } + + public int MiddleClickBehavior + { + get => (int)_colorPickerSettings.Properties.MiddleClickAction; + + set + { + if (value != (int)_colorPickerSettings.Properties.MiddleClickAction) + { + _colorPickerSettings.Properties.MiddleClickAction = (ColorPickerClickAction)value; + OnPropertyChanged(nameof(MiddleClickBehavior)); + NotifySettingsChanged(); + } + } + } + + public int SecondaryClickBehavior + { + get => (int)_colorPickerSettings.Properties.SecondaryClickAction; + + set + { + if (value != (int)_colorPickerSettings.Properties.SecondaryClickAction) + { + _colorPickerSettings.Properties.SecondaryClickAction = (ColorPickerClickAction)value; + OnPropertyChanged(nameof(SecondaryClickBehavior)); + NotifySettingsChanged(); + } + } + } + public bool ShowColorName { get => _colorPickerSettings.Properties.ShowColorName;