Skip to content

Commit 89190c6

Browse files
trigger-segfaultDHowett
authored andcommitted
Add support for background image alignment (as one setting) (microsoft#1959)
* Implement base background image alignment settings TerminalSettings now has two new properties: * BackgroundImageHorizontalAlignment * BackgroundImageVerticalAlignment These properties are used in TermControl::_InitializeBackgroundBrush to specify the alignment for TermControl::_bgImageLayer. This is a base commit that will split into two possible branches: * Use one setting in profiles.json: "backgroundImageAlignment" * Use two settings in profiles.json: "backgroundImageHorizontal/VerticalAlignment" * Implement background image alignment profile setting Implement background image alignment as one profile setting. * This has the benefit of acting as a single setting when the user would likely want to change both horizontal and vertical alignment. * HorizontalAlignment and VerticalAlignment are still stored as a tuple in Profile because they are an optional field. And thus, it would not make sense for one of the alignments to be left unused while the other is not. * Cons are that the tuple signature is quite long, but it is only used in a small number of locations. The Serialize method is also a little mishapen with the nested switch statements. Empty lines have been added between base-level cases to improve readability. * Fix capitalization typo for BackgroundImageStretchModeKey In Profiles.cpp, the key for the image stretch mode json property had a lowercase 'i' in "Backgroundimage", not following proper UpperCamelCase. The "i" has been capitalized and the two usages of the constant have been updated as well. * Document Background Image settings * Adds entries SettingsSchema.md for the original 3 backgroundImage settings in addition to the new backgroundImageAlignment setting. * Fix setting capitalization error in UsingJsonSettings.md * The background image example in UsingJsonSettings.md listing a backgroundImageStretchMode of "Fill" has been corrected to "fill". Fixes microsoft#1949.
1 parent 2c3e175 commit 89190c6

8 files changed

Lines changed: 183 additions & 8 deletions

File tree

doc/cascadia/SettingsSchema.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Properties listed below are specific to each unique profile.
3535
| `startingDirectory` | _Required_ | String | `%USERPROFILE%` | The directory the shell starts in when it is loaded. |
3636
| `useAcrylic` | _Required_ | Boolean | `false` | When set to `true`, the window will have an acrylic background. When set to `false`, the window will have a plain, untextured background. |
3737
| `background` | Optional | String | | Sets the background color of the profile. Overrides `background` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
38+
| `backgroundImage` | Optional | String | | Sets the file location of the Image to draw over the window background. |
39+
| `backgroundImageAlignment` | Optional | String | `center` | Sets how the background image aligns to the boundaries of the window. Possible values: `"center"`, `"left"`, `"top"`, `"right"`, `"bottom"`, `"topLeft"`, `"topRight"`, `"bottomLeft"`, `"bottomRight"` |
40+
| `backgroundImageOpacity` | Optional | Number | `1.0` | Sets the transparency of the background image. Accepts floating point values from 0-1. |
41+
| `backgroundImageStretchMode` | Optional | String | `uniformToFill` | Sets how the background image is resized to fill the window. Possible values: `"none"`, `"fill"`, `"uniform"`, `"uniformToFill"` |
3842
| `colorTable` | Optional | Array[String] | | Array of colors used in the profile if `colorscheme` is not set. Colors use hex color format: `"#rrggbb"`. Ordering is as follows: `[black, red, green, yellow, blue, magenta, cyan, white, bright black, bright red, bright green, bright yellow, bright blue, bright magenta, bright cyan, bright white]` |
3943
| `cursorHeight` | Optional | Integer | | Sets the percentage height of the cursor starting from the bottom. Only works when `cursorShape` is set to `"vintage"`. Accepts values from 25-100. |
4044
| `foreground` | Optional | String | | Sets the foreground color of the profile. Overrides `foreground` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |

doc/user-docs/UsingJsonSettings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ The schema name can then be referenced in one or more profiles.
110110
```json
111111
"backgroundImage": "ms-appdata:///Roaming/openlogo.jpg",
112112
"backgroundImageOpacity": 0.3,
113-
"backgroundImageStretchMode": "Fill",
113+
"backgroundImageStretchMode": "fill",
114114
```
115115
5. Make sure that `useAcrylic` is `false`.
116116
6. Save the file.

src/cascadia/TerminalApp/Profile.cpp

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ static constexpr std::string_view StartingDirectoryKey{ "startingDirectory" };
3838
static constexpr std::string_view IconKey{ "icon" };
3939
static constexpr std::string_view BackgroundImageKey{ "backgroundImage" };
4040
static constexpr std::string_view BackgroundImageOpacityKey{ "backgroundImageOpacity" };
41-
static constexpr std::string_view BackgroundimageStretchModeKey{ "backgroundImageStretchMode" };
41+
static constexpr std::string_view BackgroundImageStretchModeKey{ "backgroundImageStretchMode" };
42+
static constexpr std::string_view BackgroundImageAlignmentKey{ "backgroundImageAlignment" };
4243

4344
// Possible values for Scrollbar state
4445
static constexpr std::wstring_view AlwaysVisible{ L"visible" };
@@ -57,6 +58,17 @@ static constexpr std::string_view ImageStretchModeFill{ "fill" };
5758
static constexpr std::string_view ImageStretchModeUniform{ "uniform" };
5859
static constexpr std::string_view ImageStretchModeUniformTofill{ "uniformToFill" };
5960

61+
// Possible values for Image Alignment
62+
static constexpr std::string_view ImageAlignmentCenter{ "center" };
63+
static constexpr std::string_view ImageAlignmentLeft{ "left" };
64+
static constexpr std::string_view ImageAlignmentTop{ "top" };
65+
static constexpr std::string_view ImageAlignmentRight{ "right" };
66+
static constexpr std::string_view ImageAlignmentBottom{ "bottom" };
67+
static constexpr std::string_view ImageAlignmentTopLeft{ "topLeft" };
68+
static constexpr std::string_view ImageAlignmentTopRight{ "topRight" };
69+
static constexpr std::string_view ImageAlignmentBottomLeft{ "bottomLeft" };
70+
static constexpr std::string_view ImageAlignmentBottomRight{ "bottomRight" };
71+
6072
Profile::Profile() :
6173
Profile(Utils::CreateGuid())
6274
{
@@ -89,7 +101,8 @@ Profile::Profile(const winrt::guid& guid) :
89101
_icon{},
90102
_backgroundImage{},
91103
_backgroundImageOpacity{},
92-
_backgroundImageStretchMode{}
104+
_backgroundImageStretchMode{},
105+
_backgroundImageAlignment{}
93106
{
94107
}
95108

@@ -200,6 +213,14 @@ TerminalSettings Profile::CreateTerminalSettings(const std::vector<ColorScheme>&
200213
terminalSettings.BackgroundImageStretchMode(_backgroundImageStretchMode.value());
201214
}
202215

216+
if (_backgroundImageAlignment)
217+
{
218+
const auto imageHorizontalAlignment = std::get<winrt::Windows::UI::Xaml::HorizontalAlignment>(_backgroundImageAlignment.value());
219+
const auto imageVerticalAlignment = std::get<winrt::Windows::UI::Xaml::VerticalAlignment>(_backgroundImageAlignment.value());
220+
terminalSettings.BackgroundImageHorizontalAlignment(imageHorizontalAlignment);
221+
terminalSettings.BackgroundImageVerticalAlignment(imageVerticalAlignment);
222+
}
223+
203224
return terminalSettings;
204225
}
205226

@@ -293,7 +314,12 @@ Json::Value Profile::ToJson() const
293314

294315
if (_backgroundImageStretchMode)
295316
{
296-
root[JsonKey(BackgroundimageStretchModeKey)] = SerializeImageStretchMode(_backgroundImageStretchMode.value()).data();
317+
root[JsonKey(BackgroundImageStretchModeKey)] = SerializeImageStretchMode(_backgroundImageStretchMode.value()).data();
318+
}
319+
320+
if (_backgroundImageAlignment)
321+
{
322+
root[JsonKey(BackgroundImageAlignmentKey)] = SerializeImageAlignment(_backgroundImageAlignment.value()).data();
297323
}
298324

299325
return root;
@@ -428,10 +454,14 @@ Profile Profile::FromJson(const Json::Value& json)
428454
{
429455
result._backgroundImageOpacity = backgroundImageOpacity.asFloat();
430456
}
431-
if (auto backgroundImageStretchMode{ json[JsonKey(BackgroundimageStretchModeKey)] })
457+
if (auto backgroundImageStretchMode{ json[JsonKey(BackgroundImageStretchModeKey)] })
432458
{
433459
result._backgroundImageStretchMode = ParseImageStretchMode(backgroundImageStretchMode.asString());
434460
}
461+
if (auto backgroundImageAlignment{ json[JsonKey(BackgroundImageAlignmentKey)] })
462+
{
463+
result._backgroundImageAlignment = ParseImageAlignment(backgroundImageAlignment.asString());
464+
}
435465

436466
return result;
437467
}
@@ -654,6 +684,114 @@ std::string_view Profile::SerializeImageStretchMode(const winrt::Windows::UI::Xa
654684
}
655685
}
656686

687+
// Method Description:
688+
// - Helper function for converting a user-specified image horizontal and vertical
689+
// alignment to the appropriate enum values tuple
690+
// Arguments:
691+
// - The value from the profiles.json file
692+
// Return Value:
693+
// - The corresponding enum values tuple which maps to the string provided by the user
694+
std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> Profile::ParseImageAlignment(const std::string_view imageAlignment)
695+
{
696+
if (imageAlignment == ImageAlignmentTopLeft)
697+
{
698+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Left,
699+
winrt::Windows::UI::Xaml::VerticalAlignment::Top);
700+
}
701+
else if (imageAlignment == ImageAlignmentBottomLeft)
702+
{
703+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Left,
704+
winrt::Windows::UI::Xaml::VerticalAlignment::Bottom);
705+
}
706+
else if (imageAlignment == ImageAlignmentLeft)
707+
{
708+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Left,
709+
winrt::Windows::UI::Xaml::VerticalAlignment::Center);
710+
}
711+
else if (imageAlignment == ImageAlignmentTopRight)
712+
{
713+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Right,
714+
winrt::Windows::UI::Xaml::VerticalAlignment::Top);
715+
}
716+
else if (imageAlignment == ImageAlignmentBottomRight)
717+
{
718+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Right,
719+
winrt::Windows::UI::Xaml::VerticalAlignment::Bottom);
720+
}
721+
else if (imageAlignment == ImageAlignmentRight)
722+
{
723+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Right,
724+
winrt::Windows::UI::Xaml::VerticalAlignment::Center);
725+
}
726+
else if (imageAlignment == ImageAlignmentTop)
727+
{
728+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Center,
729+
winrt::Windows::UI::Xaml::VerticalAlignment::Top);
730+
}
731+
else if (imageAlignment == ImageAlignmentBottom)
732+
{
733+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Center,
734+
winrt::Windows::UI::Xaml::VerticalAlignment::Bottom);
735+
}
736+
else // Fall through to default alignment
737+
{
738+
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Center,
739+
winrt::Windows::UI::Xaml::VerticalAlignment::Center);
740+
}
741+
}
742+
743+
// Method Description:
744+
// - Helper function for converting the HorizontalAlignment+VerticalAlignment tuple
745+
// to the correct string value.
746+
// Arguments:
747+
// - imageAlignment: The enum values tuple to convert to a string.
748+
// Return Value:
749+
// - The string value for the given ImageAlignment
750+
std::string_view Profile::SerializeImageAlignment(const std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> imageAlignment)
751+
{
752+
const auto imageHorizontalAlignment = std::get<winrt::Windows::UI::Xaml::HorizontalAlignment>(imageAlignment);
753+
const auto imageVerticalAlignment = std::get<winrt::Windows::UI::Xaml::VerticalAlignment>(imageAlignment);
754+
switch (imageHorizontalAlignment)
755+
{
756+
case winrt::Windows::UI::Xaml::HorizontalAlignment::Left:
757+
switch (imageVerticalAlignment)
758+
{
759+
case winrt::Windows::UI::Xaml::VerticalAlignment::Top:
760+
return ImageAlignmentTopLeft;
761+
case winrt::Windows::UI::Xaml::VerticalAlignment::Bottom:
762+
return ImageAlignmentBottomLeft;
763+
default:
764+
case winrt::Windows::UI::Xaml::VerticalAlignment::Center:
765+
return ImageAlignmentLeft;
766+
}
767+
768+
case winrt::Windows::UI::Xaml::HorizontalAlignment::Right:
769+
switch (imageVerticalAlignment)
770+
{
771+
case winrt::Windows::UI::Xaml::VerticalAlignment::Top:
772+
return ImageAlignmentTopRight;
773+
case winrt::Windows::UI::Xaml::VerticalAlignment::Bottom:
774+
return ImageAlignmentBottomRight;
775+
default:
776+
case winrt::Windows::UI::Xaml::VerticalAlignment::Center:
777+
return ImageAlignmentRight;
778+
}
779+
780+
default:
781+
case winrt::Windows::UI::Xaml::HorizontalAlignment::Center:
782+
switch (imageVerticalAlignment)
783+
{
784+
case winrt::Windows::UI::Xaml::VerticalAlignment::Top:
785+
return ImageAlignmentTop;
786+
case winrt::Windows::UI::Xaml::VerticalAlignment::Bottom:
787+
return ImageAlignmentBottom;
788+
default:
789+
case winrt::Windows::UI::Xaml::VerticalAlignment::Center:
790+
return ImageAlignmentCenter;
791+
}
792+
}
793+
}
794+
657795
// Method Description:
658796
// - Helper function for converting a user-specified cursor style corresponding
659797
// CursorStyle enum value

src/cascadia/TerminalApp/Profile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class TerminalApp::Profile final
6262
static winrt::Microsoft::Terminal::Settings::ScrollbarState ParseScrollbarState(const std::wstring& scrollbarState);
6363
static winrt::Windows::UI::Xaml::Media::Stretch ParseImageStretchMode(const std::string_view imageStretchMode);
6464
static std::string_view SerializeImageStretchMode(const winrt::Windows::UI::Xaml::Media::Stretch imageStretchMode);
65+
static std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> ParseImageAlignment(const std::string_view imageAlignment);
66+
static std::string_view SerializeImageAlignment(const std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> imageAlignment);
6567
static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString);
6668
static std::wstring_view _SerializeCursorStyle(const winrt::Microsoft::Terminal::Settings::CursorStyle cursorShape);
6769

@@ -91,6 +93,7 @@ class TerminalApp::Profile final
9193
std::optional<std::wstring> _backgroundImage;
9294
std::optional<double> _backgroundImageOpacity;
9395
std::optional<winrt::Windows::UI::Xaml::Media::Stretch> _backgroundImageStretchMode;
96+
std::optional<std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment>> _backgroundImageAlignment;
9497

9598
std::optional<std::wstring> _scrollbarState;
9699
bool _closeOnExit;

src/cascadia/TerminalControl/TermControl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,13 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
276276
// internet.
277277
Media::Imaging::BitmapImage image(imageUri);
278278
_bgImageLayer.Source(image);
279-
_bgImageLayer.HorizontalAlignment(HorizontalAlignment::Center);
280-
_bgImageLayer.VerticalAlignment(VerticalAlignment::Center);
281279
}
282280

283-
// Apply stretch and opacity settings
281+
// Apply stretch, opacity and alignment settings
284282
_bgImageLayer.Stretch(_settings.BackgroundImageStretchMode());
285283
_bgImageLayer.Opacity(_settings.BackgroundImageOpacity());
284+
_bgImageLayer.HorizontalAlignment(_settings.BackgroundImageHorizontalAlignment());
285+
_bgImageLayer.VerticalAlignment(_settings.BackgroundImageVerticalAlignment());
286286
}
287287
else
288288
{

src/cascadia/TerminalSettings/IControlSettings.idl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,7 @@ namespace Microsoft.Terminal.Settings
3737
String BackgroundImage;
3838
Double BackgroundImageOpacity;
3939
Windows.UI.Xaml.Media.Stretch BackgroundImageStretchMode;
40+
Windows.UI.Xaml.HorizontalAlignment BackgroundImageHorizontalAlignment;
41+
Windows.UI.Xaml.VerticalAlignment BackgroundImageVerticalAlignment;
4042
};
4143
}

src/cascadia/TerminalSettings/TerminalSettings.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
3030
_backgroundImage{},
3131
_backgroundImageOpacity{ 1.0 },
3232
_backgroundImageStretchMode{ winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill },
33+
_backgroundImageHorizontalAlignment{ winrt::Windows::UI::Xaml::HorizontalAlignment::Center },
34+
_backgroundImageVerticalAlignment{ winrt::Windows::UI::Xaml::VerticalAlignment::Center },
3335
_keyBindings{ nullptr },
3436
_scrollbarState{ ScrollbarState::Visible }
3537
{
@@ -236,6 +238,26 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
236238
_backgroundImageStretchMode = value;
237239
}
238240

241+
winrt::Windows::UI::Xaml::HorizontalAlignment TerminalSettings::BackgroundImageHorizontalAlignment()
242+
{
243+
return _backgroundImageHorizontalAlignment;
244+
}
245+
246+
void TerminalSettings::BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value)
247+
{
248+
_backgroundImageHorizontalAlignment = value;
249+
}
250+
251+
winrt::Windows::UI::Xaml::VerticalAlignment TerminalSettings::BackgroundImageVerticalAlignment()
252+
{
253+
return _backgroundImageVerticalAlignment;
254+
}
255+
256+
void TerminalSettings::BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value)
257+
{
258+
_backgroundImageVerticalAlignment = value;
259+
}
260+
239261
Settings::IKeyBindings TerminalSettings::KeyBindings()
240262
{
241263
return _keyBindings;

src/cascadia/TerminalSettings/terminalsettings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
6969
void BackgroundImageOpacity(double value);
7070
winrt::Windows::UI::Xaml::Media::Stretch BackgroundImageStretchMode();
7171
void BackgroundImageStretchMode(winrt::Windows::UI::Xaml::Media::Stretch value);
72+
winrt::Windows::UI::Xaml::HorizontalAlignment BackgroundImageHorizontalAlignment();
73+
void BackgroundImageHorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment value);
74+
winrt::Windows::UI::Xaml::VerticalAlignment BackgroundImageVerticalAlignment();
75+
void BackgroundImageVerticalAlignment(winrt::Windows::UI::Xaml::VerticalAlignment value);
7276

7377
winrt::Microsoft::Terminal::Settings::IKeyBindings KeyBindings();
7478
void KeyBindings(winrt::Microsoft::Terminal::Settings::IKeyBindings const& value);
@@ -107,6 +111,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
107111
hstring _backgroundImage;
108112
double _backgroundImageOpacity;
109113
winrt::Windows::UI::Xaml::Media::Stretch _backgroundImageStretchMode;
114+
winrt::Windows::UI::Xaml::HorizontalAlignment _backgroundImageHorizontalAlignment;
115+
winrt::Windows::UI::Xaml::VerticalAlignment _backgroundImageVerticalAlignment;
110116
hstring _commandline;
111117
hstring _startingDir;
112118
hstring _envVars;

0 commit comments

Comments
 (0)