2019-05-03 00:29:04 +02:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#include "pch.h"
|
|
|
|
#include "Profile.h"
|
2019-06-04 23:55:27 +02:00
|
|
|
#include "Utils.h"
|
2019-05-03 00:29:04 +02:00
|
|
|
#include "../../types/inc/Utils.hpp"
|
|
|
|
#include <DefaultSettings.h>
|
|
|
|
|
|
|
|
using namespace TerminalApp;
|
|
|
|
using namespace winrt::Microsoft::Terminal::Settings;
|
|
|
|
using namespace ::Microsoft::Console;
|
|
|
|
|
2019-06-04 23:55:27 +02:00
|
|
|
static constexpr std::string_view NameKey{ "name" };
|
|
|
|
static constexpr std::string_view GuidKey{ "guid" };
|
|
|
|
static constexpr std::string_view ColorSchemeKey{ "colorScheme" };
|
|
|
|
static constexpr std::string_view ColorSchemeKeyOld{ "colorscheme" };
|
|
|
|
|
|
|
|
static constexpr std::string_view ForegroundKey{ "foreground" };
|
|
|
|
static constexpr std::string_view BackgroundKey{ "background" };
|
|
|
|
static constexpr std::string_view ColorTableKey{ "colorTable" };
|
2019-07-02 19:09:22 +02:00
|
|
|
static constexpr std::string_view TabTitleKey{ "tabTitle" };
|
2019-06-04 23:55:27 +02:00
|
|
|
static constexpr std::string_view HistorySizeKey{ "historySize" };
|
|
|
|
static constexpr std::string_view SnapOnInputKey{ "snapOnInput" };
|
|
|
|
static constexpr std::string_view CursorColorKey{ "cursorColor" };
|
|
|
|
static constexpr std::string_view CursorShapeKey{ "cursorShape" };
|
|
|
|
static constexpr std::string_view CursorHeightKey{ "cursorHeight" };
|
|
|
|
|
2019-07-25 22:31:41 +02:00
|
|
|
static constexpr std::string_view ConnectionTypeKey{ "connectionType" };
|
2019-06-04 23:55:27 +02:00
|
|
|
static constexpr std::string_view CommandlineKey{ "commandline" };
|
|
|
|
static constexpr std::string_view FontFaceKey{ "fontFace" };
|
|
|
|
static constexpr std::string_view FontSizeKey{ "fontSize" };
|
|
|
|
static constexpr std::string_view AcrylicTransparencyKey{ "acrylicOpacity" };
|
|
|
|
static constexpr std::string_view UseAcrylicKey{ "useAcrylic" };
|
|
|
|
static constexpr std::string_view ScrollbarStateKey{ "scrollbarState" };
|
|
|
|
static constexpr std::string_view CloseOnExitKey{ "closeOnExit" };
|
|
|
|
static constexpr std::string_view PaddingKey{ "padding" };
|
|
|
|
static constexpr std::string_view StartingDirectoryKey{ "startingDirectory" };
|
|
|
|
static constexpr std::string_view IconKey{ "icon" };
|
|
|
|
static constexpr std::string_view BackgroundImageKey{ "backgroundImage" };
|
|
|
|
static constexpr std::string_view BackgroundImageOpacityKey{ "backgroundImageOpacity" };
|
2019-07-25 06:47:06 +02:00
|
|
|
static constexpr std::string_view BackgroundImageStretchModeKey{ "backgroundImageStretchMode" };
|
|
|
|
static constexpr std::string_view BackgroundImageAlignmentKey{ "backgroundImageAlignment" };
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
// Possible values for Scrollbar state
|
2019-06-04 23:55:27 +02:00
|
|
|
static constexpr std::wstring_view AlwaysVisible{ L"visible" };
|
|
|
|
static constexpr std::wstring_view AlwaysHide{ L"hidden" };
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
// Possible values for Cursor Shape
|
2019-06-04 23:55:27 +02:00
|
|
|
static constexpr std::wstring_view CursorShapeVintage{ L"vintage" };
|
|
|
|
static constexpr std::wstring_view CursorShapeBar{ L"bar" };
|
|
|
|
static constexpr std::wstring_view CursorShapeUnderscore{ L"underscore" };
|
|
|
|
static constexpr std::wstring_view CursorShapeFilledbox{ L"filledBox" };
|
|
|
|
static constexpr std::wstring_view CursorShapeEmptybox{ L"emptyBox" };
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-05-29 20:35:46 +02:00
|
|
|
// Possible values for Image Stretch Mode
|
2019-06-04 23:55:27 +02:00
|
|
|
static constexpr std::string_view ImageStretchModeNone{ "none" };
|
|
|
|
static constexpr std::string_view ImageStretchModeFill{ "fill" };
|
|
|
|
static constexpr std::string_view ImageStretchModeUniform{ "uniform" };
|
|
|
|
static constexpr std::string_view ImageStretchModeUniformTofill{ "uniformToFill" };
|
2019-05-29 20:35:46 +02:00
|
|
|
|
2019-07-25 06:47:06 +02:00
|
|
|
// Possible values for Image Alignment
|
|
|
|
static constexpr std::string_view ImageAlignmentCenter{ "center" };
|
|
|
|
static constexpr std::string_view ImageAlignmentLeft{ "left" };
|
|
|
|
static constexpr std::string_view ImageAlignmentTop{ "top" };
|
|
|
|
static constexpr std::string_view ImageAlignmentRight{ "right" };
|
|
|
|
static constexpr std::string_view ImageAlignmentBottom{ "bottom" };
|
|
|
|
static constexpr std::string_view ImageAlignmentTopLeft{ "topLeft" };
|
|
|
|
static constexpr std::string_view ImageAlignmentTopRight{ "topRight" };
|
|
|
|
static constexpr std::string_view ImageAlignmentBottomLeft{ "bottomLeft" };
|
|
|
|
static constexpr std::string_view ImageAlignmentBottomRight{ "bottomRight" };
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
Profile::Profile() :
|
2019-05-21 22:29:16 +02:00
|
|
|
Profile(Utils::CreateGuid())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
Profile::Profile(const winrt::guid& guid) :
|
2019-05-21 22:29:16 +02:00
|
|
|
_guid(guid),
|
2019-05-03 00:29:04 +02:00
|
|
|
_name{ L"Default" },
|
|
|
|
_schemeName{},
|
|
|
|
|
2019-06-11 22:27:09 +02:00
|
|
|
_defaultForeground{},
|
|
|
|
_defaultBackground{},
|
2019-05-03 00:29:04 +02:00
|
|
|
_colorTable{},
|
2019-07-02 19:09:22 +02:00
|
|
|
_tabTitle{},
|
2019-05-03 00:29:04 +02:00
|
|
|
_historySize{ DEFAULT_HISTORY_SIZE },
|
|
|
|
_snapOnInput{ true },
|
|
|
|
_cursorColor{ DEFAULT_CURSOR_COLOR },
|
|
|
|
_cursorShape{ CursorStyle::Bar },
|
|
|
|
_cursorHeight{ DEFAULT_CURSOR_HEIGHT },
|
|
|
|
|
2019-07-25 22:31:41 +02:00
|
|
|
_connectionType{},
|
2019-05-03 00:29:04 +02:00
|
|
|
_commandline{ L"cmd.exe" },
|
2019-06-11 22:27:09 +02:00
|
|
|
_startingDirectory{},
|
2019-05-03 00:29:04 +02:00
|
|
|
_fontFace{ DEFAULT_FONT_FACE },
|
|
|
|
_fontSize{ DEFAULT_FONT_SIZE },
|
|
|
|
_acrylicTransparency{ 0.5 },
|
|
|
|
_useAcrylic{ false },
|
2019-06-11 22:27:09 +02:00
|
|
|
_scrollbarState{},
|
2019-05-09 16:17:33 +02:00
|
|
|
_closeOnExit{ true },
|
2019-05-03 00:29:04 +02:00
|
|
|
_padding{ DEFAULT_PADDING },
|
2019-06-11 22:27:09 +02:00
|
|
|
_icon{},
|
|
|
|
_backgroundImage{},
|
|
|
|
_backgroundImageOpacity{},
|
2019-07-25 06:47:06 +02:00
|
|
|
_backgroundImageStretchMode{},
|
|
|
|
_backgroundImageAlignment{}
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Profile::~Profile()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GUID Profile::GetGuid() const noexcept
|
|
|
|
{
|
|
|
|
return _guid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Function Description:
|
|
|
|
// - Searches a list of color schemes to find one matching the given name. Will
|
|
|
|
//return the first match in the list, if the list has multiple schemes with the same name.
|
|
|
|
// Arguments:
|
|
|
|
// - schemes: a list of schemes to search
|
|
|
|
// - schemeName: the name of the sceme to look for
|
|
|
|
// Return Value:
|
|
|
|
// - a non-ownership pointer to the matching scheme if we found one, else nullptr
|
|
|
|
const ColorScheme* _FindScheme(const std::vector<ColorScheme>& schemes,
|
|
|
|
const std::wstring& schemeName)
|
|
|
|
{
|
|
|
|
for (auto& scheme : schemes)
|
|
|
|
{
|
|
|
|
if (scheme.GetName() == schemeName)
|
|
|
|
{
|
|
|
|
return &scheme;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Create a TerminalSettings from this object. Apply our settings, as well as
|
2019-05-30 20:32:05 +02:00
|
|
|
// any colors from our color scheme, if we have one.
|
2019-05-03 00:29:04 +02:00
|
|
|
// Arguments:
|
|
|
|
// - schemes: a list of schemes to look for our color scheme in, if we have one.
|
|
|
|
// Return Value:
|
|
|
|
// - a new TerminalSettings object with our settings in it.
|
|
|
|
TerminalSettings Profile::CreateTerminalSettings(const std::vector<ColorScheme>& schemes) const
|
|
|
|
{
|
|
|
|
TerminalSettings terminalSettings{};
|
|
|
|
|
|
|
|
// Fill in the Terminal Setting's CoreSettings from the profile
|
2019-08-06 20:33:32 +02:00
|
|
|
auto const colorTableCount = gsl::narrow_cast<int>(_colorTable.size());
|
|
|
|
for (int i = 0; i < colorTableCount; i++)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
terminalSettings.SetColorTableEntry(i, _colorTable[i]);
|
|
|
|
}
|
|
|
|
terminalSettings.HistorySize(_historySize);
|
|
|
|
terminalSettings.SnapOnInput(_snapOnInput);
|
|
|
|
terminalSettings.CursorColor(_cursorColor);
|
|
|
|
terminalSettings.CursorHeight(_cursorHeight);
|
|
|
|
terminalSettings.CursorShape(_cursorShape);
|
|
|
|
|
|
|
|
// Fill in the remaining properties from the profile
|
|
|
|
terminalSettings.UseAcrylic(_useAcrylic);
|
|
|
|
terminalSettings.CloseOnExit(_closeOnExit);
|
|
|
|
terminalSettings.TintOpacity(_acrylicTransparency);
|
|
|
|
|
|
|
|
terminalSettings.FontFace(_fontFace);
|
|
|
|
terminalSettings.FontSize(_fontSize);
|
|
|
|
terminalSettings.Padding(_padding);
|
|
|
|
|
|
|
|
terminalSettings.Commandline(winrt::to_hstring(_commandline.c_str()));
|
|
|
|
|
|
|
|
if (_startingDirectory)
|
|
|
|
{
|
|
|
|
const auto evaluatedDirectory = Profile::EvaluateStartingDirectory(_startingDirectory.value());
|
|
|
|
terminalSettings.StartingDirectory(winrt::to_hstring(evaluatedDirectory.c_str()));
|
|
|
|
}
|
|
|
|
|
A better fix for #tab-titles-are-too-long (#2373)
### User Stories:
1. A user wants to be able to use the executable path as their starting title
- Does anyone want this?
2. A user wants to be able to set a custom starting title, but have that title be overridable
3. A user wants to be able to set an overridable starting title, different from the profile name
- Presumably someone will want this
4. A user totally wants to ignore the VT title and use something else
- This will make more sense in the post [#1320] "Support runtime variables in the custom user title" settings
### Solutions:
1. `name`, `startingTitle`, `tabTitle`
* a. `name` is only ever used as the profile name.
* b. If `startingTitle` isn't set, then the executable path is used
* c. If `startingTitle` is set, it's used as the initial title
* d. If `tabTitle` is set, it overrides the title from the terminal
* e. Current users of `tabTitle` need to manually update to the new behavior.
2. `name` as starting title, `tabTitle` as a different starting title
* a. `name` is used as the starting title and the profile name in the dropdown
* b. If `tabTitle` is set, we'll use that as the overridable starting title instead.
* c. In the future, `dynamicTabTitle` or `tabTitleOverride` could be added to support [#1320]
* d. Current users of `tabTitle` automatically get the new (different!) behavior.
* e. User Story 1 is impossible
- Does anyone want the behavior _ever_? Perhaps making that scenario impossible is good?
3. `name` unchanged, `tabTitle` as the starting title
* a. `name` is only ever used as the profile name.
* b. If `tabTitle` is set, we'll use that as the overridable starting title.
* c. In the future, `dynamicTabTitle` or `tabTitleOverride` could be added to support [#1320]
* d. Current users of `tabTitle` automatically get the new (different!) behavior.
4. `name` as starting title, `tabTitle` as different starting title, `suppressApplicationTitle` Boolean to force it to override
* a. `name`, `tabTitle` work as in Solution 2.
* b. When someone wants to be able to statically totally override that title (story 4), they can use `suppressApplicationTitle`
* c. `suppressApplicationTitle` name is WIP
* d. We'll add `suppressApplicationTitle` when someone complains
* e. If you really want story 1, use `tabTitle: c:\path\to\foo.exe` and `suppressApplicationTitle`.
[#1320]: https://github.com/microsoft/terminal/issues/1320
We've decided to pursue path 4.
2019-08-15 01:16:38 +02:00
|
|
|
// GH#2373: Use the tabTitle as the starting title if it exists, otherwise
|
|
|
|
// use the profile name
|
|
|
|
terminalSettings.StartingTitle(_tabTitle ? _tabTitle.value() : _name);
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
if (_schemeName)
|
|
|
|
{
|
|
|
|
const ColorScheme* const matchingScheme = _FindScheme(schemes, _schemeName.value());
|
|
|
|
if (matchingScheme)
|
|
|
|
{
|
|
|
|
matchingScheme->ApplyScheme(terminalSettings);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_defaultForeground)
|
|
|
|
{
|
|
|
|
terminalSettings.DefaultForeground(_defaultForeground.value());
|
|
|
|
}
|
|
|
|
if (_defaultBackground)
|
|
|
|
{
|
|
|
|
terminalSettings.DefaultBackground(_defaultBackground.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_scrollbarState)
|
|
|
|
{
|
|
|
|
ScrollbarState result = ParseScrollbarState(_scrollbarState.value());
|
|
|
|
terminalSettings.ScrollState(result);
|
|
|
|
}
|
|
|
|
|
2019-05-29 20:35:46 +02:00
|
|
|
if (_backgroundImage)
|
|
|
|
{
|
|
|
|
terminalSettings.BackgroundImage(_backgroundImage.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_backgroundImageOpacity)
|
|
|
|
{
|
|
|
|
terminalSettings.BackgroundImageOpacity(_backgroundImageOpacity.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_backgroundImageStretchMode)
|
|
|
|
{
|
|
|
|
terminalSettings.BackgroundImageStretchMode(_backgroundImageStretchMode.value());
|
|
|
|
}
|
|
|
|
|
2019-07-25 06:47:06 +02:00
|
|
|
if (_backgroundImageAlignment)
|
|
|
|
{
|
|
|
|
const auto imageHorizontalAlignment = std::get<winrt::Windows::UI::Xaml::HorizontalAlignment>(_backgroundImageAlignment.value());
|
|
|
|
const auto imageVerticalAlignment = std::get<winrt::Windows::UI::Xaml::VerticalAlignment>(_backgroundImageAlignment.value());
|
|
|
|
terminalSettings.BackgroundImageHorizontalAlignment(imageHorizontalAlignment);
|
|
|
|
terminalSettings.BackgroundImageVerticalAlignment(imageVerticalAlignment);
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
return terminalSettings;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Serialize this object to a JsonObject.
|
|
|
|
// Arguments:
|
|
|
|
// - <none>
|
|
|
|
// Return Value:
|
|
|
|
// - a JsonObject which is an equivalent serialization of this object.
|
2019-06-04 23:55:27 +02:00
|
|
|
Json::Value Profile::ToJson() const
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
Json::Value root;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-06-04 23:55:27 +02:00
|
|
|
///// Profile-specific settings /////
|
|
|
|
root[JsonKey(GuidKey)] = winrt::to_string(Utils::GuidToString(_guid));
|
|
|
|
root[JsonKey(NameKey)] = winrt::to_string(_name);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-06-04 23:55:27 +02:00
|
|
|
///// Core Settings /////
|
2019-05-03 00:29:04 +02:00
|
|
|
if (_defaultForeground)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(ForegroundKey)] = Utils::ColorToHexString(_defaultForeground.value());
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
if (_defaultBackground)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(BackgroundKey)] = Utils::ColorToHexString(_defaultBackground.value());
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
if (_schemeName)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
const auto scheme = winrt::to_string(_schemeName.value());
|
|
|
|
root[JsonKey(ColorSchemeKey)] = scheme;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
Json::Value tableArray{};
|
2019-05-03 00:29:04 +02:00
|
|
|
for (auto& color : _colorTable)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
tableArray.append(Utils::ColorToHexString(color));
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(ColorTableKey)] = tableArray;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(HistorySizeKey)] = _historySize;
|
|
|
|
root[JsonKey(SnapOnInputKey)] = _snapOnInput;
|
|
|
|
root[JsonKey(CursorColorKey)] = Utils::ColorToHexString(_cursorColor);
|
2019-05-03 00:29:04 +02:00
|
|
|
// Only add the cursor height property if we're a legacy-style cursor.
|
|
|
|
if (_cursorShape == CursorStyle::Vintage)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(CursorHeightKey)] = _cursorHeight;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(CursorShapeKey)] = winrt::to_string(_SerializeCursorStyle(_cursorShape));
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-06-04 23:55:27 +02:00
|
|
|
///// Control Settings /////
|
|
|
|
root[JsonKey(CommandlineKey)] = winrt::to_string(_commandline);
|
|
|
|
root[JsonKey(FontFaceKey)] = winrt::to_string(_fontFace);
|
|
|
|
root[JsonKey(FontSizeKey)] = _fontSize;
|
|
|
|
root[JsonKey(AcrylicTransparencyKey)] = _acrylicTransparency;
|
|
|
|
root[JsonKey(UseAcrylicKey)] = _useAcrylic;
|
|
|
|
root[JsonKey(CloseOnExitKey)] = _closeOnExit;
|
|
|
|
root[JsonKey(PaddingKey)] = winrt::to_string(_padding);
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2019-07-25 22:31:41 +02:00
|
|
|
if (_connectionType)
|
|
|
|
{
|
|
|
|
root[JsonKey(ConnectionTypeKey)] = winrt::to_string(Utils::GuidToString(_connectionType.value()));
|
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
if (_scrollbarState)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
const auto scrollbarState = winrt::to_string(_scrollbarState.value());
|
|
|
|
root[JsonKey(ScrollbarStateKey)] = scrollbarState;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_icon)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
const auto icon = winrt::to_string(_icon.value());
|
|
|
|
root[JsonKey(IconKey)] = icon;
|
|
|
|
}
|
|
|
|
|
2019-07-02 19:09:22 +02:00
|
|
|
if (_tabTitle)
|
|
|
|
{
|
|
|
|
root[JsonKey(TabTitleKey)] = winrt::to_string(_tabTitle.value());
|
|
|
|
}
|
|
|
|
|
2019-06-04 23:55:27 +02:00
|
|
|
if (_startingDirectory)
|
|
|
|
{
|
|
|
|
root[JsonKey(StartingDirectoryKey)] = winrt::to_string(_startingDirectory.value());
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-05-29 20:35:46 +02:00
|
|
|
if (_backgroundImage)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(BackgroundImageKey)] = winrt::to_string(_backgroundImage.value());
|
2019-05-29 20:35:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_backgroundImageOpacity)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
root[JsonKey(BackgroundImageOpacityKey)] = _backgroundImageOpacity.value();
|
2019-05-29 20:35:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_backgroundImageStretchMode)
|
|
|
|
{
|
2019-07-25 06:47:06 +02:00
|
|
|
root[JsonKey(BackgroundImageStretchModeKey)] = SerializeImageStretchMode(_backgroundImageStretchMode.value()).data();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_backgroundImageAlignment)
|
|
|
|
{
|
|
|
|
root[JsonKey(BackgroundImageAlignmentKey)] = SerializeImageAlignment(_backgroundImageAlignment.value()).data();
|
2019-05-29 20:35:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-04 23:55:27 +02:00
|
|
|
return root;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Create a new instance of this class from a serialized JsonObject.
|
|
|
|
// Arguments:
|
|
|
|
// - json: an object which should be a serialization of a Profile object.
|
|
|
|
// Return Value:
|
|
|
|
// - a new Profile instance created from the values in `json`
|
2019-06-04 23:55:27 +02:00
|
|
|
Profile Profile::FromJson(const Json::Value& json)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
Profile result{};
|
|
|
|
|
|
|
|
// Profile-specific Settings
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto name{ json[JsonKey(NameKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._name = GetWstringFromJson(name);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto guid{ json[JsonKey(GuidKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._guid = Utils::GuidFromString(GetWstringFromJson(guid));
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-07-26 18:11:26 +02:00
|
|
|
else
|
|
|
|
{
|
2019-08-26 19:21:30 +02:00
|
|
|
// Always use the name to generate the temporary GUID. That way, across
|
|
|
|
// reloads, we'll generate the same static GUID.
|
|
|
|
const std::wstring_view name = result._name;
|
|
|
|
result._guid = Utils::CreateV5Uuid(RUNTIME_GENERATED_PROFILE_NAMESPACE_GUID, gsl::as_bytes(gsl::make_span(name)));
|
2019-07-30 02:24:20 +02:00
|
|
|
|
|
|
|
TraceLoggingWrite(
|
|
|
|
g_hTerminalAppProvider,
|
|
|
|
"SynthesizedGuidForProfile",
|
|
|
|
TraceLoggingDescription("Event emitted when a profile is deserialized without a GUID"),
|
|
|
|
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
|
|
|
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
2019-07-26 18:11:26 +02:00
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
// Core Settings
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto foreground{ json[JsonKey(ForegroundKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
const auto color = Utils::ColorFromHexString(foreground.asString());
|
2019-05-03 00:29:04 +02:00
|
|
|
result._defaultForeground = color;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto background{ json[JsonKey(BackgroundKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
const auto color = Utils::ColorFromHexString(background.asString());
|
2019-05-03 00:29:04 +02:00
|
|
|
result._defaultBackground = color;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto colorScheme{ json[JsonKey(ColorSchemeKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._schemeName = GetWstringFromJson(colorScheme);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (auto colorScheme{ json[JsonKey(ColorSchemeKeyOld)] })
|
2019-05-30 20:32:05 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
// TODO:GH#1069 deprecate old settings key
|
|
|
|
result._schemeName = GetWstringFromJson(colorScheme);
|
2019-05-30 20:32:05 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (auto colortable{ json[JsonKey(ColorTableKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-05-30 20:32:05 +02:00
|
|
|
int i = 0;
|
2019-06-04 23:55:27 +02:00
|
|
|
for (const auto& tableEntry : colortable)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
if (tableEntry.isString())
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
const auto color = Utils::ColorFromHexString(tableEntry.asString());
|
2019-05-30 20:32:05 +02:00
|
|
|
result._colorTable[i] = color;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-05-30 20:32:05 +02:00
|
|
|
i++;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto historySize{ json[JsonKey(HistorySizeKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
// TODO:MSFT:20642297 - Use a sentinel value (-1) for "Infinite scrollback"
|
2019-06-04 23:55:27 +02:00
|
|
|
result._historySize = historySize.asInt();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto snapOnInput{ json[JsonKey(SnapOnInputKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._snapOnInput = snapOnInput.asBool();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto cursorColor{ json[JsonKey(CursorColorKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
const auto color = Utils::ColorFromHexString(cursorColor.asString());
|
2019-05-03 00:29:04 +02:00
|
|
|
result._cursorColor = color;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto cursorHeight{ json[JsonKey(CursorHeightKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._cursorHeight = cursorHeight.asUInt();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto cursorShape{ json[JsonKey(CursorShapeKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._cursorShape = _ParseCursorShape(GetWstringFromJson(cursorShape));
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-07-02 19:09:22 +02:00
|
|
|
if (auto tabTitle{ json[JsonKey(TabTitleKey)] })
|
|
|
|
{
|
|
|
|
result._tabTitle = GetWstringFromJson(tabTitle);
|
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
// Control Settings
|
2019-07-25 22:31:41 +02:00
|
|
|
if (auto connectionType{ json[JsonKey(ConnectionTypeKey)] })
|
|
|
|
{
|
|
|
|
result._connectionType = Utils::GuidFromString(GetWstringFromJson(connectionType));
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto commandline{ json[JsonKey(CommandlineKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._commandline = GetWstringFromJson(commandline);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto fontFace{ json[JsonKey(FontFaceKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._fontFace = GetWstringFromJson(fontFace);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto fontSize{ json[JsonKey(FontSizeKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._fontSize = fontSize.asInt();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto acrylicTransparency{ json[JsonKey(AcrylicTransparencyKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._acrylicTransparency = acrylicTransparency.asFloat();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto useAcrylic{ json[JsonKey(UseAcrylicKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._useAcrylic = useAcrylic.asBool();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto closeOnExit{ json[JsonKey(CloseOnExitKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._closeOnExit = closeOnExit.asBool();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto padding{ json[JsonKey(PaddingKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._padding = GetWstringFromJson(padding);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto scrollbarState{ json[JsonKey(ScrollbarStateKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._scrollbarState = GetWstringFromJson(scrollbarState);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto startingDirectory{ json[JsonKey(StartingDirectoryKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._startingDirectory = GetWstringFromJson(startingDirectory);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto icon{ json[JsonKey(IconKey)] })
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._icon = GetWstringFromJson(icon);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto backgroundImage{ json[JsonKey(BackgroundImageKey)] })
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._backgroundImage = GetWstringFromJson(backgroundImage);
|
2019-05-29 20:35:46 +02:00
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
if (auto backgroundImageOpacity{ json[JsonKey(BackgroundImageOpacityKey)] })
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._backgroundImageOpacity = backgroundImageOpacity.asFloat();
|
2019-05-29 20:35:46 +02:00
|
|
|
}
|
2019-07-25 06:47:06 +02:00
|
|
|
if (auto backgroundImageStretchMode{ json[JsonKey(BackgroundImageStretchModeKey)] })
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
result._backgroundImageStretchMode = ParseImageStretchMode(backgroundImageStretchMode.asString());
|
2019-05-29 20:35:46 +02:00
|
|
|
}
|
2019-07-25 06:47:06 +02:00
|
|
|
if (auto backgroundImageAlignment{ json[JsonKey(BackgroundImageAlignmentKey)] })
|
|
|
|
{
|
|
|
|
result._backgroundImageAlignment = ParseImageAlignment(backgroundImageAlignment.asString());
|
|
|
|
}
|
2019-05-03 00:29:04 +02:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetFontFace(std::wstring fontFace) noexcept
|
|
|
|
{
|
2019-08-06 20:33:32 +02:00
|
|
|
_fontFace = std::move(fontFace);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetColorScheme(std::optional<std::wstring> schemeName) noexcept
|
|
|
|
{
|
2019-08-06 20:33:32 +02:00
|
|
|
_schemeName = std::move(schemeName);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetAcrylicOpacity(double opacity) noexcept
|
|
|
|
{
|
|
|
|
_acrylicTransparency = opacity;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetCommandline(std::wstring cmdline) noexcept
|
|
|
|
{
|
2019-08-06 20:33:32 +02:00
|
|
|
_commandline = std::move(cmdline);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-05-11 09:02:28 +02:00
|
|
|
void Profile::SetStartingDirectory(std::wstring startingDirectory) noexcept
|
|
|
|
{
|
2019-08-06 20:33:32 +02:00
|
|
|
_startingDirectory = std::move(startingDirectory);
|
2019-05-11 09:02:28 +02:00
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
void Profile::SetName(std::wstring name) noexcept
|
|
|
|
{
|
2019-08-06 20:33:32 +02:00
|
|
|
_name = std::move(name);
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetUseAcrylic(bool useAcrylic) noexcept
|
|
|
|
{
|
|
|
|
_useAcrylic = useAcrylic;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetDefaultForeground(COLORREF defaultForeground) noexcept
|
|
|
|
{
|
|
|
|
_defaultForeground = defaultForeground;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetDefaultBackground(COLORREF defaultBackground) noexcept
|
|
|
|
{
|
|
|
|
_defaultBackground = defaultBackground;
|
|
|
|
}
|
|
|
|
|
2019-07-25 22:31:41 +02:00
|
|
|
void Profile::SetCloseOnExit(bool defaultClose) noexcept
|
|
|
|
{
|
|
|
|
_closeOnExit = defaultClose;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Profile::SetConnectionType(GUID connectionType) noexcept
|
|
|
|
{
|
|
|
|
_connectionType = connectionType;
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
bool Profile::HasIcon() const noexcept
|
|
|
|
{
|
2019-07-25 19:44:58 +02:00
|
|
|
return _icon.has_value() && !_icon.value().empty();
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
2019-07-02 19:09:22 +02:00
|
|
|
// Method Description
|
|
|
|
// - Sets this profile's tab title.
|
|
|
|
// Arguments:
|
|
|
|
// - tabTitle: the tab title
|
|
|
|
void Profile::SetTabTitle(std::wstring tabTitle) noexcept
|
|
|
|
{
|
2019-08-06 20:33:32 +02:00
|
|
|
_tabTitle = std::move(tabTitle);
|
2019-07-02 19:09:22 +02:00
|
|
|
}
|
|
|
|
|
2019-05-22 22:03:10 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Sets this profile's icon path.
|
|
|
|
// Arguments:
|
|
|
|
// - path: the path
|
2019-08-06 20:33:32 +02:00
|
|
|
void Profile::SetIconPath(std::wstring_view path)
|
2019-05-22 22:03:10 +02:00
|
|
|
{
|
2019-08-06 20:33:32 +02:00
|
|
|
static_assert(!noexcept(_icon.emplace(path)));
|
2019-05-22 22:03:10 +02:00
|
|
|
_icon.emplace(path);
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// Method Description:
|
2019-08-15 01:12:14 +02:00
|
|
|
// - Returns this profile's icon path, if one is set. Otherwise returns the
|
|
|
|
// empty string. This method will expand any environment variables in the
|
|
|
|
// path, if there are any.
|
2019-05-03 00:29:04 +02:00
|
|
|
// Return Value:
|
|
|
|
// - this profile's icon path, if one is set. Otherwise returns the empty string.
|
2019-08-15 01:12:14 +02:00
|
|
|
winrt::hstring Profile::GetExpandedIconPath() const
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
2019-08-15 01:12:14 +02:00
|
|
|
if (!HasIcon())
|
|
|
|
{
|
|
|
|
return { L"" };
|
|
|
|
}
|
|
|
|
winrt::hstring envExpandedPath{ wil::ExpandEnvironmentStringsW<std::wstring>(_icon.value().data()) };
|
|
|
|
return envExpandedPath;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Returns the name of this profile.
|
|
|
|
// Arguments:
|
|
|
|
// - <none>
|
|
|
|
// Return Value:
|
|
|
|
// - the name of this profile
|
|
|
|
std::wstring_view Profile::GetName() const noexcept
|
|
|
|
{
|
|
|
|
return _name;
|
|
|
|
}
|
|
|
|
|
2019-07-25 22:31:41 +02:00
|
|
|
bool Profile::HasConnectionType() const noexcept
|
|
|
|
{
|
|
|
|
return _connectionType.has_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
GUID Profile::GetConnectionType() const noexcept
|
|
|
|
{
|
|
|
|
return HasConnectionType() ?
|
|
|
|
_connectionType.value() :
|
|
|
|
_GUID{};
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
bool Profile::GetCloseOnExit() const noexcept
|
|
|
|
{
|
|
|
|
return _closeOnExit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Helper function for expanding any environment variables in a user-supplied starting directory and validating the resulting path
|
|
|
|
// Arguments:
|
|
|
|
// - The value from the profiles.json file
|
|
|
|
// Return Value:
|
|
|
|
// - The directory string with any environment variables expanded. If the resulting path is invalid,
|
|
|
|
// - the function returns an evaluated version of %userprofile% to avoid blocking the session from starting.
|
|
|
|
std::wstring Profile::EvaluateStartingDirectory(const std::wstring& directory)
|
|
|
|
{
|
|
|
|
// First expand path
|
|
|
|
DWORD numCharsInput = ExpandEnvironmentStrings(directory.c_str(), nullptr, 0);
|
|
|
|
std::unique_ptr<wchar_t[]> evaluatedPath = std::make_unique<wchar_t[]>(numCharsInput);
|
|
|
|
THROW_LAST_ERROR_IF(0 == ExpandEnvironmentStrings(directory.c_str(), evaluatedPath.get(), numCharsInput));
|
|
|
|
|
|
|
|
// Validate that the resulting path is legitimate
|
|
|
|
const DWORD dwFileAttributes = GetFileAttributes(evaluatedPath.get());
|
|
|
|
if ((dwFileAttributes != INVALID_FILE_ATTRIBUTES) && (WI_IsFlagSet(dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
|
|
|
|
{
|
|
|
|
return std::wstring(evaluatedPath.get(), numCharsInput);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// In the event where the user supplied a path that can't be resolved, use a reasonable default (in this case, %userprofile%)
|
|
|
|
const DWORD numCharsDefault = ExpandEnvironmentStrings(DEFAULT_STARTING_DIRECTORY.c_str(), nullptr, 0);
|
|
|
|
std::unique_ptr<wchar_t[]> defaultPath = std::make_unique<wchar_t[]>(numCharsDefault);
|
|
|
|
THROW_LAST_ERROR_IF(0 == ExpandEnvironmentStrings(DEFAULT_STARTING_DIRECTORY.c_str(), defaultPath.get(), numCharsDefault));
|
|
|
|
|
|
|
|
return std::wstring(defaultPath.get(), numCharsDefault);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Helper function for converting a user-specified scrollbar state to its corresponding enum
|
|
|
|
// Arguments:
|
|
|
|
// - The value from the profiles.json file
|
|
|
|
// Return Value:
|
|
|
|
// - The corresponding enum value which maps to the string provided by the user
|
|
|
|
ScrollbarState Profile::ParseScrollbarState(const std::wstring& scrollbarState)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
if (scrollbarState == AlwaysVisible)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
return ScrollbarState::Visible;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (scrollbarState == AlwaysHide)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
return ScrollbarState::Hidden;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return ScrollbarState::Visible;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-29 20:35:46 +02:00
|
|
|
// 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
|
2019-06-04 23:55:27 +02:00
|
|
|
winrt::Windows::UI::Xaml::Media::Stretch Profile::ParseImageStretchMode(const std::string_view imageStretchMode)
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
if (imageStretchMode == ImageStretchModeNone)
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
|
|
|
return winrt::Windows::UI::Xaml::Media::Stretch::None;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (imageStretchMode == ImageStretchModeFill)
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
|
|
|
return winrt::Windows::UI::Xaml::Media::Stretch::Fill;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (imageStretchMode == ImageStretchModeUniform)
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
|
|
|
return winrt::Windows::UI::Xaml::Media::Stretch::Uniform;
|
|
|
|
}
|
|
|
|
else // Fall through to default behavior
|
|
|
|
{
|
|
|
|
return winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
2019-06-04 23:55:27 +02:00
|
|
|
// - Helper function for converting an ImageStretchMode to the
|
2019-05-29 20:35:46 +02:00
|
|
|
// correct string value.
|
|
|
|
// Arguments:
|
|
|
|
// - imageStretchMode: The enum value to convert to a string.
|
|
|
|
// Return Value:
|
|
|
|
// - The string value for the given ImageStretchMode
|
2019-06-04 23:55:27 +02:00
|
|
|
std::string_view Profile::SerializeImageStretchMode(const winrt::Windows::UI::Xaml::Media::Stretch imageStretchMode)
|
2019-05-29 20:35:46 +02:00
|
|
|
{
|
|
|
|
switch (imageStretchMode)
|
|
|
|
{
|
|
|
|
case winrt::Windows::UI::Xaml::Media::Stretch::None:
|
2019-06-04 23:55:27 +02:00
|
|
|
return ImageStretchModeNone;
|
2019-05-29 20:35:46 +02:00
|
|
|
case winrt::Windows::UI::Xaml::Media::Stretch::Fill:
|
2019-06-04 23:55:27 +02:00
|
|
|
return ImageStretchModeFill;
|
2019-05-29 20:35:46 +02:00
|
|
|
case winrt::Windows::UI::Xaml::Media::Stretch::Uniform:
|
2019-06-04 23:55:27 +02:00
|
|
|
return ImageStretchModeUniform;
|
2019-05-29 20:35:46 +02:00
|
|
|
default:
|
|
|
|
case winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill:
|
2019-06-04 23:55:27 +02:00
|
|
|
return ImageStretchModeUniformTofill;
|
2019-05-29 20:35:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-25 06:47:06 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Helper function for converting a user-specified image horizontal and vertical
|
|
|
|
// alignment to the appropriate enum values tuple
|
|
|
|
// Arguments:
|
|
|
|
// - The value from the profiles.json file
|
|
|
|
// Return Value:
|
|
|
|
// - The corresponding enum values tuple which maps to the string provided by the user
|
|
|
|
std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> Profile::ParseImageAlignment(const std::string_view imageAlignment)
|
|
|
|
{
|
|
|
|
if (imageAlignment == ImageAlignmentTopLeft)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Left,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Top);
|
|
|
|
}
|
|
|
|
else if (imageAlignment == ImageAlignmentBottomLeft)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Left,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Bottom);
|
|
|
|
}
|
|
|
|
else if (imageAlignment == ImageAlignmentLeft)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Left,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Center);
|
|
|
|
}
|
|
|
|
else if (imageAlignment == ImageAlignmentTopRight)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Right,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Top);
|
|
|
|
}
|
|
|
|
else if (imageAlignment == ImageAlignmentBottomRight)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Right,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Bottom);
|
|
|
|
}
|
|
|
|
else if (imageAlignment == ImageAlignmentRight)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Right,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Center);
|
|
|
|
}
|
|
|
|
else if (imageAlignment == ImageAlignmentTop)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Center,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Top);
|
|
|
|
}
|
|
|
|
else if (imageAlignment == ImageAlignmentBottom)
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Center,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Bottom);
|
|
|
|
}
|
|
|
|
else // Fall through to default alignment
|
|
|
|
{
|
|
|
|
return std::make_tuple(winrt::Windows::UI::Xaml::HorizontalAlignment::Center,
|
|
|
|
winrt::Windows::UI::Xaml::VerticalAlignment::Center);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Helper function for converting the HorizontalAlignment+VerticalAlignment tuple
|
|
|
|
// to the correct string value.
|
|
|
|
// Arguments:
|
|
|
|
// - imageAlignment: The enum values tuple to convert to a string.
|
|
|
|
// Return Value:
|
|
|
|
// - The string value for the given ImageAlignment
|
|
|
|
std::string_view Profile::SerializeImageAlignment(const std::tuple<winrt::Windows::UI::Xaml::HorizontalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment> imageAlignment)
|
|
|
|
{
|
|
|
|
const auto imageHorizontalAlignment = std::get<winrt::Windows::UI::Xaml::HorizontalAlignment>(imageAlignment);
|
|
|
|
const auto imageVerticalAlignment = std::get<winrt::Windows::UI::Xaml::VerticalAlignment>(imageAlignment);
|
|
|
|
switch (imageHorizontalAlignment)
|
|
|
|
{
|
|
|
|
case winrt::Windows::UI::Xaml::HorizontalAlignment::Left:
|
|
|
|
switch (imageVerticalAlignment)
|
|
|
|
{
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Top:
|
|
|
|
return ImageAlignmentTopLeft;
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Bottom:
|
|
|
|
return ImageAlignmentBottomLeft;
|
|
|
|
default:
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Center:
|
|
|
|
return ImageAlignmentLeft;
|
|
|
|
}
|
|
|
|
|
|
|
|
case winrt::Windows::UI::Xaml::HorizontalAlignment::Right:
|
|
|
|
switch (imageVerticalAlignment)
|
|
|
|
{
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Top:
|
|
|
|
return ImageAlignmentTopRight;
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Bottom:
|
|
|
|
return ImageAlignmentBottomRight;
|
|
|
|
default:
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Center:
|
|
|
|
return ImageAlignmentRight;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
case winrt::Windows::UI::Xaml::HorizontalAlignment::Center:
|
|
|
|
switch (imageVerticalAlignment)
|
|
|
|
{
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Top:
|
|
|
|
return ImageAlignmentTop;
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Bottom:
|
|
|
|
return ImageAlignmentBottom;
|
|
|
|
default:
|
|
|
|
case winrt::Windows::UI::Xaml::VerticalAlignment::Center:
|
|
|
|
return ImageAlignmentCenter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
// Method Description:
|
|
|
|
// - Helper function for converting a user-specified cursor style corresponding
|
|
|
|
// CursorStyle enum value
|
|
|
|
// Arguments:
|
|
|
|
// - cursorShapeString: The string value from the settings file to parse
|
|
|
|
// Return Value:
|
|
|
|
// - The corresponding enum value which maps to the string provided by the user
|
|
|
|
CursorStyle Profile::_ParseCursorShape(const std::wstring& cursorShapeString)
|
|
|
|
{
|
2019-06-04 23:55:27 +02:00
|
|
|
if (cursorShapeString == CursorShapeVintage)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
return CursorStyle::Vintage;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (cursorShapeString == CursorShapeBar)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
return CursorStyle::Bar;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (cursorShapeString == CursorShapeUnderscore)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
return CursorStyle::Underscore;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (cursorShapeString == CursorShapeFilledbox)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
return CursorStyle::FilledBox;
|
|
|
|
}
|
2019-06-04 23:55:27 +02:00
|
|
|
else if (cursorShapeString == CursorShapeEmptybox)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
return CursorStyle::EmptyBox;
|
|
|
|
}
|
|
|
|
// default behavior for invalid data
|
|
|
|
return CursorStyle::Bar;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
2019-05-21 08:15:44 +02:00
|
|
|
// - Helper function for converting a CursorStyle to its corresponding string
|
2019-05-03 00:29:04 +02:00
|
|
|
// value.
|
|
|
|
// Arguments:
|
|
|
|
// - cursorShape: The enum value to convert to a string.
|
|
|
|
// Return Value:
|
|
|
|
// - The string value for the given CursorStyle
|
2019-05-22 00:39:26 +02:00
|
|
|
std::wstring_view Profile::_SerializeCursorStyle(const CursorStyle cursorShape)
|
2019-05-03 00:29:04 +02:00
|
|
|
{
|
|
|
|
switch (cursorShape)
|
|
|
|
{
|
2019-06-11 22:27:09 +02:00
|
|
|
case CursorStyle::Underscore:
|
|
|
|
return CursorShapeUnderscore;
|
|
|
|
case CursorStyle::FilledBox:
|
|
|
|
return CursorShapeFilledbox;
|
|
|
|
case CursorStyle::EmptyBox:
|
|
|
|
return CursorShapeEmptybox;
|
|
|
|
case CursorStyle::Vintage:
|
|
|
|
return CursorShapeVintage;
|
|
|
|
default:
|
|
|
|
case CursorStyle::Bar:
|
|
|
|
return CursorShapeBar;
|
2019-05-03 00:29:04 +02:00
|
|
|
}
|
|
|
|
}
|