mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Remove ColorHelper (#19187)
Most of `ColorHelper` was unused and one of them had UB. Related to #19183 ## Validation Steps Performed * Set a custom tabRow theme color Split button looks similar to before ✅ * White/black FG color decision for colored tabs is similar to before ✅
This commit is contained in:
parent
7d6e0c8b8e
commit
0c3002c1b9
@ -1,267 +0,0 @@
|
||||
#include "ColorHelper.h"
|
||||
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
// Method Description:
|
||||
// Determines whether or not a given color is light
|
||||
// Arguments:
|
||||
// - color: this color is going to be examined whether it
|
||||
// is light or not
|
||||
// Return Value:
|
||||
// - true if light, false if dark
|
||||
bool ColorHelper::IsBrightColor(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
// https://www.w3.org/TR/AERT#color-contrast
|
||||
auto brightness = (color.R * 299 + color.G * 587 + color.B * 114) / 1000.f;
|
||||
return brightness > 128.f;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Converts a rgb color to an hsl one
|
||||
// Arguments:
|
||||
// - color: the rgb color, which is going to be converted
|
||||
// Return Value:
|
||||
// - a hsl color with the following ranges
|
||||
// - H: [0.f -360.f]
|
||||
// - L: [0.f - 1.f] (rounded to the third decimal place)
|
||||
// - S: [0.f - 1.f] (rounded to the third decimal place)
|
||||
HSL ColorHelper::RgbToHsl(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
// https://www.rapidtables.com/convert/color/rgb-to-hsl.html
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
auto r = color.R / 255.f;
|
||||
auto g = color.G / 255.f;
|
||||
auto b = color.B / 255.f;
|
||||
|
||||
auto max = std::max(r, std::max(g, b));
|
||||
auto min = std::min(r, std::min(g, b));
|
||||
|
||||
auto delta = max - min;
|
||||
|
||||
auto h = 0.f;
|
||||
auto s = 0.f;
|
||||
auto l = (max + min) / 2;
|
||||
|
||||
if (delta < epsilon || max < epsilon) /* delta == 0 || max == 0*/
|
||||
{
|
||||
l = std::roundf(l * 1000) / 1000;
|
||||
return HSL{ h, s, l };
|
||||
}
|
||||
|
||||
s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
|
||||
|
||||
if (max - r < epsilon) // max == r
|
||||
{
|
||||
h = (g - b) / delta + (g < b ? 6 : 0);
|
||||
}
|
||||
else if (max - g < epsilon) // max == g
|
||||
{
|
||||
h = (b - r) / delta + 2;
|
||||
}
|
||||
else if (max - b < epsilon) // max == b
|
||||
{
|
||||
h = (r - g) / delta + 4;
|
||||
}
|
||||
|
||||
// three decimal places after the comma ought
|
||||
// to be enough for everybody - Bill Gates, 1981
|
||||
auto finalH = std::roundf(h * 60);
|
||||
auto finalS = std::roundf(s * 1000) / 1000;
|
||||
auto finalL = std::roundf(l * 1000) / 1000;
|
||||
|
||||
return HSL{ finalH, finalS, finalL };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Converts a hsl color to rgb one
|
||||
// Arguments:
|
||||
// - color: the hsl color, which is going to be converted
|
||||
// Return Value:
|
||||
// - the rgb color (r,g,b - [0, 255] range)
|
||||
winrt::Windows::UI::Color ColorHelper::HslToRgb(const HSL& color)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
auto h = (color.H - 1.f > epsilon) ? color.H / 360.f : color.H;
|
||||
auto s = (color.S - 1.f > epsilon) ? color.S / 100.f : color.S;
|
||||
auto l = (color.L - 1.f > epsilon) ? color.L / 100.f : color.L;
|
||||
|
||||
auto r = l;
|
||||
auto g = l;
|
||||
auto b = l;
|
||||
|
||||
if (s > epsilon)
|
||||
{
|
||||
auto q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
auto p = 2 * l - q;
|
||||
r = HueToRgb(p, q, h + 1.f / 3.f);
|
||||
g = HueToRgb(p, q, h);
|
||||
b = HueToRgb(p, q, h - 1.f / 3.f);
|
||||
}
|
||||
|
||||
auto finalR = static_cast<uint8_t>(std::roundf(r * 255));
|
||||
auto finalG = static_cast<uint8_t>(std::roundf(g * 255));
|
||||
auto finalB = static_cast<uint8_t>(std::roundf(b * 255));
|
||||
uint8_t finalA = 255; //opaque
|
||||
|
||||
return winrt::Windows::UI::ColorHelper::FromArgb(finalA, finalR, finalG, finalB);
|
||||
}
|
||||
|
||||
float ColorHelper::HueToRgb(float p, float q, float t)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
if (t < 0)
|
||||
t += 1;
|
||||
if (t > 1)
|
||||
t -= 1;
|
||||
if (t - (1.f / 6.f) < epsilon)
|
||||
return p + (q - p) * 6 * t;
|
||||
if (t - .5f < epsilon)
|
||||
return q;
|
||||
if (t - 2.f / 3.f < epsilon)
|
||||
return p + (q - p) * (2.f / 3.f - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Lightens a color by a given amount
|
||||
// Arguments:
|
||||
// - color: the color which is going to be lightened
|
||||
// - amount: the lighten amount (0-100)
|
||||
// Return Value:
|
||||
// - the lightened color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::Lighten(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
|
||||
{
|
||||
auto hsl = RgbToHsl(color);
|
||||
hsl.L += amount / 100;
|
||||
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
|
||||
return HslToRgb(hsl);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Darkens a color by a given amount
|
||||
// Arguments:
|
||||
// - color: the color which is going to be darkened
|
||||
// - amount: the darken amount (0-100)
|
||||
// Return Value:
|
||||
// - the darkened color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::Darken(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
|
||||
{
|
||||
auto hsl = RgbToHsl(color);
|
||||
hsl.L -= amount / 100;
|
||||
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
|
||||
return HslToRgb(hsl);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets an accent color to a given color. Basically, generates
|
||||
// 16 shades of the color and finds the first which has a good
|
||||
// contrast according to https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Readability ratio of 3.5 seems to look quite nicely
|
||||
// Arguments:
|
||||
// - color: the color for which we need an accent
|
||||
// Return Value:
|
||||
// - the accent color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::GetAccentColor(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
auto accentColor = RgbToHsl(color);
|
||||
|
||||
if (accentColor.S < 0.15)
|
||||
{
|
||||
accentColor.S = 0.15f;
|
||||
}
|
||||
|
||||
constexpr auto shadeCount = 16;
|
||||
constexpr auto shadeStep = 1.f / shadeCount;
|
||||
auto shades = std::map<float, HSL>();
|
||||
for (auto i = 0; i < 15; i++)
|
||||
{
|
||||
auto shade = HSL{ accentColor.H, accentColor.S, i * shadeStep };
|
||||
auto contrast = GetReadability(shade, accentColor);
|
||||
shades.insert(std::make_pair(contrast, shade));
|
||||
}
|
||||
|
||||
// 3f is quite nice if the whole non-client area is painted
|
||||
constexpr auto readability = 1.75f;
|
||||
for (auto shade : shades)
|
||||
{
|
||||
if (shade.first >= readability)
|
||||
{
|
||||
return HslToRgb(shade.second);
|
||||
}
|
||||
}
|
||||
return HslToRgb(shades.end()->second);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets the readability of two colors according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Arguments:
|
||||
// - firstColor: the first color for the readability check (hsl)
|
||||
// - secondColor: the second color for the readability check (hsl)
|
||||
// Return Value:
|
||||
// - the readability of the colors according to (WCAG Version 2)
|
||||
float ColorHelper::GetReadability(const HSL& first, const HSL& second)
|
||||
{
|
||||
return GetReadability(HslToRgb(first), HslToRgb(second));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets the readability of two colors according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Arguments:
|
||||
// - firstColor: the first color for the readability check (rgb)
|
||||
// - secondColor: the second color for the readability check (rgb)
|
||||
// Return Value:
|
||||
// - the readability of the colors according to (WCAG Version 2)
|
||||
float ColorHelper::GetReadability(const winrt::Windows::UI::Color& first, const winrt::Windows::UI::Color& second)
|
||||
{
|
||||
auto l1 = GetLuminance(first);
|
||||
auto l2 = GetLuminance(second);
|
||||
|
||||
return (std::max(l1, l2) + 0.05f) / std::min(l1, l2) + 0.05f;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Calculates the luminance of a given color according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
// Arguments:
|
||||
// - color: its luminance is going to be calculated
|
||||
// Return Value:
|
||||
// - the luminance of the color
|
||||
float ColorHelper::GetLuminance(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
float R, G, B;
|
||||
auto RsRGB = color.R / 255.f;
|
||||
auto GsRGB = color.G / 255.f;
|
||||
auto BsRGB = color.B / 255.f;
|
||||
|
||||
if (RsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
R = RsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
R = std::pow(((RsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
if (GsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
G = GsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
G = std::pow(((GsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
if (BsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
B = BsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
B = std::pow(((BsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
auto luminance = (0.2126f * R) + (0.7152f * G) + (0.0722f * B);
|
||||
return std::roundf(luminance * 10000) / 10000.f;
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <winrt/Windows.UI.h>
|
||||
|
||||
namespace winrt::TerminalApp
|
||||
{
|
||||
class HSL
|
||||
{
|
||||
public:
|
||||
float H;
|
||||
float S;
|
||||
float L;
|
||||
};
|
||||
|
||||
class ColorHelper
|
||||
{
|
||||
public:
|
||||
static bool IsBrightColor(const Windows::UI::Color& color);
|
||||
static HSL RgbToHsl(const Windows::UI::Color& color);
|
||||
static Windows::UI::Color HslToRgb(const HSL& color);
|
||||
static Windows::UI::Color Lighten(const Windows::UI::Color& color, float amount = 10.f);
|
||||
static Windows::UI::Color Darken(const Windows::UI::Color& color, float amount = 10.f);
|
||||
static Windows::UI::Color GetAccentColor(const Windows::UI::Color& color);
|
||||
static float GetLuminance(const Windows::UI::Color& color);
|
||||
static float GetReadability(const Windows::UI::Color& first, const Windows::UI::Color& second);
|
||||
static float GetReadability(const HSL& first, const HSL& second);
|
||||
|
||||
private:
|
||||
static float HueToRgb(float p, float q, float t);
|
||||
};
|
||||
}
|
||||
@ -8,8 +8,8 @@
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "Tab.g.cpp"
|
||||
#include "Utils.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "AppLogic.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
@ -2275,11 +2275,13 @@ namespace winrt::TerminalApp::implementation
|
||||
// the background color
|
||||
// - This method should only be called on the UI thread.
|
||||
// Arguments:
|
||||
// - color: the color the user picked for their tab
|
||||
// - uiColor: the color the user picked for their tab
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void Tab::_ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color)
|
||||
void Tab::_ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& uiColor)
|
||||
{
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
const til::color color{ uiColor };
|
||||
Media::SolidColorBrush selectedTabBrush{};
|
||||
Media::SolidColorBrush deselectedTabBrush{};
|
||||
Media::SolidColorBrush fontBrush{};
|
||||
@ -2292,7 +2294,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// calculate the luminance of the current color and select a font
|
||||
// color based on that
|
||||
// see https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(color))
|
||||
if (ColorFix::GetLightness(color) >= lightnessThreshold)
|
||||
{
|
||||
auto subtleFillColorSecondary = winrt::Windows::UI::Colors::Black();
|
||||
subtleFillColorSecondary.A = 0x09;
|
||||
@ -2312,8 +2314,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// The tab font should be based on the evaluated appearance of the tab color layered on tab row.
|
||||
const auto layeredTabColor = til::color{ color }.layer_over(_tabRowColor);
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(layeredTabColor))
|
||||
const auto layeredTabColor = color.layer_over(_tabRowColor);
|
||||
if (ColorFix::GetLightness(layeredTabColor) >= lightnessThreshold)
|
||||
{
|
||||
fontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
auto secondaryFontColor = winrt::Windows::UI::Colors::Black();
|
||||
@ -2333,8 +2335,7 @@ namespace winrt::TerminalApp::implementation
|
||||
selectedTabBrush.Color(color);
|
||||
|
||||
// Start with the current tab color, set to Opacity=.3
|
||||
til::color deselectedTabColor{ color };
|
||||
deselectedTabColor = deselectedTabColor.with_alpha(77); // 255 * .3 = 77
|
||||
auto deselectedTabColor = color.with_alpha(77); // 255 * .3 = 77
|
||||
|
||||
// If we DON'T have a color set from the color picker, or the profile's
|
||||
// tabColor, but we do have a unfocused color in the theme, use the
|
||||
@ -2376,7 +2377,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// We don't want that to result in white text on a white tab row for
|
||||
// inactive tabs.
|
||||
const auto deselectedActualColor = deselectedTabColor.layer_over(_tabRowColor);
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(deselectedActualColor))
|
||||
if (ColorFix::GetLightness(deselectedActualColor) >= lightnessThreshold)
|
||||
{
|
||||
deselectedFontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "TabRowControl.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "..\TerminalSettingsModel\FileUtils.h"
|
||||
|
||||
|
||||
@ -134,7 +134,6 @@
|
||||
<ClInclude Include="FilteredCommand.h" />
|
||||
<ClInclude Include="Pane.h" />
|
||||
<ClInclude Include="fzf/fzf.h" />
|
||||
<ClInclude Include="ColorHelper.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="ShortcutActionDispatch.h">
|
||||
<DependentUpon>ShortcutActionDispatch.idl</DependentUpon>
|
||||
@ -247,9 +246,6 @@
|
||||
<ClCompile Include="FilteredCommand.cpp" />
|
||||
<ClCompile Include="Pane.cpp" />
|
||||
<ClCompile Include="Pane.LayoutSizeNode.cpp" />
|
||||
<ClCompile Include="ColorHelper.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DebugTapConnection.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="AppCommandlineArgs.cpp" />
|
||||
<ClCompile Include="Commandline.cpp" />
|
||||
<ClCompile Include="ColorHelper.cpp" />
|
||||
<ClCompile Include="DebugTapConnection.cpp" />
|
||||
<ClCompile Include="Jumplist.cpp" />
|
||||
<ClCompile Include="FilteredCommand.cpp">
|
||||
@ -48,7 +47,6 @@
|
||||
<ClInclude Include="AppCommandlineArgs.h" />
|
||||
<ClInclude Include="Commandline.h" />
|
||||
<ClInclude Include="DebugTapConnection.h" />
|
||||
<ClInclude Include="ColorHelper.h" />
|
||||
<ClInclude Include="Jumplist.h" />
|
||||
<ClInclude Include="FilteredCommand.h">
|
||||
<Filter>commandPalette</Filter>
|
||||
|
||||
@ -6,24 +6,24 @@
|
||||
#include "TerminalPage.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
#include <TerminalCore/ControlKeyStates.hpp>
|
||||
#include <Utils.h>
|
||||
#include <TerminalCore/ControlKeyStates.hpp>
|
||||
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "App.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "ScratchpadContent.h"
|
||||
#include "SnippetsPaneContent.h"
|
||||
#include "MarkdownPaneContent.h"
|
||||
#include "TabRowControl.h"
|
||||
#include "Remoting.h"
|
||||
#include "ScratchpadContent.h"
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "SnippetsPaneContent.h"
|
||||
#include "TabRowControl.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include "TerminalPage.g.cpp"
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
#include "RenameWindowRequestedArgs.g.cpp"
|
||||
#include "RequestMoveContentArgs.g.cpp"
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
#include "TerminalPage.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Microsoft::Management::Deployment;
|
||||
@ -3904,36 +3904,18 @@ namespace winrt::TerminalApp::implementation
|
||||
// and the non-client are behind it
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor)
|
||||
void TerminalPage::_SetNewTabButtonColor(const til::color color, const til::color accentColor)
|
||||
{
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
// TODO GH#3327: Look at what to do with the tab button when we have XAML theming
|
||||
auto IsBrightColor = ColorHelper::IsBrightColor(color);
|
||||
auto isLightAccentColor = ColorHelper::IsBrightColor(accentColor);
|
||||
winrt::Windows::UI::Color pressedColor{};
|
||||
winrt::Windows::UI::Color hoverColor{};
|
||||
winrt::Windows::UI::Color foregroundColor{};
|
||||
const auto hoverColorAdjustment = 5.f;
|
||||
const auto pressedColorAdjustment = 7.f;
|
||||
const auto IsBrightColor = ColorFix::GetLightness(color) >= lightnessThreshold;
|
||||
const auto isLightAccentColor = ColorFix::GetLightness(accentColor) >= lightnessThreshold;
|
||||
const auto hoverColorAdjustment = isLightAccentColor ? -0.05f : 0.05f;
|
||||
const auto pressedColorAdjustment = isLightAccentColor ? -0.1f : 0.1f;
|
||||
|
||||
if (IsBrightColor)
|
||||
{
|
||||
foregroundColor = winrt::Windows::UI::Colors::Black();
|
||||
}
|
||||
else
|
||||
{
|
||||
foregroundColor = winrt::Windows::UI::Colors::White();
|
||||
}
|
||||
|
||||
if (isLightAccentColor)
|
||||
{
|
||||
hoverColor = ColorHelper::Darken(accentColor, hoverColorAdjustment);
|
||||
pressedColor = ColorHelper::Darken(accentColor, pressedColorAdjustment);
|
||||
}
|
||||
else
|
||||
{
|
||||
hoverColor = ColorHelper::Lighten(accentColor, hoverColorAdjustment);
|
||||
pressedColor = ColorHelper::Lighten(accentColor, pressedColorAdjustment);
|
||||
}
|
||||
const auto foregroundColor = IsBrightColor ? Colors::Black() : Colors::White();
|
||||
const auto hoverColor = til::color{ ColorFix::AdjustLightness(accentColor, hoverColorAdjustment) };
|
||||
const auto pressedColor = til::color{ ColorFix::AdjustLightness(accentColor, pressedColorAdjustment) };
|
||||
|
||||
Media::SolidColorBrush backgroundBrush{ accentColor };
|
||||
Media::SolidColorBrush backgroundHoverBrush{ hoverColor };
|
||||
|
||||
@ -463,7 +463,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _RefreshUIForSettingsReload();
|
||||
|
||||
void _SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor);
|
||||
void _SetNewTabButtonColor(til::color color, til::color accentColor);
|
||||
void _ClearNewTabButtonColor();
|
||||
|
||||
safe_void_coroutine _CompleteInitialization();
|
||||
|
||||
@ -7,8 +7,7 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "TitlebarControl.h"
|
||||
|
||||
#include "ColorHelper.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
|
||||
#include "TitlebarControl.g.cpp"
|
||||
|
||||
@ -189,7 +188,8 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
const auto isBrightColor = ColorHelper::IsBrightColor(c);
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
const auto isBrightColor = ColorFix::GetLightness(c) >= lightnessThreshold;
|
||||
MinMaxCloseControl().RequestedTheme(isBrightColor ? winrt::Windows::UI::Xaml::ElementTheme::Light :
|
||||
winrt::Windows::UI::Xaml::ElementTheme::Dark);
|
||||
}
|
||||
|
||||
@ -1,130 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "../TerminalSettingsModel/Profile.h"
|
||||
#include "../TerminalApp/ColorHelper.h"
|
||||
|
||||
// Import some templates to compare floats using approximate matching.
|
||||
#include <consoletaeftemplates.hpp>
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
|
||||
namespace TerminalAppUnitTests
|
||||
{
|
||||
class ColorHelperTests
|
||||
{
|
||||
BEGIN_TEST_CLASS(ColorHelperTests)
|
||||
TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.Unit.Tests.manifest")
|
||||
END_TEST_CLASS()
|
||||
|
||||
TEST_METHOD(ConvertRgbToHsl);
|
||||
TEST_METHOD(ConvertHslToRgb);
|
||||
TEST_METHOD(LuminanceTests);
|
||||
};
|
||||
|
||||
void ColorHelperTests::ConvertHslToRgb()
|
||||
{
|
||||
auto red = winrt::Windows::UI::Colors::Red();
|
||||
auto redHsl = ColorHelper::RgbToHsl(red);
|
||||
VERIFY_ARE_EQUAL(0.f, redHsl.H);
|
||||
VERIFY_ARE_EQUAL(1.f, redHsl.S);
|
||||
VERIFY_ARE_EQUAL(0.5f, redHsl.L);
|
||||
|
||||
auto green = winrt::Windows::UI::Colors::Lime();
|
||||
auto greenHsl = ColorHelper::RgbToHsl(green);
|
||||
VERIFY_ARE_EQUAL(120.f, greenHsl.H);
|
||||
VERIFY_ARE_EQUAL(1.f, greenHsl.S);
|
||||
VERIFY_ARE_EQUAL(0.5f, greenHsl.L);
|
||||
|
||||
auto blue = winrt::Windows::UI::Colors::Blue();
|
||||
auto blueHsl = ColorHelper::RgbToHsl(blue);
|
||||
VERIFY_ARE_EQUAL(240.f, blueHsl.H);
|
||||
VERIFY_ARE_EQUAL(1.f, blueHsl.S);
|
||||
VERIFY_ARE_EQUAL(0.5f, blueHsl.L);
|
||||
|
||||
auto darkTurquoise = winrt::Windows::UI::Colors::DarkTurquoise();
|
||||
auto darkTurquoiseHsl = ColorHelper::RgbToHsl(darkTurquoise);
|
||||
VERIFY_ARE_EQUAL(181.f, darkTurquoiseHsl.H);
|
||||
VERIFY_ARE_EQUAL(1.f, darkTurquoiseHsl.S);
|
||||
VERIFY_ARE_EQUAL(0.41f, darkTurquoiseHsl.L);
|
||||
|
||||
auto darkViolet = winrt::Windows::UI::Colors::DarkViolet();
|
||||
auto darkVioletHsl = ColorHelper::RgbToHsl(darkViolet);
|
||||
VERIFY_ARE_EQUAL(282.f, darkVioletHsl.H);
|
||||
VERIFY_ARE_EQUAL(1.f, darkVioletHsl.S);
|
||||
VERIFY_ARE_EQUAL(0.414f, darkVioletHsl.L);
|
||||
|
||||
auto white = winrt::Windows::UI::Colors::White();
|
||||
auto whiteHsl = ColorHelper::RgbToHsl(white);
|
||||
VERIFY_ARE_EQUAL(0.f, whiteHsl.H);
|
||||
VERIFY_ARE_EQUAL(0.f, whiteHsl.S);
|
||||
VERIFY_ARE_EQUAL(1.f, whiteHsl.L);
|
||||
|
||||
auto black = winrt::Windows::UI::Colors::Black();
|
||||
auto blackHsl = ColorHelper::RgbToHsl(black);
|
||||
VERIFY_ARE_EQUAL(0.f, blackHsl.H);
|
||||
VERIFY_ARE_EQUAL(0.f, blackHsl.S);
|
||||
VERIFY_ARE_EQUAL(0.f, blackHsl.L);
|
||||
}
|
||||
|
||||
void ColorHelperTests::ConvertRgbToHsl()
|
||||
{
|
||||
auto redHsl = HSL{ 0.f, 100.f, 50.f };
|
||||
auto red = ColorHelper::HslToRgb(redHsl);
|
||||
VERIFY_ARE_EQUAL(255, red.R);
|
||||
VERIFY_ARE_EQUAL(0, red.G);
|
||||
VERIFY_ARE_EQUAL(0, red.B);
|
||||
|
||||
auto greenHsl = HSL{ 120.f, 100.f, 50.f };
|
||||
auto green = ColorHelper::HslToRgb(greenHsl);
|
||||
VERIFY_ARE_EQUAL(0, green.R);
|
||||
VERIFY_ARE_EQUAL(255, green.G);
|
||||
VERIFY_ARE_EQUAL(0, green.B);
|
||||
|
||||
auto blueHsl = HSL{ 240.f, 100.f, 50.f };
|
||||
auto blue = ColorHelper::HslToRgb(blueHsl);
|
||||
VERIFY_ARE_EQUAL(0, blue.R);
|
||||
VERIFY_ARE_EQUAL(0, blue.G);
|
||||
VERIFY_ARE_EQUAL(255, blue.B);
|
||||
|
||||
auto darkTurquoiseHsl = HSL{ 181.f, 100.f, 41.f };
|
||||
auto darkTurquoise = ColorHelper::HslToRgb(darkTurquoiseHsl);
|
||||
VERIFY_ARE_EQUAL(0, darkTurquoise.R);
|
||||
VERIFY_ARE_EQUAL(206, darkTurquoise.G);
|
||||
VERIFY_ARE_EQUAL(209, darkTurquoise.B);
|
||||
|
||||
auto darkVioletHsl = HSL{ 282.f, 100.f, 41.4f };
|
||||
auto darkViolet = ColorHelper::HslToRgb(darkVioletHsl);
|
||||
VERIFY_ARE_EQUAL(148, darkViolet.R);
|
||||
VERIFY_ARE_EQUAL(0, darkViolet.G);
|
||||
VERIFY_ARE_EQUAL(211, darkViolet.B);
|
||||
|
||||
auto whiteHsl = HSL{ 360.f, 100.f, 100.f };
|
||||
auto white = ColorHelper::HslToRgb(whiteHsl);
|
||||
VERIFY_ARE_EQUAL(255, white.R);
|
||||
VERIFY_ARE_EQUAL(255, white.G);
|
||||
VERIFY_ARE_EQUAL(255, white.B);
|
||||
|
||||
auto blackHsl = HSL{ 0.f, 0.f, 0.f };
|
||||
auto black = ColorHelper::HslToRgb(blackHsl);
|
||||
VERIFY_ARE_EQUAL(0, black.R);
|
||||
VERIFY_ARE_EQUAL(0, black.G);
|
||||
VERIFY_ARE_EQUAL(0, black.B);
|
||||
}
|
||||
|
||||
void ColorHelperTests::LuminanceTests()
|
||||
{
|
||||
auto darkTurquoiseLuminance = ColorHelper::GetLuminance(winrt::Windows::UI::Colors::DarkTurquoise());
|
||||
VERIFY_ARE_EQUAL(48.75f, darkTurquoiseLuminance * 100);
|
||||
auto darkVioletLuminance = ColorHelper::GetLuminance(winrt::Windows::UI::Colors::DarkViolet());
|
||||
VERIFY_ARE_EQUAL(11.f, darkVioletLuminance * 100);
|
||||
auto magentaLuminance = ColorHelper::GetLuminance(winrt::Windows::UI::Colors::Magenta());
|
||||
VERIFY_ARE_EQUAL(28.48f, magentaLuminance * 100);
|
||||
}
|
||||
}
|
||||
@ -21,17 +21,11 @@
|
||||
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ColorHelperTests.cpp" />
|
||||
|
||||
<ClCompile Include="JsonUtilsTests.cpp" />
|
||||
<ClCompile Include="FzfTests.cpp" />
|
||||
|
||||
<ClCompile Include="precomp.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\TerminalApp\ColorHelper.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ========================= Project References ======================== -->
|
||||
|
||||
@ -322,7 +322,7 @@ CATCH_RETURN()
|
||||
auto misc = _api.s.write()->misc.write();
|
||||
misc->selectionColor = newSelectionColor;
|
||||
// Select a black or white foreground based on the perceptual lightness of the background.
|
||||
misc->selectionForeground = ColorFix::GetLuminosity(newSelectionColor) < 0.5f ? 0xffffffff : 0xff000000;
|
||||
misc->selectionForeground = ColorFix::GetLightness(newSelectionColor) < 0.5f ? 0xffffffff : 0xff000000;
|
||||
|
||||
// We copied the selection colors into _p during StartPaint, which happened just before PrepareRenderInfo
|
||||
// This keeps their generations in sync.
|
||||
|
||||
@ -209,7 +209,14 @@ COLORREF ColorFix::GetPerceivableColor(COLORREF color, COLORREF reference, float
|
||||
return linearToColorref(oklab::oklab_to_linear_srgb(colorOklab)) | (color & 0xff000000);
|
||||
}
|
||||
|
||||
float ColorFix::GetLuminosity(COLORREF color) noexcept
|
||||
COLORREF ColorFix::AdjustLightness(COLORREF color, float delta) noexcept
|
||||
{
|
||||
auto lab = oklab::linear_srgb_to_oklab(colorrefToLinear(color));
|
||||
lab.l = saturate(lab.l + delta);
|
||||
return linearToColorref(oklab::oklab_to_linear_srgb(lab)) | (color & 0xff000000);
|
||||
}
|
||||
|
||||
float ColorFix::GetLightness(COLORREF color) noexcept
|
||||
{
|
||||
return oklab::linear_srgb_to_oklab(colorrefToLinear(color)).l;
|
||||
}
|
||||
|
||||
@ -10,5 +10,6 @@
|
||||
namespace ColorFix
|
||||
{
|
||||
COLORREF GetPerceivableColor(COLORREF color, COLORREF reference, float minSquaredDistance) noexcept;
|
||||
float GetLuminosity(COLORREF color) noexcept;
|
||||
COLORREF AdjustLightness(COLORREF color, float delta) noexcept;
|
||||
float GetLightness(COLORREF color) noexcept;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user