Color picker - Lab format: use roundoff optional #13603#42986
Color picker - Lab format: use roundoff optional #13603#42986vanzue merged 3 commits intomicrosoft:mainfrom
Conversation
|
@microsoft-github-policy-service agree |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Adds an optional integer-rounding formatter for CIELab components in Color Picker formats, and updates the Settings UI help so users can discover/use the new formatter.
Changes:
- Extends
ColorFormatHelperto support aniformat suffix for%Lc/%Ca/%Cbto round CIELab values to whole numbers. - Updates the Settings UI Color Format Editor to show the new CIELab-specific formatter option.
- Updates localized help strings to describe CIELab formatting options.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/settings-ui/Settings.UI/Strings/en-us/Resources.resw | Updates help text and adds a new localized description for integer rounding. |
| src/settings-ui/Settings.UI/SettingsXAML/Controls/ColorFormatEditor.xaml.cs | Populates a new CIELab formatter list (adds i) and renames the RGBA formatter list control. |
| src/settings-ui/Settings.UI/SettingsXAML/Controls/ColorFormatEditor.xaml | Adds UI elements to display the CIELab formatter list and adjusts helpline text blocks accordingly. |
| src/common/ManagedCommon/ColorFormatHelper.cs | Implements the i formatter behavior for CIELab output via a shared formatting helper. |
| case 'i': | ||
| double roundedColorPercentValue = Math.Round(colorPercentValue); | ||
| if (roundedColorPercentValue == 0) | ||
| { |
There was a problem hiding this comment.
Math.Round(colorPercentValue) uses midpoint rounding-to-even by default. For a user-facing “rounded to nearest integer” option this can be surprising for *.5 values (e.g., 74.5 -> 74). Consider explicitly choosing a midpoint mode (commonly AwayFromZero) so rounding matches typical expectations.
There was a problem hiding this comment.
Should be ok in this scenario
| private static string ColorPercentFormatted(double colorPercentValue, char paramFormat, int defaultDecimalDigits) | ||
| { | ||
| switch (paramFormat) | ||
| { |
There was a problem hiding this comment.
The new i formatter for %Lc/%Ca/%Cb is behavior-changing but doesn’t appear to have unit coverage. There are existing ColorPicker unit tests for default format output; please add tests that assert integer rounding (and edge cases like negative values near 0) to prevent regressions.
| private static string ColorPercentFormatted(double colorPercentValue, char paramFormat, int defaultDecimalDigits) | ||
| { | ||
| switch (paramFormat) | ||
| { | ||
| case 'i': | ||
| double roundedColorPercentValue = Math.Round(colorPercentValue); | ||
| if (roundedColorPercentValue == 0) | ||
| { | ||
| // convert -0 to 0 | ||
| roundedColorPercentValue = 0.0; | ||
| } | ||
|
|
||
| return roundedColorPercentValue.ToString(CultureInfo.InvariantCulture); | ||
| default: | ||
| return Math.Round(colorPercentValue, defaultDecimalDigits).ToString(CultureInfo.InvariantCulture); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
ColorPercentFormatted is now used for CIELab L/a/b values but doesn’t actually apply a percent transformation (no *100, no % sign). Consider renaming the helper to reflect what it does (round/format a double) to avoid confusing future callers.
| private static string ColorPercentFormatted(double colorPercentValue, char paramFormat, int defaultDecimalDigits) | |
| { | |
| switch (paramFormat) | |
| { | |
| case 'i': | |
| double roundedColorPercentValue = Math.Round(colorPercentValue); | |
| if (roundedColorPercentValue == 0) | |
| { | |
| // convert -0 to 0 | |
| roundedColorPercentValue = 0.0; | |
| } | |
| return roundedColorPercentValue.ToString(CultureInfo.InvariantCulture); | |
| default: | |
| return Math.Round(colorPercentValue, defaultDecimalDigits).ToString(CultureInfo.InvariantCulture); | |
| } | |
| } | |
| /// <summary> | |
| /// Formats a color component value according to the specified format. | |
| /// This helper performs rounding only and does not apply any percent transformation | |
| /// (no multiplication by 100 and no percent sign is added). | |
| /// </summary> | |
| private static string FormatColorComponent(double value, char paramFormat, int defaultDecimalDigits) | |
| { | |
| switch (paramFormat) | |
| { | |
| case 'i': | |
| double roundedValue = Math.Round(value); | |
| if (roundedValue == 0) | |
| { | |
| // convert -0 to 0 | |
| roundedValue = 0.0; | |
| } | |
| return roundedValue.ToString(CultureInfo.InvariantCulture); | |
| default: | |
| return Math.Round(value, defaultDecimalDigits).ToString(CultureInfo.InvariantCulture); | |
| } | |
| } | |
| /// <summary> | |
| /// Formats a color value that was historically treated as a "percent" value. | |
| /// This method does not apply a percent transformation; it simply rounds and formats | |
| /// the provided value. Use <see cref="FormatColorComponent"/> for new code. | |
| /// </summary> | |
| [Obsolete("ColorPercentFormatted does not apply a percent transformation. Use FormatColorComponent instead.")] | |
| private static string ColorPercentFormatted(double colorPercentValue, char paramFormat, int defaultDecimalDigits) | |
| { | |
| return FormatColorComponent(colorPercentValue, paramFormat, defaultDecimalDigits); | |
| } |
| <value>rounded to the nearest integer</value> | ||
| </data> | ||
| <data name="ColorFormatEditorHelpline4.Text" xml:space="preserve"> | ||
| <value>Example: %ReX means red value in hex uppercase two digits format.</value> |
There was a problem hiding this comment.
The updated help text introduces a Lab-specific formatter (i), but the only example shown is still %ReX (RGB). Consider adding a Lab example (e.g., how to use i with %Lc/%Ca/%Cb) and/or stating the default (two decimal places) when no formatter is provided, so the new option is discoverable.
| <value>Example: %ReX means red value in hex uppercase two digits format.</value> | |
| <value>Example: %ReX means red value in hex uppercase two digits format. %Li means lightness value formatted as an integer using the Lab-specific 'i' formatter. When no formatter is provided (for example, %L, %Ca or %Cb), the value is shown with two decimal places by default.</value> |
|
Looking forward to the implementation released in next PT version. Thanks |
Summary of the Pull Request
The default CIELab format rounds the values to two decimal places, which is a degree of precision that isn't always needed. This PR adds an optional formatting character (i) to the three CIELab format parameters, which rounds the value to the nearest integer.
PR Checklist
Detailed Description of the Pull Request / Additional comments
In the case where a or b get rounded to -0 (e.g. -0.0001 rounds to -0), the negative sign gets removed. However, I noticed during testing that the default format (rounding to two decimal places) retains the negative sign in these situations (see third screenshot). I can a) revert to keeping the -0 for the new rounding behavior, b) change -0 to 0 for other rounded values, or c) leave it as-is. Also open to suggestions.
I can update the docs as well, if we're happy with the approach.
Validation Steps Performed