Compare commits

...

11 Commits

Author SHA1 Message Date
Mike Griese
0e2f3edfa1 Use the actual Terminal color to colorize the titlebar 2019-12-13 14:45:01 -06:00
Mike Griese
798c60a4ad Update the titlebar color during runtime 2019-12-13 11:56:42 -06:00
Mike Griese
8452d29b7b Revert "This sorta worked, but I hate it"
This reverts commit 8524f5f980.
2019-12-13 10:02:16 -06:00
Mike Griese
8524f5f980 This sorta worked, but I hate it
the caption buttons don't shrink in size, so the tab end up just weirdly floating there. I'll gonna move past this for now.
2019-12-13 10:01:36 -06:00
Mike Griese
72145e1dd6 add a XAML resource for PaneBorderWidth 2019-12-13 09:15:09 -06:00
Mike Griese
79c3f5c00c This makes the pane borders configurable via XAML resources 2019-12-13 09:05:34 -06:00
Mike Griese
c1c22fc07e Merge branch 'dev/migrie/f/3061-pane-accent-color' into dev/migrie/f/3327-xaml-theming-proto
# Conflicts:
#	src/cascadia/TerminalApp/CascadiaSettings.cpp
#	src/cascadia/TerminalApp/Pane.cpp
2019-12-13 08:25:36 -06:00
Mike Griese
a79d0d902c This does the thing with the accent color 2019-12-13 08:19:08 -06:00
Mike Griese
de92e5369d Hey look the TermControl needs to depend on the UIA renderer 2019-12-13 08:06:34 -06:00
Mike Griese
0fce304676 This works for some basic tab theming 2019-12-13 07:46:33 -06:00
Mike Griese
eb87e62d1c Enable changing the color of the active pane border 2019-11-27 12:22:48 -06:00
23 changed files with 407 additions and 33 deletions

View File

@@ -176,6 +176,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalControl", "src\casc
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
{1CF55140-EF6A-4736-A403-957E4F7430BB} = {1CF55140-EF6A-4736-A403-957E4F7430BB}
{48D21369-3D7B-4431-9967-24E81292CF63} = {48D21369-3D7B-4431-9967-24E81292CF63}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\cascadia\WindowsTerminal\WindowsTerminal.vcxproj", "{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}"

View File

@@ -256,6 +256,17 @@
"additionalProperties": true,
"description": "Properties that affect the entire window, regardless of the profile settings.",
"properties": {
"activePaneBorderColor": {
"default": "accent",
"oneOf": [
{"$ref": "#/definitions/Color"},
{"type": "string", "pattern": "accent" }
],
"description": "The color to use for the active pane border. Should be null, \"accent\", or a color in format \"#RRGGBB\"",
"type": ["string", "null"]
},
"alwaysShowTabs": {
"default": true,
"description": "When set to true, tabs are always displayed. When set to false and showTabsInTitlebar is set to false, tabs only appear after opening a new tab.",

View File

@@ -52,6 +52,8 @@ the MIT License. See LICENSE in the project root for license information. -->
<!-- Suppress all padding except left around the tabs. The TabView looks far better like this. -->
<Thickness x:Key="TabViewHeaderPadding">8,0,0,0</Thickness>
<x:Double x:Key="PaneBorderWidth">2.0</x:Double>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<!-- Define resources for Dark mode here -->
@@ -61,12 +63,20 @@ the MIT License. See LICENSE in the project root for license information. -->
sample the pixels out of it, or premultiply the alpha into the background. For obvious reasons, we've chosen
the latter. -->
<SolidColorBrush x:Key="TabViewBackground" Color="#FF333333" />
<StaticResource x:Key="PaneBorderBrush" ResourceKey="TabViewBackground" />
<SolidColorBrush x:Key="ActivePaneBorderBrush" Color="{ThemeResource SystemAccentColor}" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<!-- Define resources for Light mode here -->
<!-- See note about premultiplication above. -->
<SolidColorBrush x:Key="TabViewBackground" Color="#FFCCCCCC" />
<StaticResource x:Key="PaneBorderBrush" ResourceKey="TabViewBackground" />
<SolidColorBrush x:Key="ActivePaneBorderBrush" Color="{ThemeResource SystemAccentColor}" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

View File

@@ -27,10 +27,11 @@ namespace winrt
// !!! IMPORTANT !!!
// Make sure that these keys are in the same order as the
// SettingsLoadWarnings/Errors enum is!
static const std::array<std::wstring_view, 3> settingsLoadWarningsLabels {
static const std::array<std::wstring_view, 4> settingsLoadWarningsLabels {
USES_RESOURCE(L"MissingDefaultProfileText"),
USES_RESOURCE(L"DuplicateProfileText"),
USES_RESOURCE(L"UnknownColorSchemeText")
USES_RESOURCE(L"UnknownColorSchemeText"),
USES_RESOURCE(L"BadActivePaneBorderColorValueText")
};
static const std::array<std::wstring_view, 2> settingsLoadErrorsLabels {
USES_RESOURCE(L"NoProfilesText"),

View File

@@ -148,6 +148,17 @@ GlobalAppSettings& CascadiaSettings::GlobalSettings()
return _globals;
}
// Method Description:
// - Get a const reference to our global settings
// Arguments:
// - <none>
// Return Value:
// - a reference to our global settings
const GlobalAppSettings& CascadiaSettings::GlobalSettings() const
{
return _globals;
}
// Method Description:
// - Gets our list of warnings we found during loading. These are things that we
// knew were bad when we called `_ValidateSettings` last.
@@ -205,6 +216,9 @@ void CascadiaSettings::_ValidateSettings()
// TODO:GH#3522 With variable args to keybindings, it's possible that a user
// set a keybinding without all the required args for an action. Display a
// warning if an action didn't have a required arg.
// Validate that pane colors are either a color or "accent"
_ValidatePaneAccentColorValues();
}
// Method Description:
@@ -589,3 +603,39 @@ GUID CascadiaSettings::_GetProfileForIndex(std::optional<int> index) const
}
return profileGuid;
}
// Method Description:
// - Ensures that the value set for "activePaneBorderColor" is a reasonable
// value. This should be one of:
// - `null`: to clear the active pane border color
// - `"accent"`:
// - a color string in format `"#RRGGBB"`
// - If the color is not set to one of these values, this will reset the value
// to null and display a warning.
// Arguments:
// - <none>
// Return Value:
// - <none>
// - Appends a SettingsLoadWarnings::BadActivePaneBorderColorValue to our list
// of warnings if the color is not an appropriate value.
void CascadiaSettings::_ValidatePaneAccentColorValues()
{
// The only real case we need to check here is if the pane border color was
// set, but it wasn't set to "accent", nor was it otherwise able to be
// parsed.
if (_globals.HasPaneFocusBorderColor() && !_globals.IsPaneFocusColorAccentColor())
{
// Try parsing the color. If we fail to parse the color, then add the
// warning. Otherwise, the setting is good to go.
try
{
const auto color = _globals.GetPaneFocusColor();
color;
}
catch (...)
{
_warnings.push_back(::TerminalApp::SettingsLoadWarnings::BadActivePaneBorderColorValue);
_globals.SetPaneFocusColor(std::nullopt);
}
}
}

View File

@@ -56,6 +56,7 @@ public:
winrt::Microsoft::Terminal::Settings::TerminalSettings BuildSettings(GUID profileGuid) const;
GlobalAppSettings& GlobalSettings();
const GlobalAppSettings& GlobalSettings() const;
std::basic_string_view<Profile> GetProfiles() const noexcept;
@@ -114,6 +115,7 @@ private:
void _ReorderProfilesToMatchUserSettingsOrder();
void _RemoveHiddenProfiles();
void _ValidateAllSchemesExist();
void _ValidatePaneAccentColorValues();
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::ProfileTests;

View File

@@ -33,6 +33,8 @@ static constexpr std::wstring_view MaximizedLaunchModeValue{ L"maximized" };
static constexpr std::wstring_view LightThemeValue{ L"light" };
static constexpr std::wstring_view DarkThemeValue{ L"dark" };
static constexpr std::wstring_view SystemThemeValue{ L"system" };
static constexpr std::string_view ActivePaneBorderColorKey{ "activePaneBorderColor" };
static constexpr std::wstring_view UseAccentColorValue{ L"accent" };
GlobalAppSettings::GlobalAppSettings() :
_keybindings{ winrt::make_self<winrt::TerminalApp::implementation::AppKeyBindings>() },
@@ -277,6 +279,8 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
{
_keybindings->LayerJson(keybindings);
}
JsonUtils::GetOptionalString(json, ActivePaneBorderColorKey, _activePaneBorderColor);
}
// Method Description:
@@ -442,3 +446,54 @@ void GlobalAppSettings::AddColorScheme(ColorScheme scheme)
std::wstring name{ scheme.GetName() };
_colorSchemes[name] = std::move(scheme);
}
// Method Description:
// - Returns true if the user has set the pane border to an actual value. If
// they've set the active pane border color to `null`, then this will return
// false.
// Arguments:
// - <none>
// Return Value:
// - true iff there's a active pane border color set.
bool GlobalAppSettings::HasPaneFocusBorderColor() const noexcept
{
return _activePaneBorderColor.has_value();
}
// Method Description:
// - Returns true if the user has set the pane border to the system accent
// color, using the value "accent".
// Arguments:
// - <none>
// Return Value:
// - true iff the active pane border color is set to "accent"
bool GlobalAppSettings::IsPaneFocusColorAccentColor() const noexcept
{
return HasPaneFocusBorderColor() && _activePaneBorderColor.value() == UseAccentColorValue;
}
// Method Description:
// - Retrieve the color the user has set the pane border to. If the user has set
// the color to "accent", or set the color to "null", or any other invalid
// string, this method will throw an exception.
// Arguments:
// - <none>
// Return Value:
// - the parsed color the user has set the active pane border to.
COLORREF GlobalAppSettings::GetPaneFocusColor() const
{
return ::Microsoft::Console::Utils::ColorFromHexString(_activePaneBorderColor.value());
}
// Method Description:
// - Sets the active pane border value. Used by
// CascadiaSettings::_ValidatePaneAccentColorValues to reset the active pane
// border color, in case the color was set to something invalid.
// Arguments:
// - newValue: the new string to use for this setting, or nullopt to clear the value.
// Return Value:
// - <none>
void GlobalAppSettings::SetPaneFocusColor(std::optional<std::wstring> newValue)
{
_activePaneBorderColor = newValue;
}

View File

@@ -76,6 +76,11 @@ public:
void ApplyToSettings(winrt::Microsoft::Terminal::Settings::TerminalSettings& settings) const noexcept;
bool HasPaneFocusBorderColor() const noexcept;
bool IsPaneFocusColorAccentColor() const noexcept;
COLORREF GetPaneFocusColor() const;
void SetPaneFocusColor(std::optional<std::wstring> newValue);
private:
GUID _defaultProfile;
winrt::com_ptr<winrt::TerminalApp::implementation::AppKeyBindings> _keybindings;
@@ -96,8 +101,8 @@ private:
std::wstring _wordDelimiters;
bool _copyOnSelect;
winrt::Windows::UI::Xaml::ElementTheme _requestedTheme;
winrt::TerminalApp::LaunchMode _launchMode;
std::optional<std::wstring> _activePaneBorderColor{ std::nullopt };
static winrt::Windows::UI::Xaml::ElementTheme _ParseTheme(const std::wstring& themeString) noexcept;
static std::wstring_view _SerializeTheme(const winrt::Windows::UI::Xaml::ElementTheme theme) noexcept;

View File

@@ -5,6 +5,7 @@
#include "Pane.h"
#include "Profile.h"
#include "CascadiaSettings.h"
#include "../../WinRTUtils/inc/Utils.h"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI;
@@ -17,8 +18,8 @@ using namespace winrt::Microsoft::Terminal::TerminalConnection;
using namespace winrt::TerminalApp;
using namespace TerminalApp;
static const int PaneBorderSize = 2;
static const int CombinedPaneBorderSize = 2 * PaneBorderSize;
static int PaneBorderSize = 2;
static int CombinedPaneBorderSize = 2 * PaneBorderSize;
static const float Half = 0.50f;
winrt::Windows::UI::Xaml::Media::SolidColorBrush Pane::s_focusedBorderBrush = { nullptr };
@@ -543,6 +544,13 @@ void Pane::UpdateSettings(const TerminalSettings& settings, const GUID& profile)
{
_control.UpdateSettings(settings);
}
_root.Dispatcher().RunAsync(CoreDispatcherPriority::Low, [this]() {
// Call _SetupResources to potentially reload the active pane brush,
// and UpdateVisuals to apply the brush
_SetupResources();
UpdateVisuals();
});
}
}
@@ -1109,36 +1117,61 @@ void Pane::_ControlGotFocusHandler(winrt::Windows::Foundation::IInspectable cons
void Pane::_SetupResources()
{
const auto res = Application::Current().Resources();
const auto accentColorKey = winrt::box_value(L"SystemAccentColor");
if (res.HasKey(accentColorKey))
{
const auto colorFromResources = res.Lookup(accentColorKey);
// If SystemAccentColor is _not_ a Color for some reason, use
// Transparent as the color, so we don't do this process again on
// the next pane (by leaving s_focusedBorderBrush nullptr)
auto actualColor = winrt::unbox_value_or<Color>(colorFromResources, Colors::Black());
s_focusedBorderBrush = SolidColorBrush(actualColor);
}
else
{
// DON'T use Transparent here - if it's "Transparent", then it won't
// be able to hittest for clicks, and then clicking on the border
// will eat focus.
s_focusedBorderBrush = SolidColorBrush{ Colors::Black() };
//TODO: Does this hot-reload?
// First setup the pane border TabViewBackground color
const auto tabViewBackgroundKey = winrt::box_value(L"PaneBorderBrush");
if (res.HasKey(tabViewBackgroundKey))
{
winrt::Windows::Foundation::IInspectable obj = res.Lookup(tabViewBackgroundKey);
s_unfocusedBorderBrush = obj.try_as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
}
else
{
// DON'T use Transparent here - if it's "Transparent", then it won't
// be able to hittest for clicks, and then clicking on the border
// will eat focus.
s_unfocusedBorderBrush = SolidColorBrush{ Colors::Black() };
}
}
const auto tabViewBackgroundKey = winrt::box_value(L"TabViewBackground");
if (res.HasKey(tabViewBackgroundKey))
{
winrt::Windows::Foundation::IInspectable obj = res.Lookup(tabViewBackgroundKey);
s_unfocusedBorderBrush = obj.try_as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
const auto activeBorderKey = winrt::box_value(L"ActivePaneBorderBrush");
if (res.HasKey(activeBorderKey))
{
winrt::Windows::Foundation::IInspectable obj = res.Lookup(activeBorderKey);
s_focusedBorderBrush = obj.try_as<winrt::Windows::UI::Xaml::Media::SolidColorBrush>();
}
else
{
// DON'T use Transparent here - if it's "Transparent", then it won't
// be able to hittest for clicks, and then clicking on the border
// will eat focus.
s_focusedBorderBrush = SolidColorBrush{ Colors::Black() };
}
}
else
{
// DON'T use Transparent here - if it's "Transparent", then it won't
// be able to hittest for clicks, and then clicking on the border
// will eat focus.
s_unfocusedBorderBrush = SolidColorBrush{ Colors::Black() };
// TODO: This needs to be able to hot-reload, by changing all the
// existing borders to the current width
// TODO: we shouldn't do this once per-pane on a reload, we should do it
// once at the root. maybe use a std::optional<> to hold the value,
// clear it on reload, and only set it when it's unset
const auto activeBorderKey = winrt::box_value(L"PaneBorderWidth");
if (res.HasKey(activeBorderKey))
{
const auto colorFromResources = res.Lookup(activeBorderKey);
auto actualColor = winrt::unbox_value_or<double>(colorFromResources, 2.0);
PaneBorderSize = gsl::narrow_cast<int>(actualColor);
CombinedPaneBorderSize = 2 * PaneBorderSize;
}
else
{
}
}
}

View File

@@ -131,6 +131,10 @@
</data>
<data name="UnknownColorSchemeText" xml:space="preserve">
<value>Found a profile with an invalid "colorScheme". Defaulting that profile to the default colors. Make sure that when setting a "colorScheme", the value matches the "name" of a color scheme in the "schemes" list.
</value>
</data>
<data name="BadActivePaneBorderColorValueText" xml:space="preserve">
<value>Found an invalid value for "activePaneBorderColor". This must either be set to null, "accent", or a hex color code in format "#RRGGBB". Defaulting to no color.
</value>
</data>
<data name="NoProfilesText" xml:space="preserve">

View File

@@ -360,4 +360,9 @@ void Tab::_AttachEventHandlersToPane(std::shared_ptr<Pane> pane)
});
}
winrt::Windows::UI::Color Tab::GetActiveTerminalBackground()
{
return _activePane->GetTerminalControl().BackgroundColor();
}
DEFINE_EVENT(Tab, ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);

View File

@@ -37,6 +37,8 @@ public:
void ClosePane();
winrt::Windows::UI::Color GetActiveTerminalBackground();
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
DECLARE_EVENT(ActivePaneChanged, _ActivePaneChangedHandlers, winrt::delegate<>);

View File

@@ -6,6 +6,7 @@
#include "ActionAndArgs.h"
#include "Utils.h"
#include "../../types/inc/utils.hpp"
#include "../../WinRTUtils/inc/Utils.h"
#include <LibraryResources.h>
@@ -17,8 +18,12 @@
#include "TabRowControl.h"
using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Media;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::System;
using namespace winrt::Windows::ApplicationModel::DataTransfer;
using namespace winrt::Windows::UI::Text;
@@ -55,6 +60,93 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::Create()
{
auto res = ::winrt::Windows::UI::Xaml::Application::Current().Resources();
{
res.Insert(winrt::box_value(L"PaneBorderWidth"), winrt::box_value(8.0));
}
{
Media::SolidColorBrush myBrush{};
myBrush.Color(winrt::Windows::UI::Colors::Red());
res.Insert(winrt::box_value(L"PaneBorderBrush"), myBrush);
}
{
// So this works to apply theming to _all_ tab items
Media::SolidColorBrush myBrush{};
const auto accentColorKey = winrt::box_value(L"SystemAccentColor");
if (res.HasKey(accentColorKey))
{
const auto colorFromResources = res.Lookup(accentColorKey);
// If SystemAccentColor is _not_ a Color for some reason, use
// Transparent as the color, so we don't do this process again on
// the next pane (by leaving s_focusedBorderBrush nullptr)
auto actualColor = winrt::unbox_value_or<winrt::Windows::UI::Color>(colorFromResources, winrt::Windows::UI::Colors::Black());
myBrush.Color(actualColor);
}
else
{
myBrush.Color(winrt::Windows::UI::Colors::Red());
}
// These two will colorize the tabs:
// res.Insert(winrt::box_value(L"TabViewItemHeaderBackground"), myBrush);
// res.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), myBrush);
// This will colorize the background (the titlebar)
res.Insert(winrt::box_value(L"TabViewBackground"), myBrush);
// When the color picker sets the color of a tab, it will only set
// the color for that tab, and clearing the color will revert to the
// one we set here.
}
{
// Now try and set the pane border color.
// - If it's null, we'll use the TabViewBackground color.
// - if it's "accent", we'll use the accent color
// - if it's "#rrbbgg", we'll use the given color
Media::SolidColorBrush activeBorderBrush{};
const auto& settings = CascadiaSettings::GetCurrentAppSettings();
const auto& globals = settings.GlobalSettings();
if (!globals.HasPaneFocusBorderColor())
{
// do nothing
// Make sure it's the unfocused border brush?
}
else
{
if (globals.IsPaneFocusColorAccentColor())
{
// Use the accent color for the pane border
const auto accentColorKey = winrt::box_value(L"SystemAccentColor");
if (res.HasKey(accentColorKey))
{
const auto colorFromResources = res.Lookup(accentColorKey);
// If SystemAccentColor is _not_ a Color for some reason, use
// Transparent as the color, so we don't do this process again on
// the next pane (by leaving s_focusedBorderBrush nullptr)
auto actualColor = winrt::unbox_value_or<Color>(colorFromResources, Colors::Black());
activeBorderBrush.Color(actualColor);
}
else
{
// // DON'T use Transparent here - see earlier comment for why
// s_focusedBorderBrush = s_unfocusedBorderBrush;
}
}
else
{
// Create a brush for the color the user specified
const COLORREF focusColor = globals.GetPaneFocusColor();
activeBorderBrush.Color(ColorRefToColor(focusColor));
}
res.Insert(winrt::box_value(L"ActivePaneBorderBrush"), activeBorderBrush);
}
}
// Hookup the key bindings
_HookupKeyBindings(_settings->GetKeybindings());
@@ -1284,7 +1376,8 @@ namespace winrt::TerminalApp::implementation
// Arguments:
// - sender: the control that originated this event
// - eventArgs: the event's constituent arguments
void TerminalPage::_OnTabSelectionChanged(const IInspectable& sender, const WUX::Controls::SelectionChangedEventArgs& /*eventArgs*/)
void TerminalPage::_OnTabSelectionChanged(const IInspectable& sender,
const WUX::Controls::SelectionChangedEventArgs& /*eventArgs*/)
{
if (!_rearranging)
{
@@ -1308,6 +1401,35 @@ namespace winrt::TerminalApp::implementation
tab->SetFocused(true);
_titleChangeHandlers(*this, Title());
// DANGER: Make sure to _modify_ the current brush. Don't
// insert a new one. If we modify the current brush, then
// the TitlebarControl will auto-update, because the value
// of it's brush's color changed. If we Insert instead, then
// the titlebar's background will still be the old,
// unmodified brush.
auto res = Application::Current().Resources();
// This will colorize the background (the titlebar)
auto obj = res.Lookup(winrt::box_value(L"TabViewBackground"));
auto tvbBrush = obj.try_as<SolidColorBrush>();
tvbBrush.Color(tab->GetActiveTerminalBackground());
// Don't do the tab here -
// res.Insert(winrt::box_value(L"TabViewItemHeaderBackground"), myBrush);
// res.Insert(winrt::box_value(L"TabViewBackground"), myBrush);
// _tabView.Background(myBrush);
// The tab will want to update it's color on it's own
// IF tabRow.background == "terminalBackground":
// The TerminalPage will listen for the
//
// * active tab changing
// * The active pane changing
//
// And use both of those as a chance to query the acctive
// tab's active pane's terminal's BG color, to set
// TabViewBackground.
}
CATCH_LOG();
}

View File

@@ -31,12 +31,15 @@ namespace winrt::TerminalApp::implementation
void CloseWindow();
// Windows::UI::Color TitlebarBackgroundColor();
// -------------------------------- WinRT Events ---------------------------------
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangeHandlers, winrt::Windows::Foundation::IInspectable, winrt::hstring);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(LastTabClosed, _lastTabClosedHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTitleBarContent, _setTitleBarContentHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::UIElement);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(ShowDialog, _showDialogHandlers, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::Controls::ContentDialog);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(ToggleFullscreen, _toggleFullscreenHandlers, winrt::Windows::Foundation::IInspectable, winrt::TerminalApp::ToggleFullscreenEventArgs);
// TYPED_EVENT(TitlebarBackgroundColorChanged, Windows::Foundation::IInspectable, Windows::UI::Xaml::RoutedEventArgs);
private:
// If you add controls here, but forget to null them either here or in

View File

@@ -15,5 +15,9 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.Controls.ContentDialog> ShowDialog;
event Windows.Foundation.TypedEventHandler<Object, ToggleFullscreenEventArgs> ToggleFullscreen;
// // TODO: this should probably just be a dependency property
// event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.RoutedEventArgs> TitlebarBackgroundColorChanged;
// Windows.UI.Color TitlebarBackgroundColor { get; };
}
}

View File

@@ -23,7 +23,8 @@ namespace TerminalApp
{
MissingDefaultProfile = 0,
DuplicateProfile = 1,
UnknownColorScheme = 2
UnknownColorScheme = 2,
BadActivePaneBorderColorValue = 3
};
// SettingsLoadWarnings are scenarios where the settings had invalid state

View File

@@ -1,6 +1,7 @@
// THIS IS AN AUTO-GENERATED FILE! Changes to this file will be ignored.
{
"alwaysShowTabs": true,
"activePaneBorderColor": "accent",
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"initialCols": 120,
"initialRows": 30,

View File

@@ -356,6 +356,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
}
winrt::Windows::UI::Color TermControl::BackgroundColor() const
{
return ColorRefToColor(_settings.DefaultBackground());
}
// Method Description:
// - Style the background of the control with the provided background color
// Arguments:
@@ -391,6 +396,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// Set the default background as transparent to prevent the
// DX layer from overwriting the background image or acrylic effect
_settings.DefaultBackground(ARGB(0, R, G, B));
_BackgroundColorChangedHandlers(*control, nullptr);
}
});
}

View File

@@ -83,6 +83,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
const Windows::UI::Xaml::Thickness GetPadding() const;
TerminalConnection::ConnectionState ConnectionState() const;
winrt::Windows::UI::Color BackgroundColor() const;
static Windows::Foundation::Point GetProposedDimensions(Microsoft::Terminal::Settings::IControlSettings const& settings, const uint32_t dpi);
@@ -95,6 +96,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CopyToClipboard, _clipboardCopyHandlers, TerminalControl::TermControl, TerminalControl::CopyToClipboardEventArgs);
TYPED_EVENT(ConnectionStateChanged, TerminalControl::TermControl, IInspectable);
TYPED_EVENT(BackgroundColorChanged, TerminalControl::TermControl, IInspectable);
// clang-format on
private:

View File

@@ -52,5 +52,8 @@ namespace Microsoft.Terminal.TerminalControl
void AdjustFontSize(Int32 fontSizeDelta);
void ResetFontSize();
event Windows.Foundation.TypedEventHandler<TermControl, IInspectable> BackgroundColorChanged;
Windows.UI.Color BackgroundColor { get; };
}
}

View File

@@ -76,6 +76,20 @@ void NonClientIslandWindow::Initialize()
_rootGrid.Children().Append(_titlebar);
Controls::Grid::SetRow(_titlebar, 0);
// Add a _pair_ of handlers here: When the titlebar's background brush
// changes, add an event handler that listens for when that brush's color
// changes. When that coor changes, invalidate the window, so the titlebar
// will get an updated color.
auto panel = _titlebar.try_as<Controls::Panel>();
panel.RegisterPropertyChangedCallback(panel.BackgroundProperty(), [this](auto&&, auto&&) {
auto bg = _titlebar.Background();
auto bgBrush = bg.try_as<Media::SolidColorBrush>();
bgBrush.RegisterPropertyChangedCallback(bgBrush.ColorProperty(), [this](auto&&, auto&&) {
auto hwnd = GetHandle();
InvalidateRect(hwnd, NULL, TRUE);
});
});
}
// Method Description:
@@ -520,6 +534,7 @@ void NonClientIslandWindow::_UpdateFrameMargins() const noexcept
{
// Create brush for titlebar color.
_backgroundBrush = wil::unique_hbrush(CreateSolidBrush(color));
_backgroundBrushColor = color;
}
// To hide the original title bar, we have to paint on top of it with

View File

@@ -47,7 +47,8 @@ namespace Microsoft::Console::Utils
GUID CreateGuid();
std::string ColorToHexString(const COLORREF color);
COLORREF ColorFromHexString(const std::string wstr);
COLORREF ColorFromHexString(const std::string& wstr);
COLORREF ColorFromHexString(const std::wstring& wstr);
void InitializeCampbellColorTable(const gsl::span<COLORREF> table);
void InitializeCampbellColorTableForConhost(const gsl::span<COLORREF> table);

View File

@@ -70,7 +70,7 @@ std::string Utils::ColorToHexString(const COLORREF color)
// Return Value:
// - A COLORREF if the string could successfully be parsed. If the string is not
// the correct format, throws E_INVALIDARG
COLORREF Utils::ColorFromHexString(const std::string str)
COLORREF Utils::ColorFromHexString(const std::string& str)
{
THROW_HR_IF(E_INVALIDARG, str.size() != 7 && str.size() != 4);
THROW_HR_IF(E_INVALIDARG, str.at(0) != '#');
@@ -99,6 +99,42 @@ COLORREF Utils::ColorFromHexString(const std::string str)
return RGB(r, g, b);
}
// Function Description:
// - Parses a color from a string. The string should be in the format "#RRGGBB" or "#RGB"
// Arguments:
// - str: a string representation of the COLORREF to parse
// Return Value:
// - A COLORREF if the string could successfully be parsed. If the string is not
// the correct format, throws E_INVALIDARG
COLORREF Utils::ColorFromHexString(const std::wstring& str)
{
THROW_HR_IF(E_INVALIDARG, str.size() != 7 && str.size() != 4);
THROW_HR_IF(E_INVALIDARG, str.at(0) != '#');
std::wstring rStr;
std::wstring gStr;
std::wstring bStr;
if (str.size() == 4)
{
rStr = std::wstring(2, str.at(1));
gStr = std::wstring(2, str.at(2));
bStr = std::wstring(2, str.at(3));
}
else
{
rStr = std::wstring(&str.at(1), 2);
gStr = std::wstring(&str.at(3), 2);
bStr = std::wstring(&str.at(5), 2);
}
const BYTE r = gsl::narrow_cast<BYTE>(std::stoul(rStr, nullptr, 16));
const BYTE g = gsl::narrow_cast<BYTE>(std::stoul(gStr, nullptr, 16));
const BYTE b = gsl::narrow_cast<BYTE>(std::stoul(bStr, nullptr, 16));
return RGB(r, g, b);
}
// Routine Description:
// - Shorthand check if a handle value is null or invalid.
// Arguments: