Skip to content

Commit

Permalink
Implement background image over acrylic or solid color (microsoft#1107)
Browse files Browse the repository at this point in the history
  • Loading branch information
Summon528 authored and mcpiroman committed Jul 23, 2019
1 parent 8a22038 commit 42a5259
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 56 deletions.
89 changes: 33 additions & 56 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
Controls::Grid::SetColumn(swapChainPanel, 0);
Controls::Grid::SetColumn(_scrollBar, 1);

_root = container;
Controls::Grid root{};
Controls::Image bgImageLayer{};
root.Children().Append(bgImageLayer);
root.Children().Append(container);

_root = root;
_bgImageLayer = bgImageLayer;

_swapChainPanel = swapChainPanel;
_controlRoot.Content(_root);

Expand Down Expand Up @@ -193,15 +200,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}

// Method Description:
// - Set up the brush used to display the control's background.
// - Set up each layer's brush used to display the control's background.
// - Respects the settings for acrylic, background image and opacity from
// _settings.
// * Prioritizes the acrylic background if chosen, respecting acrylicOpacity
// from _settings.
// * If acrylic is not enabled and a backgroundImage is present, it is used,
// respecting the opacity and stretch mode settings from _settings.
// * Falls back to a solid color background from _settings if acrylic is not
// enabled and no background image is present.
// * If acrylic is not enabled, setup a solid color background, otherwise
// use bgcolor as acrylic's tint
// - Avoids image flickering and acrylic brush redraw if settings are changed
// but the appropriate brush is still in place.
// - Does not apply background color outside of acrylic mode;
Expand Down Expand Up @@ -246,23 +249,20 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_root.Background(acrylic);
}
}
else if (!_settings.BackgroundImage().empty())
else
{
Windows::Foundation::Uri imageUri{ _settings.BackgroundImage() };

// Check if the existing brush is an image brush, and if not
// construct a new one
auto brush = _root.Background().try_as<Media::ImageBrush>();
Media::SolidColorBrush solidColor{};
_root.Background(solidColor);
}

if (brush == nullptr)
{
brush = Media::ImageBrush{};
}
if (!_settings.BackgroundImage().empty())
{
Windows::Foundation::Uri imageUri{ _settings.BackgroundImage() };

// Check if the image brush is already pointing to the image
// in the modified settings; if it isn't (or isn't there),
// set a new image source for the brush
auto imageSource = brush.ImageSource().try_as<Media::Imaging::BitmapImage>();
auto imageSource = _bgImageLayer.Source().try_as<Media::Imaging::BitmapImage>();

if (imageSource == nullptr ||
imageSource.UriSource() == nullptr ||
Expand All @@ -273,23 +273,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// may well be both large and somewhere out on the
// internet.
Media::Imaging::BitmapImage image(imageUri);
brush.ImageSource(image);
_bgImageLayer.Source(image);
_bgImageLayer.HorizontalAlignment(HorizontalAlignment::Center);
_bgImageLayer.VerticalAlignment(VerticalAlignment::Center);
}

// Apply stretch and opacity settings
brush.Stretch(_settings.BackgroundImageStretchMode());
brush.Opacity(_settings.BackgroundImageOpacity());

// Apply brush if it isn't already there
if (_root.Background() != brush)
{
_root.Background(brush);
}
_bgImageLayer.Stretch(_settings.BackgroundImageStretchMode());
_bgImageLayer.Opacity(_settings.BackgroundImageOpacity());
}
else
{
Media::SolidColorBrush solidColor{};
_root.Background(solidColor);
_bgImageLayer.Source(nullptr);
}
}

Expand All @@ -312,37 +307,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
bgColor.B = B;
bgColor.A = 255;

if (_settings.UseAcrylic())
if (auto acrylic = _root.Background().try_as<Media::AcrylicBrush>())
{
if (auto acrylic = _root.Background().try_as<Media::AcrylicBrush>())
{
acrylic.FallbackColor(bgColor);
acrylic.TintColor(bgColor);
}

// If we're acrylic, we want to make sure that the default BG color
// is transparent, so we can see the acrylic effect on text with the
// default BG color.
_settings.DefaultBackground(ARGB(0, R, G, B));
acrylic.FallbackColor(bgColor);
acrylic.TintColor(bgColor);
}
else if (!_settings.BackgroundImage().empty())
else if (auto solidColor = _root.Background().try_as<Media::SolidColorBrush>())
{
// This currently applies no changes to the image background
// brush itself.

// Set the default background as transparent to prevent the
// DX layer from overwriting the background image
_settings.DefaultBackground(ARGB(0, R, G, B));
solidColor.Color(bgColor);
}
else
{
if (auto solidColor = _root.Background().try_as<Media::SolidColorBrush>())
{
solidColor.Color(bgColor);
}

_settings.DefaultBackground(RGB(R, G, B));
}
// 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));
});
}

Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation

Windows::UI::Xaml::Controls::UserControl _controlRoot;
Windows::UI::Xaml::Controls::Grid _root;
Windows::UI::Xaml::Controls::Image _bgImageLayer;
Windows::UI::Xaml::Controls::SwapChainPanel _swapChainPanel;
Windows::UI::Xaml::Controls::Primitives::ScrollBar _scrollBar;
event_token _connectionOutputEventToken;
Expand Down

0 comments on commit 42a5259

Please sign in to comment.