mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 17:56:44 +02:00
[ColorPicker]Custom color formats (#22141)
* [ColorPicker] Development: custom color formats, first steps * ColorPicker development of custom format handling. * Custom color format developmnet. Added common helper class for format string Fixed settings loading Added numbering if default name exists (My format (1)) * Custom color format implementation. Extended the colorPicker settings with the format string Updated the color to string conversion * Custom color format in color picker, development. Adding edit, delete buttons. Implement functionality Re-arranging settings panel (newly created formats at the top) Implementing details (valid parameters, more format elements, more types) * Minor commit * Development color picker custom formats. "Last" steps. Replacing hard coded english strings with resources, polishing. * Adding help to the format edit dialog. * Undoing changes unwillingly commited in Host module * Fixing bug unable to delete a custom format after renaming it - use the colorformat object as reference (and not the name) Modifying the default custom formula Removing unnecessary using directives * Udating the default user defined color format * Removing unnecessary using directive * ColorPicker Implementing custom color formats: adding custom formats to the default format selection (dropdown box). * Fix binding of name and example * Custom color formats, implemented steps: vorwarts compatibility loading settings. Fixed UI as requested (removed one settings panel, added button to the first panel) * Minor change in the UI: description modified * ColorPicker Custom Color Formats develepoment. Added conversion from old predefined formats to customizable formats. Extended default settings (in case settings file is deleted/corrupted). Minor fixes. * Fixing color format parameters. Implementing 3 different Saturation calculations, 2 Hue calculations and 2 Lightness calculations (depending color format) * Color Picker: New/Edit Color format. Fixing bug when cancelling addition/edit * ColorPicker. Updating help section, available parameters * Fix spellchecker * Remove the MinWidth so that scrollviewers can be drawn * ColorPicker bugfix: Not allowing to delete the last color format.
This commit is contained in:
@@ -10,10 +10,12 @@ using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Timers;
|
||||
using global::PowerToys.GPOWrapper;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Enumerations;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
@@ -35,9 +37,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
private GpoRuleConfigured _enabledGpoRuleConfiguration;
|
||||
private bool _enabledStateIsGPOConfigured;
|
||||
private bool _isEnabled;
|
||||
private int _colorFormatPreviewIndex;
|
||||
|
||||
private Func<string, int> SendConfigMSG { get; }
|
||||
|
||||
private Dictionary<string, string> _colorFormatsPreview;
|
||||
|
||||
public ColorPickerViewModel(
|
||||
ISettingsUtils settingsUtils,
|
||||
ISettingsRepository<GeneralSettings> settingsRepository,
|
||||
@@ -50,34 +55,20 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
throw new ArgumentNullException(nameof(settingsRepository));
|
||||
}
|
||||
|
||||
SelectableColorRepresentations = new Dictionary<ColorRepresentationType, string>
|
||||
{
|
||||
{ ColorRepresentationType.CMYK, "CMYK - cmyk(100%, 50%, 75%, 0%)" },
|
||||
{ ColorRepresentationType.HEX, "HEX - ffaa00" },
|
||||
{ ColorRepresentationType.HSB, "HSB - hsb(100, 50%, 75%)" },
|
||||
{ ColorRepresentationType.HSI, "HSI - hsi(100, 50%, 75%)" },
|
||||
{ ColorRepresentationType.HSL, "HSL - hsl(100, 50%, 75%)" },
|
||||
{ ColorRepresentationType.HSV, "HSV - hsv(100, 50%, 75%)" },
|
||||
{ ColorRepresentationType.HWB, "HWB - hwb(100, 50%, 75%)" },
|
||||
{ ColorRepresentationType.NCol, "NCol - R10, 50%, 75%" },
|
||||
{ ColorRepresentationType.RGB, "RGB - rgb(100, 50, 75)" },
|
||||
{ ColorRepresentationType.CIELAB, "CIE LAB - CIELab(76, 21, 80)" },
|
||||
{ ColorRepresentationType.CIEXYZ, "CIE XYZ - xyz(56, 50, 7)" },
|
||||
{ ColorRepresentationType.VEC4, "VEC4 - (1.0f, 0.7f, 0f, 1f)" },
|
||||
{ ColorRepresentationType.DecimalValue, "Decimal - 16755200" },
|
||||
{ ColorRepresentationType.HexInteger, "HEX Integer - 0xFFAA00EE" },
|
||||
};
|
||||
|
||||
GeneralSettingsConfig = settingsRepository.SettingsConfig;
|
||||
|
||||
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
|
||||
|
||||
if (colorPickerSettingsRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(colorPickerSettingsRepository));
|
||||
// used in release. This method converts the settings stored in the previous form, so we have forwards compatibility
|
||||
_colorPickerSettings = _settingsUtils.GetSettingsOrDefault<ColorPickerSettings, ColorPickerSettingsVersion1>(ColorPickerSettings.ModuleName, settingsUpgrader: ColorPickerSettings.UpgradeSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
_colorPickerSettings = colorPickerSettingsRepository.SettingsConfig; // used in the unit tests
|
||||
}
|
||||
|
||||
_colorPickerSettings = colorPickerSettingsRepository.SettingsConfig;
|
||||
_enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredColorPickerEnabledValue();
|
||||
if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
||||
{
|
||||
@@ -101,11 +92,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
InitializeColorFormats();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list with all selectable <see cref="ColorRepresentationType"/>s
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<ColorRepresentationType, string> SelectableColorRepresentations { get; }
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => _isEnabled;
|
||||
@@ -164,11 +150,16 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public ColorRepresentationType SelectedColorRepresentationValue
|
||||
public string SelectedColorRepresentationValue
|
||||
{
|
||||
get => _colorPickerSettings.Properties.CopiedColorRepresentation;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return; // do not set null value, it occurs when the combobox itemSource gets modified. Right after it well be reset to the correct value
|
||||
}
|
||||
|
||||
if (_colorPickerSettings.Properties.CopiedColorRepresentation != value)
|
||||
{
|
||||
_colorPickerSettings.Properties.CopiedColorRepresentation = value;
|
||||
@@ -212,66 +203,63 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
public ObservableCollection<ColorFormatModel> ColorFormats { get; } = new ObservableCollection<ColorFormatModel>();
|
||||
|
||||
private void InitializeColorFormats()
|
||||
public Dictionary<string, string> ColorFormatsPreview
|
||||
{
|
||||
var visibleFormats = _colorPickerSettings.Properties.VisibleColorFormats;
|
||||
var formatsUnordered = new List<ColorFormatModel>();
|
||||
|
||||
var hexFormatName = ColorRepresentationType.HEX.ToString();
|
||||
var rgbFormatName = ColorRepresentationType.RGB.ToString();
|
||||
var hslFormatName = ColorRepresentationType.HSL.ToString();
|
||||
var hsvFormatName = ColorRepresentationType.HSV.ToString();
|
||||
var cmykFormatName = ColorRepresentationType.CMYK.ToString();
|
||||
var hsbFormatName = ColorRepresentationType.HSB.ToString();
|
||||
var hsiFormatName = ColorRepresentationType.HSI.ToString();
|
||||
var hwbFormatName = ColorRepresentationType.HWB.ToString();
|
||||
var ncolFormatName = ColorRepresentationType.NCol.ToString();
|
||||
var cielabFormatName = ColorRepresentationType.CIELAB.ToString();
|
||||
var ciexyzFormatName = ColorRepresentationType.CIEXYZ.ToString();
|
||||
var vec4FormatName = ColorRepresentationType.VEC4.ToString();
|
||||
var hexIntegerFormatName = "HEX Int";
|
||||
var decimalFormatName = "Decimal";
|
||||
|
||||
formatsUnordered.Add(new ColorFormatModel(hexFormatName, "ef68ff", visibleFormats.ContainsKey(hexFormatName) && visibleFormats[hexFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(rgbFormatName, "rgb(239, 104, 255)", visibleFormats.ContainsKey(rgbFormatName) && visibleFormats[rgbFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(hslFormatName, "hsl(294, 100%, 70%)", visibleFormats.ContainsKey(hslFormatName) && visibleFormats[hslFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(hsvFormatName, "hsv(294, 59%, 100%)", visibleFormats.ContainsKey(hsvFormatName) && visibleFormats[hsvFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(cmykFormatName, "cmyk(6%, 59%, 0%, 0%)", visibleFormats.ContainsKey(cmykFormatName) && visibleFormats[cmykFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(hsbFormatName, "hsb(100, 50%, 75%)", visibleFormats.ContainsKey(hsbFormatName) && visibleFormats[hsbFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(hsiFormatName, "hsi(100, 50%, 75%)", visibleFormats.ContainsKey(hsiFormatName) && visibleFormats[hsiFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(hwbFormatName, "hwb(100, 50%, 75%)", visibleFormats.ContainsKey(hwbFormatName) && visibleFormats[hwbFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(ncolFormatName, "R10, 50%, 75%", visibleFormats.ContainsKey(ncolFormatName) && visibleFormats[ncolFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(cielabFormatName, "CIELab(66, 72, -52)", visibleFormats.ContainsKey(cielabFormatName) && visibleFormats[cielabFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(ciexyzFormatName, "XYZ(59, 35, 98)", visibleFormats.ContainsKey(ciexyzFormatName) && visibleFormats[ciexyzFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(vec4FormatName, "(0.94f, 0.41f, 1.00f, 1f)", visibleFormats.ContainsKey(vec4FormatName) && visibleFormats[vec4FormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(decimalFormatName, "15689983", visibleFormats.ContainsKey(decimalFormatName) && visibleFormats[decimalFormatName]));
|
||||
formatsUnordered.Add(new ColorFormatModel(hexIntegerFormatName, "0xFFAA00EE", visibleFormats.ContainsKey(hexIntegerFormatName) && visibleFormats[hexIntegerFormatName]));
|
||||
|
||||
foreach (var storedColorFormat in _colorPickerSettings.Properties.VisibleColorFormats)
|
||||
get => _colorFormatsPreview;
|
||||
set
|
||||
{
|
||||
var predefinedFormat = formatsUnordered.FirstOrDefault(it => it.Name == storedColorFormat.Key);
|
||||
if (predefinedFormat != null)
|
||||
{
|
||||
predefinedFormat.PropertyChanged += ColorFormat_PropertyChanged;
|
||||
ColorFormats.Add(predefinedFormat);
|
||||
formatsUnordered.Remove(predefinedFormat);
|
||||
}
|
||||
_colorFormatsPreview = value;
|
||||
OnPropertyChanged(nameof(ColorFormatsPreview));
|
||||
}
|
||||
}
|
||||
|
||||
public int ColorFormatsPreviewIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _colorFormatPreviewIndex;
|
||||
}
|
||||
|
||||
// settings file might not have all formats listed, add remaining ones we support
|
||||
foreach (var remainingColorFormat in formatsUnordered)
|
||||
set
|
||||
{
|
||||
remainingColorFormat.PropertyChanged += ColorFormat_PropertyChanged;
|
||||
ColorFormats.Add(remainingColorFormat);
|
||||
if (value != _colorFormatPreviewIndex)
|
||||
{
|
||||
_colorFormatPreviewIndex = value;
|
||||
OnPropertyChanged(nameof(ColorFormatsPreviewIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeColorFormats()
|
||||
{
|
||||
foreach (var storedColorFormat in _colorPickerSettings.Properties.VisibleColorFormats)
|
||||
{
|
||||
string format = storedColorFormat.Value.Value;
|
||||
if (format == string.Empty)
|
||||
{
|
||||
format = ColorFormatHelper.GetDefaultFormat(storedColorFormat.Key);
|
||||
}
|
||||
|
||||
ColorFormatModel customColorFormat = new ColorFormatModel(storedColorFormat.Key, format, storedColorFormat.Value.Key);
|
||||
customColorFormat.PropertyChanged += ColorFormat_PropertyChanged;
|
||||
ColorFormats.Add(customColorFormat);
|
||||
}
|
||||
|
||||
// Reordering colors with buttons: disable first and last buttons
|
||||
ColorFormats[0].CanMoveUp = false;
|
||||
ColorFormats[ColorFormats.Count - 1].CanMoveDown = false;
|
||||
|
||||
UpdateColorFormatPreview();
|
||||
ColorFormats.CollectionChanged += ColorFormats_CollectionChanged;
|
||||
}
|
||||
|
||||
private void UpdateColorFormatPreview()
|
||||
{
|
||||
ColorFormatsPreview = ColorFormats.Select(x => new KeyValuePair<string, string>(x.Name, x.Name + " - " + x.Example)).ToDictionary(x => x.Key, x => x.Value);
|
||||
SetPreviewSelectedIndex();
|
||||
ScheduleSavingOfSettings();
|
||||
}
|
||||
|
||||
private void ColorFormats_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
// Reordering colors with buttons: update buttons availability depending on order
|
||||
@@ -287,7 +275,20 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
ColorFormats[ColorFormats.Count - 1].CanMoveDown = false;
|
||||
}
|
||||
|
||||
if (ColorFormats.Count == 1)
|
||||
{
|
||||
ColorFormats.Single().CanBeDeleted = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var color in ColorFormats)
|
||||
{
|
||||
color.CanBeDeleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateColorFormats();
|
||||
UpdateColorFormatPreview();
|
||||
ScheduleSavingOfSettings();
|
||||
}
|
||||
|
||||
@@ -324,10 +325,21 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_colorPickerSettings.Properties.VisibleColorFormats.Clear();
|
||||
foreach (var colorFormat in ColorFormats)
|
||||
{
|
||||
_colorPickerSettings.Properties.VisibleColorFormats.Add(colorFormat.Name, colorFormat.IsShown);
|
||||
_colorPickerSettings.Properties.VisibleColorFormats.Add(colorFormat.Name, new KeyValuePair<bool, string>(colorFormat.IsShown, colorFormat.Format));
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddNewColorFormat(string newColorName, string newColorFormat, bool isShown)
|
||||
{
|
||||
if (ColorFormats.Count > 0)
|
||||
{
|
||||
ColorFormats[0].CanMoveUp = true;
|
||||
}
|
||||
|
||||
ColorFormats.Insert(0, new ColorFormatModel(newColorName, newColorFormat, isShown));
|
||||
SetPreviewSelectedIndex();
|
||||
}
|
||||
|
||||
private void NotifySettingsChanged()
|
||||
{
|
||||
// Using InvariantCulture as this is an IPC message
|
||||
@@ -357,5 +369,75 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
internal ColorFormatModel GetNewColorFormatModel()
|
||||
{
|
||||
var resourceLoader = ResourceLoader.GetForViewIndependentUse();
|
||||
string defaultName = resourceLoader.GetString("CustomColorFormatDefaultName");
|
||||
ColorFormatModel newColorFormatModel = new ColorFormatModel();
|
||||
newColorFormatModel.Name = defaultName;
|
||||
int extensionNumber = 1;
|
||||
while (ColorFormats.Any(x => x.Name.Equals(newColorFormatModel.Name, StringComparison.Ordinal)))
|
||||
{
|
||||
newColorFormatModel.Name = defaultName + " (" + extensionNumber + ")";
|
||||
extensionNumber++;
|
||||
}
|
||||
|
||||
return newColorFormatModel;
|
||||
}
|
||||
|
||||
internal void SetValidity(ColorFormatModel colorFormatModel, string oldName)
|
||||
{
|
||||
if ((colorFormatModel.Format == string.Empty) || (colorFormatModel.Name == string.Empty))
|
||||
{
|
||||
colorFormatModel.IsValid = false;
|
||||
}
|
||||
else if (colorFormatModel.Name == oldName)
|
||||
{
|
||||
colorFormatModel.IsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorFormatModel.IsValid = ColorFormats.Count(x => x.Name.ToUpperInvariant().Equals(colorFormatModel.Name.ToUpperInvariant(), StringComparison.Ordinal)) < 2;
|
||||
}
|
||||
}
|
||||
|
||||
internal void DeleteModel(ColorFormatModel colorFormatModel)
|
||||
{
|
||||
ColorFormats.Remove(colorFormatModel);
|
||||
SetPreviewSelectedIndex();
|
||||
}
|
||||
|
||||
internal void UpdateColorFormat(string oldName, ColorFormatModel colorFormat)
|
||||
{
|
||||
if (SelectedColorRepresentationValue == oldName)
|
||||
{
|
||||
SelectedColorRepresentationValue = colorFormat.Name; // name might be changed by the user
|
||||
}
|
||||
|
||||
UpdateColorFormatPreview();
|
||||
}
|
||||
|
||||
internal void SetPreviewSelectedIndex()
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
foreach (var item in ColorFormats)
|
||||
{
|
||||
if (item.Name == SelectedColorRepresentationValue)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index >= ColorFormats.Count)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
ColorFormatsPreviewIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user