terminal/src/cascadia/TerminalSettingsModel/ColorScheme.h
Dustin L. Howett 295fa38295
Introduce MS.Term.Core.Color to replace W.U.Color for Core/Control/TSM (#9658)
This pull request introduces Microsoft.Terminal.Core.Color as an
alternative to both Windows.UI.Color and uint32_t/COLORREF in the
TerminalCore, ...Control, ...SettingsModel and ...SettingsEditor layers.

M.T.C.Color is trivially convertible to/from til::color and therefore
to/from COLORREF, W.U.Color, and any other color representation we might
need².

I've replaced almost every use of W.U.Color and uint32_t-as-color in the
above layers, with minor exception¹.

The need for this work is twofold.

First: We cannot bear a dependency from TerminalCore (which should,
on paper, be Windows 7 compatible) on Windows.UI or any other WinRT
namespace.

This work removes one big dependency on Windows.UI, but it does not go
all the way.

Second: TerminalCore chose to communicate mostly in packed uint32s
(COLORREF), which was inherently lossy and dangerous.

¹ The UI layers (TerminalControl, TerminalApp) still use
Windows.UI.Color as they are intimately connected to the UWP XAML UI.

² In the future, we might even be able to *use* the alpha channel...

## PR Checklist
* [x] I ran into the need for this when I introduced cursor inversion
* [X] Fixes a longstanding itch

## Validation Steps Performed
Built and ran all tests for the impacted layers, even the local ones!
2021-03-30 20:15:49 +00:00

88 lines
3.2 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- ColorScheme.hpp
Abstract:
- A color scheme is a single set of colors to use as the terminal colors. These
schemes are named, and can be used to quickly change all the colors of the
terminal to another scheme.
Author(s):
- Mike Griese - March 2019
--*/
#pragma once
#include "../../inc/conattrs.hpp"
#include "inc/cppwinrt_utils.h"
#include "ColorScheme.g.h"
// fwdecl unittest classes
namespace SettingsModelLocalTests
{
class SettingsTests;
class ColorSchemeTests;
};
// Use this macro to quick implement both the getter and setter for a color property.
// This should only be used for color types where there's no logic in the
// getter/setter beyond just accessing/updating the value.
// This takes advantage of til::color
#define WINRT_TERMINAL_COLOR_PROPERTY(name, ...) \
public: \
winrt::Microsoft::Terminal::Core::Color name() const noexcept { return _##name; } \
void name(const winrt::Microsoft::Terminal::Core::Color& value) noexcept { _##name = value; } \
\
private: \
til::color _##name{ __VA_ARGS__ };
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
struct ColorScheme : ColorSchemeT<ColorScheme>
{
public:
ColorScheme();
ColorScheme(hstring name);
ColorScheme(hstring name, til::color defaultFg, til::color defaultBg, til::color cursorColor);
com_ptr<ColorScheme> Copy() const;
hstring ToString()
{
return Name();
}
static com_ptr<ColorScheme> FromJson(const Json::Value& json);
bool ShouldBeLayered(const Json::Value& json) const;
void LayerJson(const Json::Value& json);
Json::Value ToJson() const;
static std::optional<std::wstring> GetNameFromJson(const Json::Value& json);
com_array<winrt::Microsoft::Terminal::Core::Color> Table() const noexcept;
void SetColorTableEntry(uint8_t index, const winrt::Microsoft::Terminal::Core::Color& value) noexcept;
static bool ValidateColorScheme(const Json::Value& scheme);
WINRT_PROPERTY(winrt::hstring, Name);
WINRT_TERMINAL_COLOR_PROPERTY(Foreground); // defined in constructor
WINRT_TERMINAL_COLOR_PROPERTY(Background); // defined in constructor
WINRT_TERMINAL_COLOR_PROPERTY(SelectionBackground); // defined in constructor
WINRT_TERMINAL_COLOR_PROPERTY(CursorColor); // defined in constructor
private:
std::array<til::color, COLOR_TABLE_SIZE> _table;
friend class SettingsModelLocalTests::SettingsTests;
friend class SettingsModelLocalTests::ColorSchemeTests;
};
}
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
{
BASIC_FACTORY(ColorScheme);
}