Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement background image over acrylic or solid color #1107

Merged
merged 7 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 33 additions & 56 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,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 @@ -190,15 +197,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 @@ -243,23 +246,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 @@ -270,23 +270,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 @@ -309,37 +304,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 @@ -70,6 +70,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