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

Background image support #853

Merged
merged 12 commits into from
May 29, 2019
114 changes: 112 additions & 2 deletions src/cascadia/TerminalApp/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ using namespace winrt::TerminalApp;
using namespace winrt::Windows::Data::Json;
using namespace ::Microsoft::Console;


static constexpr std::wstring_view NAME_KEY{ L"name" };
static constexpr std::wstring_view GUID_KEY{ L"guid" };
static constexpr std::wstring_view COLORSCHEME_KEY{ L"colorscheme" };
Expand All @@ -36,6 +35,9 @@ static constexpr std::wstring_view CLOSEONEXIT_KEY{ L"closeOnExit" };
static constexpr std::wstring_view PADDING_KEY{ L"padding" };
static constexpr std::wstring_view STARTINGDIRECTORY_KEY{ L"startingDirectory" };
static constexpr std::wstring_view ICON_KEY{ L"icon" };
static constexpr std::wstring_view BACKGROUNDIMAGE_KEY{ L"backgroundImage" };
static constexpr std::wstring_view BACKGROUNDIMAGEOPACITY_KEY{ L"backgroundImageOpacity" };
static constexpr std::wstring_view BACKGROUNDIMAGESTRETCHMODE_KEY{ L"backgroundImageStretchMode" };

// Possible values for Scrollbar state
static constexpr std::wstring_view ALWAYS_VISIBLE{ L"visible" };
Expand All @@ -48,6 +50,12 @@ static constexpr std::wstring_view CURSORSHAPE_UNDERSCORE{ L"underscore" };
static constexpr std::wstring_view CURSORSHAPE_FILLEDBOX{ L"filledBox" };
static constexpr std::wstring_view CURSORSHAPE_EMPTYBOX{ L"emptyBox" };

// Possible values for Image Stretch Mode
static constexpr std::wstring_view IMAGESTRETCHMODE_NONE{ L"none" };
static constexpr std::wstring_view IMAGESTRETCHMODE_FILL{ L"fill" };
static constexpr std::wstring_view IMAGESTRETCHMODE_UNIFORM{ L"uniform" };
static constexpr std::wstring_view IMAGESTRETCHMODE_UNIFORMTOFILL{ L"uniformToFill" };

Profile::Profile() :
Profile(Utils::CreateGuid())
{
Expand Down Expand Up @@ -76,7 +84,10 @@ Profile::Profile(const winrt::guid& guid):
_scrollbarState{ },
_closeOnExit{ true },
_padding{ DEFAULT_PADDING },
_icon{ }
_icon{ },
_backgroundImage{ },
_backgroundImageOpacity{ },
_backgroundImageStretchMode{ }
d-bingham marked this conversation as resolved.
Show resolved Hide resolved
{
}

Expand Down Expand Up @@ -173,6 +184,21 @@ TerminalSettings Profile::CreateTerminalSettings(const std::vector<ColorScheme>&
terminalSettings.ScrollState(result);
}

if (_backgroundImage)
{
terminalSettings.BackgroundImage(_backgroundImage.value());
}

if (_backgroundImageOpacity)
{
terminalSettings.BackgroundImageOpacity(_backgroundImageOpacity.value());
}

if (_backgroundImageStretchMode)
{
terminalSettings.BackgroundImageStretchMode(_backgroundImageStretchMode.value());
}

return terminalSettings;
}

Expand Down Expand Up @@ -274,6 +300,25 @@ JsonObject Profile::ToJson() const
jsonObject.Insert(ICON_KEY, icon);
}

if (_backgroundImage)
{
const auto backgroundImage = JsonValue::CreateStringValue(_backgroundImage.value());
jsonObject.Insert(BACKGROUNDIMAGE_KEY, backgroundImage);
}

if (_backgroundImageOpacity)
{
const auto opacity = JsonValue::CreateNumberValue(_backgroundImageOpacity.value());
jsonObject.Insert(BACKGROUNDIMAGEOPACITY_KEY, opacity);
}

if (_backgroundImageStretchMode)
{
const auto imageStretchMode = JsonValue::CreateStringValue(
SerializeImageStretchMode(_backgroundImageStretchMode.value()));
jsonObject.Insert(BACKGROUNDIMAGESTRETCHMODE_KEY, imageStretchMode);
}

return jsonObject;
}

Expand Down Expand Up @@ -405,6 +450,19 @@ Profile Profile::FromJson(winrt::Windows::Data::Json::JsonObject json)
{
result._icon = json.GetNamedString(ICON_KEY);
}
if (json.HasKey(BACKGROUNDIMAGE_KEY))
{
result._backgroundImage = json.GetNamedString(BACKGROUNDIMAGE_KEY);
}
if (json.HasKey(BACKGROUNDIMAGEOPACITY_KEY))
{
result._backgroundImageOpacity = json.GetNamedNumber(BACKGROUNDIMAGEOPACITY_KEY);
}
if (json.HasKey(BACKGROUNDIMAGESTRETCHMODE_KEY))
{
const auto stretchMode = json.GetNamedString(BACKGROUNDIMAGESTRETCHMODE_KEY);
result._backgroundImageStretchMode = ParseImageStretchMode(stretchMode.c_str());
}

return result;
}
Expand Down Expand Up @@ -551,6 +609,58 @@ ScrollbarState Profile::ParseScrollbarState(const std::wstring& scrollbarState)
}
}

// Method Description:
// - Helper function for converting a user-specified image stretch mode
// to the appropriate enum value
// Arguments:
// - The value from the profiles.json file
// Return Value:
// - The corresponding enum value which maps to the string provided by the user
winrt::Windows::UI::Xaml::Media::Stretch Profile::ParseImageStretchMode(const std::wstring& imageStretchMode)
{
if (imageStretchMode == IMAGESTRETCHMODE_NONE)
{
return winrt::Windows::UI::Xaml::Media::Stretch::None;
}
else if (imageStretchMode == IMAGESTRETCHMODE_FILL)
{
return winrt::Windows::UI::Xaml::Media::Stretch::Fill;
}
else if (imageStretchMode == IMAGESTRETCHMODE_UNIFORM)
{
return winrt::Windows::UI::Xaml::Media::Stretch::Uniform;
}
else // Fall through to default behavior
{
return winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill;
}
}

// Method Description:
// - Helper function for converting an ImageStretchMode to the
// correct string value.
// Arguments:
// - imageStretchMode: The enum value to convert to a string.
// Return Value:
// - The string value for the given ImageStretchMode
std::wstring_view Profile::SerializeImageStretchMode(const winrt::Windows::UI::Xaml::Media::Stretch imageStretchMode)
{
switch (imageStretchMode)
{
case winrt::Windows::UI::Xaml::Media::Stretch::None:
return IMAGESTRETCHMODE_NONE;
case winrt::Windows::UI::Xaml::Media::Stretch::Fill:
return IMAGESTRETCHMODE_FILL;
case winrt::Windows::UI::Xaml::Media::Stretch::Uniform:
return IMAGESTRETCHMODE_UNIFORM;
default:
case winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill:
return IMAGESTRETCHMODE_UNIFORMTOFILL;
}
}



// Method Description:
// - Helper function for converting a user-specified cursor style corresponding
// CursorStyle enum value
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalApp/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class TerminalApp::Profile final
static std::wstring EvaluateStartingDirectory(const std::wstring& directory);

static winrt::Microsoft::Terminal::Settings::ScrollbarState ParseScrollbarState(const std::wstring& scrollbarState);
static winrt::Windows::UI::Xaml::Media::Stretch ParseImageStretchMode(const std::wstring& imageStretchMode);
static std::wstring_view SerializeImageStretchMode(const winrt::Windows::UI::Xaml::Media::Stretch imageStretchMode);
static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString);
static std::wstring_view _SerializeCursorStyle(const winrt::Microsoft::Terminal::Settings::CursorStyle cursorShape);

Expand All @@ -84,6 +86,10 @@ class TerminalApp::Profile final
double _acrylicTransparency;
bool _useAcrylic;

std::optional<std::wstring> _backgroundImage;
std::optional<double> _backgroundImageOpacity;
std::optional<winrt::Windows::UI::Xaml::Media::Stretch> _backgroundImageStretchMode;

std::optional<std::wstring> _scrollbarState;
bool _closeOnExit;
std::wstring _padding;
Expand Down
29 changes: 27 additions & 2 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// - Style our UI elements based on the values in our _settings, and set up
// other control-specific settings. This method will be called whenever
// the settings are reloaded.
// * Sets up the background of the control with the provided BG color,
// acrylic or not, and if acrylic, then uses the 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.
// - Core settings will be passed to the terminal in _InitializeTerminal
// Arguments:
// - <none>
Expand Down Expand Up @@ -189,6 +193,27 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// default BG color.
_settings.DefaultBackground(ARGB(0, R, G, B));
}
else if (!_settings.BackgroundImage().empty())
{
Windows::Foundation::Uri imageUri{ _settings.BackgroundImage() };
Media::Imaging::BitmapImage image(imageUri);

// Note that BitmapImage handles the image load asynchronously,
// which is especially important since the image
// may well be both large and somewhere out on the
// internet.

Media::ImageBrush brush{};
brush.ImageSource(image);
brush.Stretch(_settings.BackgroundImageStretchMode());
brush.Opacity(_settings.BackgroundImageOpacity());

_root.Background(brush);
d-bingham marked this conversation as resolved.
Show resolved Hide resolved

// Set the default background as transparent to prevent the
// DX layer from overwriting the background image
_settings.DefaultBackground(ARGB(0, R, G, B));
}
else
{
Media::SolidColorBrush solidColor{};
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.media.imaging.h>
#include <winrt/Windows.ui.xaml.input.h>

#include <windows.ui.xaml.media.dxinterop.h>
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalSettings/IControlSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@ namespace Microsoft.Terminal.Settings
String StartingDirectory;
String EnvironmentVariables;

String BackgroundImage;
Double BackgroundImageOpacity;
Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode;
};
}
33 changes: 33 additions & 0 deletions src/cascadia/TerminalSettings/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_padding{ DEFAULT_PADDING },
_fontFace{ DEFAULT_FONT_FACE },
_fontSize{ DEFAULT_FONT_SIZE },
_backgroundImage{},
_backgroundImageOpacity{ 1.0 },
_backgroundImageStretchMode{ winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill },
_keyBindings{ nullptr },
_scrollbarState{ ScrollbarState::Visible }
{
Expand Down Expand Up @@ -191,6 +194,36 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_fontSize = value;
}

void TerminalSettings::BackgroundImage(hstring const& value)
{
_backgroundImage = value;
}

hstring TerminalSettings::BackgroundImage()
{
return _backgroundImage;
}

void TerminalSettings::BackgroundImageOpacity(double value)
{
_backgroundImageOpacity = value;
}

double TerminalSettings::BackgroundImageOpacity()
{
return _backgroundImageOpacity;
}

winrt::Windows::UI::Xaml::Media::Stretch TerminalSettings::BackgroundImageStretchMode()
{
return _backgroundImageStretchMode;
}

void TerminalSettings::BackgroundImageStretchMode(winrt::Windows::UI::Xaml::Media::Stretch value)
{
_backgroundImageStretchMode = value;
}

Settings::IKeyBindings TerminalSettings::KeyBindings()
{
return _keyBindings;
Expand Down
10 changes: 10 additions & 0 deletions src/cascadia/TerminalSettings/terminalsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
int32_t FontSize();
void FontSize(int32_t value);

hstring BackgroundImage();
void BackgroundImage(hstring const& value);
double BackgroundImageOpacity();
void BackgroundImageOpacity(double value);
winrt::Windows::UI::Xaml::Media::Stretch BackgroundImageStretchMode();
void BackgroundImageStretchMode(winrt::Windows::UI::Xaml::Media::Stretch value);

winrt::Microsoft::Terminal::Settings::IKeyBindings KeyBindings();
void KeyBindings(winrt::Microsoft::Terminal::Settings::IKeyBindings const& value);

Expand Down Expand Up @@ -94,6 +101,9 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
hstring _fontFace;
int32_t _fontSize;
hstring _padding;
hstring _backgroundImage;
double _backgroundImageOpacity;
winrt::Windows::UI::Xaml::Media::Stretch _backgroundImageStretchMode;
hstring _commandline;
hstring _startingDir;
hstring _envVars;
Expand Down