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

Introduce TerminalSettingsModel project #7667

Merged
merged 11 commits into from
Oct 6, 2020
13 changes: 8 additions & 5 deletions OpenConsole.sln
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_SettingsModel", "src\cascadia\LocalTests_SettingsModel\SettingsModel.LocalTests.vcxproj", "{CA5CAD1A-9B68-456A-B13E-C8218070DC42}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -2011,8 +2017,7 @@ Global
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x64.ActiveCfg = Release|x64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|x86.Build.0 = AuditMode|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.Debug|Any CPU.ActiveCfg = Debug|Win32
Expand All @@ -2038,8 +2043,7 @@ Global
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x64.ActiveCfg = Release|x64
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{CA5CAD1A-082C-4476-9F33-94B339494076}.AuditMode|x86.Build.0 = AuditMode|Win32
{CA5CAD1A-082C-4476-9F33-94B339494076}.Debug|Any CPU.ActiveCfg = Debug|Win32
Expand All @@ -2066,7 +2070,6 @@ Global
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|x64.ActiveCfg = AuditMode|x64
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|x64.Build.0 = AuditMode|x64
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.AuditMode|x86.Build.0 = AuditMode|Win32
{CA5CAD1A-9B68-456A-B13E-C8218070DC42}.Debug|Any CPU.ActiveCfg = Debug|Win32
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/TerminalApp/DebugTapConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ namespace winrt::Microsoft::TerminalApp::implementation

void DebugTapConnection::_OutputHandler(const hstring str)
{
_TerminalOutputHandlers(VisualizeControlCodes(str));
_TerminalOutputHandlers(til::visualize_control_codes(str));
}

// Called by the DebugInputTapConnection to print user input
void DebugTapConnection::_PrintInput(const hstring& str)
{
auto clean{ VisualizeControlCodes(str) };
auto clean{ til::visualize_control_codes(str) };
auto formatted{ wil::str_printf<std::wstring>(L"\x1b[91m%ls\x1b[m", clean.data()) };
_TerminalOutputHandlers(formatted);
}
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "ColorPickupFlyout.h"
#include "Tab.h"
#include "Tab.g.cpp"
#include "../inc/Utils.h"
#include "Utils.h"
#include "ColorHelper.h"

using namespace winrt;
Expand Down
3 changes: 1 addition & 2 deletions src/cascadia/TerminalApp/TerminalAppLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
<DependentUpon>Tab.idl</DependentUpon>
</ClInclude>
<ClInclude Include="Pane.h" />
<ClInclude Include="$(OpenConsoleDir)\src\cascadia\inc\Utils.h" />
<ClInclude Include="Utils.h" />
<ClInclude Include="ColorHelper.h" />
<ClInclude Include="TerminalSettings.h">
<DependentUpon>TerminalSettings.idl</DependentUpon>
Expand Down Expand Up @@ -160,7 +160,6 @@
<ClCompile Include="Pane.LayoutSizeNode.cpp" />
<ClCompile Include="ColorHelper.cpp" />
<ClCompile Include="DebugTapConnection.cpp" />
<ClCompile Include="$(OpenConsoleDir)\src\cascadia\inc\Utils.cpp" />
<ClCompile Include="TerminalSettings.cpp">
<DependentUpon>TerminalSettings.idl</DependentUpon>
</ClCompile>
Expand Down
68 changes: 66 additions & 2 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "pch.h"
#include "TerminalPage.h"
#include "../inc/Utils.h"
#include "Utils.h"
#include "AppLogic.h"
#include "../../types/inc/utils.hpp"

Expand Down Expand Up @@ -80,6 +80,70 @@ namespace winrt::TerminalApp::implementation
}
}

// Method Description:
// - Actually initialize the IconSource. Supports a variety of icons:
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
// * If the icon is a path to an image, we'll use that.
// * If it isn't, then we'll try and use the text as a FontIcon. If the
// character is in the range of symbols reserved for the Segoe MDL2
// Asserts, well treat it as such. Otherwise, we'll default to a Sego
// UI icon, so things like emoji will work.
// - MUST BE CALLED ON THE UI THREAD.
// Arguments:
// - <none>
// Return Value:
// - <none>
static void _refreshIcon(const Command& cmd)
DHowett marked this conversation as resolved.
Show resolved Hide resolved
{
if (cmd.IconPath().size() != 0)
{
cmd.IconSource(GetColoredIcon<winrt::WUX::Controls::IconSource>(cmd.IconPath()));

// If we fail to set the icon source using the "icon" as a path,
// let's try it as a symbol/emoji.
//
// Anything longer that 2 wchar_t's _isn't_ an emoji or symbol, so
// don't do this if it's just an invalid path.
if (cmd.IconSource() == nullptr && cmd.IconPath().size() <= 2)
{
try
{
WUX::Controls::FontIconSource icon;
const wchar_t ch = cmd.IconPath()[0];

// The range of MDL2 Icons isn't explicitly defined, but
// we're using this based off the table on:
// https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font
const bool isMDL2Icon = ch >= L'\uE700' && ch <= L'\uF8FF';
if (isMDL2Icon)
{
icon.FontFamily(WUX::Media::FontFamily{ L"Segoe MDL2 Assets" });
}
else
{
// Note: you _do_ need to manually set the font here.
icon.FontFamily(WUX::Media::FontFamily{ L"Segoe UI" });
}
icon.FontSize(12);
icon.Glyph(cmd.IconPath());
cmd.IconSource(icon);
}
CATCH_LOG();
}
}
if (cmd.IconSource() == nullptr)
{
// Set the default IconSource to a BitmapIconSource with a null source
// (instead of just nullptr) because there's a really weird crash when swapping
// data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette).
// Swapping between nullptr IconSources and non-null IconSources causes a crash
// to occur, but swapping between IconSources with a null source and non-null IconSources
// work perfectly fine :shrug:.
winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon;
icon.UriSource(nullptr);
cmd.IconSource(icon);
}
}

static void _recursiveUpdateCommandIcons(IMapView<winrt::hstring, Command> commands)
{
for (const auto& nameAndCmd : commands)
Expand All @@ -89,7 +153,7 @@ namespace winrt::TerminalApp::implementation
// !!! LOAD-BEARING !!! If this is never called, then Commands will
// have a nullptr icon. If they do, a really weird crash can occur.
// MAKE SURE this is called once after a settings load.
command.RefreshIcon();
_refreshIcon(command);

if (command.HasNestedCommands())
{
Expand Down
30 changes: 0 additions & 30 deletions src/cascadia/inc/Utils.h → src/cascadia/TerminalApp/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,6 @@ Author(s):
--*/
#pragma once

// This is a pair of helpers for determining if a pair of guids are equal, and
// establishing an ordering on GUIDs (via std::less).
namespace std
{
template<>
struct less<GUID>
{
bool operator()(const GUID& lhs, const GUID& rhs) const
{
return memcmp(&lhs, &rhs, sizeof(rhs)) < 0;
}
};

template<>
struct equal_to<GUID>
{
bool operator()(const GUID& lhs, const GUID& rhs) const
{
return memcmp(&lhs, &rhs, sizeof(rhs)) == 0;
}
};
}

namespace winrt::Microsoft::UI::Xaml::Controls
{
struct IconSource;
Expand Down Expand Up @@ -101,10 +78,3 @@ TIconSource GetColoredIcon(const winrt::hstring& path)

return nullptr;
}

std::wstring VisualizeControlCodes(std::wstring str) noexcept;

inline std::wstring VisualizeControlCodes(std::wstring_view str) noexcept
{
return VisualizeControlCodes(std::wstring{ str });
}
2 changes: 1 addition & 1 deletion src/cascadia/TerminalConnection/AzureConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static inline std::wstring _formatTenant(int tenantNumber, const Tenant& tenant)

namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
winrt::guid AzureConnection::ConnectionType()
winrt::guid AzureConnection::ConnectionType() noexcept
{
return AzureConnectionType;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalConnection/AzureConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
struct AzureConnection : AzureConnectionT<AzureConnection>, ConnectionStateHolder<AzureConnection>
{
static winrt::guid ConnectionType();
static winrt::guid ConnectionType() noexcept;
static bool IsAzureConnectionAvailable() noexcept;
AzureConnection(const uint32_t rows, const uint32_t cols);

Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalConnection/TelnetConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static constexpr winrt::guid TelnetConnectionType = { 0x311153fb, 0xd3f0, 0x4ac6

namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
winrt::guid TelnetConnection::ConnectionType()
winrt::guid TelnetConnection::ConnectionType() noexcept
{
return TelnetConnectionType;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalConnection/TelnetConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
{
struct TelnetConnection : TelnetConnectionT<TelnetConnection>, ConnectionStateHolder<TelnetConnection>
{
static winrt::guid ConnectionType();
static winrt::guid ConnectionType() noexcept;

TelnetConnection(const hstring& uri);

Expand Down
4 changes: 1 addition & 3 deletions src/cascadia/TerminalSettingsModel/ActionArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#include "RenameTabArgs.g.cpp"
#include "ExecuteCommandlineArgs.g.cpp"

#include "../inc/Utils.h"

#include <LibraryResources.h>

using namespace winrt::Microsoft::Terminal::TerminalControl;
Expand Down Expand Up @@ -212,7 +210,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// The string will be similar to the following:
// * "Send Input: ...input..."

auto escapedInput = VisualizeControlCodes(_Input);
auto escapedInput = til::visualize_control_codes(_Input);
auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput);
return winrt::hstring{ name };
}
Expand Down
1 change: 0 additions & 1 deletion src/cascadia/TerminalSettingsModel/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "CloseTabsAfterArgs.g.h"

#include "../../cascadia/inc/cppwinrt_utils.h"
#include "../inc/Utils.h"
#include "JsonUtils.h"
#include "TerminalWarnings.h"

Expand Down
67 changes: 1 addition & 66 deletions src/cascadia/TerminalSettingsModel/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "Command.h"
#include "Command.g.cpp"

#include "../inc/Utils.h"
#include "ActionAndArgs.h"
#include "JsonUtils.h"
#include <LibraryResources.h>
Expand Down Expand Up @@ -107,70 +106,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return actionAndArgs->GenerateName();
}

// Method Description:
// - Actually initialize our IconSource for our _lastIconPath. Supports a variety of icons:
// * If the icon is a path to an image, we'll use that.
// * If it isn't, then we'll try and use the text as a FontIcon. If the
// character is in the range of symbols reserved for the Segoe MDL2
// Asserts, well treat it as such. Otherwise, we'll default to a Sego
// UI icon, so things like emoji will work.
// - MUST BE CALLED ON THE UI THREAD.
// Arguments:
// - <none>
// Return Value:
// - <none>
void Command::RefreshIcon()
{
if (!_lastIconPath.empty())
{
_setIconSource(GetColoredIcon<winrt::WUX::Controls::IconSource>(_lastIconPath));

// If we fail to set the icon source using the "icon" as a path,
// let's try it as a symbol/emoji.
//
// Anything longer that 2 wchar_t's _isn't_ an emoji or symbol, so
// don't do this if it's just an invalid path.
if (IconSource() == nullptr && _lastIconPath.size() <= 2)
{
try
{
WUX::Controls::FontIconSource icon;
const wchar_t ch = _lastIconPath[0];

// The range of MDL2 Icons isn't explicitly defined, but
// we're using this based off the table on:
// https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font
const bool isMDL2Icon = ch >= L'\uE700' && ch <= L'\uF8FF';
if (isMDL2Icon)
{
icon.FontFamily(WUX::Media::FontFamily{ L"Segoe MDL2 Assets" });
}
else
{
// Note: you _do_ need to manually set the font here.
icon.FontFamily(WUX::Media::FontFamily{ L"Segoe UI" });
}
icon.FontSize(12);
icon.Glyph(_lastIconPath);
_setIconSource(icon);
}
CATCH_LOG();
}
}
if (IconSource() == nullptr)
{
// Set the default IconSource to a BitmapIconSource with a null source
// (instead of just nullptr) because there's a really weird crash when swapping
// data bound IconSourceElements in a ListViewTemplate (i.e. CommandPalette).
// Swapping between nullptr IconSources and non-null IconSources causes a crash
// to occur, but swapping between IconSources with a null source and non-null IconSources
// work perfectly fine :shrug:.
winrt::Windows::UI::Xaml::Controls::BitmapIconSource icon;
icon.UriSource(nullptr);
_setIconSource(icon);
}
}

// Method Description:
// - Deserialize a Command from the `json` object. The json object should
// contain a "name" and "action", and optionally an "icon".
Expand Down Expand Up @@ -216,7 +151,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

// Only get the icon path right now. The icon needs to be resolved into
// an IconSource on the UI thread, which will be done by RefreshIcon.
JsonUtils::GetValueForKey(json, IconKey, result->_lastIconPath);
JsonUtils::GetValueForKey(json, IconKey, result->_IconPath);

// If we're a nested command, we can ignore the current action.
if (!nested)
Expand Down
5 changes: 1 addition & 4 deletions src/cascadia/TerminalSettingsModel/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,21 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
bool HasNestedCommands();
Windows::Foundation::Collections::IMapView<winrt::hstring, Model::Command> NestedCommands();

void RefreshIcon();

winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker;

WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Name, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(Model::ActionAndArgs, Action, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr);
GETSET_PROPERTY(winrt::hstring, IconPath);

GETSET_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None);

private:
Json::Value _originalJson;
Windows::Foundation::Collections::IMap<winrt::hstring, Model::Command> _subcommands{ nullptr };

winrt::hstring _lastIconPath{};

static std::vector<Model::Command> _expandCommand(Command* const expandable,
Windows::Foundation::Collections::IVectorView<Model::Profile> profiles,
Windows::Foundation::Collections::IVectorView<Model::ColorScheme> schemes,
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalSettingsModel/Command.idl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Microsoft.Terminal.Settings.Model
String KeyChordText;

Windows.UI.Xaml.Controls.IconSource IconSource;
void RefreshIcon();
String IconPath { get; };

Boolean HasNestedCommands { get; };
Windows.Foundation.Collections.IMapView<String, Command> NestedCommands { get; };
Expand Down
Loading